Conversation
|
Azure Pipelines: Successfully started running 4 pipeline(s). 12 pipeline(s) were filtered out due to trigger conditions. There may be pipelines that require an authorized user to comment /azp run to run. |
|
Tagging subscribers to this area: @dotnet/area-infrastructure-libraries |
|
This needs updates discussed and applied in #132827 |
Now, saying OpenHarmony is uniquer than those would be an understatement:
I am not sure, given all that, how to fit into current RID structure: Treating openharmony NOT as linux but its own thing maybe better but I'm not sure if we can avoid breaking our "libcFlavor" slot and still accommodate a generic "flavor" slot to fit in "kernelFlavor"? Perhaps: "runtimes": {
"openharmony": {
"#import": ["unix"]
},
"openharmony-linux": {
"#import": [ "openharmony", "linux" ]
},
"openharmony-hongmeng": {
"#import": [ "openharmony" ]
},
"openharmony-liteos": {
"#import": [ "openharmony" ]
}
} |
|
openharmony-linux/openharmony-hongmeng/openharmony-liteos would make sense only if it is common for openharmony apps to violate the kernel abstraction and have different binaries depending on the underlying kernel. |
|
Done — the updates discussed in #132827 have been applied to this branch: Note This comment was drafted with AI assistance (Copilot/agent tooling) under the repository owner's direction. |
|
@jkotas @am11 — thanks for the detailed analysis, this is very helpful. On @jkotas's question: OpenHarmony applications (HAP packages) are built against the SDK and libc abstraction, not against the kernel. A single application binary runs across the supported kernels, and producing kernel-specific binaries is not the common case. So I agree that kernel-flavored RIDs ( The For the single RID, I'd recommend keeping
Whichever way the maintainers decide ( Note This comment was drafted with AI assistance (Copilot/agent tooling) under the repository owner's direction. |
|
Updating this thread with the RID decision and verification results. RID decision: @jkoritzinsky has decided on Worth noting that the ecosystem itself is split on naming: the Node.js community uses The kernel-flavored variants ( On-device verification (HarmonyOS hardware, HongMeng Kernel 1.13.0, aarch64): the ported runtime runs natively on a real HarmonyOS device (RID Status of review items here: the Note This comment was drafted with AI assistance (Copilot/agent tooling) under the repository owner's direction. |
978c1b5 to
cda8296
Compare
|
@jkotas — thanks for the review. Terminology: fixed in On "pretending to be Linux": agreed, and this is exactly the kind of inconsistency the RID rename was meant to fix. Here's the refactor I'd like to apply, split into three explicit layers so nothing is inherited implicitly anymore:
Two questions before I push this to the PR:
Note This comment was drafted with AI assistance (Copilot/agent tooling) under the repository owner's direction. |
Have you done analysis of how many TARGET_LINUX guards are correct for OpenHarmony? For example, there are Linux syscall numbers hardcoded under Linux guards: runtime/src/native/libs/System.Native/pal_process.c Lines 26 to 38 in 04a9b1a |
Not that many: $ git grep -E '(HOST|TARGET)_LINUX' | wc -l
193For a port to new platform, <200 lines is pretty trivial. |
|
@jkotas — you're right, I hadn't done that analysis. I've now run it: code inventory + on-device verification (HarmonyOS, HongMeng Kernel 1.13.0, aarch64, with the ported runtime running). Syscall numbers: they match the Linux generic table on the tested kernel (memfd_create=279, copy_file_range=285, membarrier=283, close_range=436 all reach the kernel with Linux numbers) — so the hardcodes "work" empirically. Agreed that's not a contract. Seccomp audit (on-device, SIGSYS-trapped syscalls the runtime uses):
This is a version-dependent policy, not a permanent kernel limitation. When porting the Bun runtime to OpenHarmony I went through the same seccomp whitelist with the HarmonyOS team: they have agreed to relax the policy in HarmonyOS 7.1 to allow Your exact example is confirmed broken on the current policy: Full audit (in progress, will publish on this PR):
So: audit-driven, not blanket inheritance. The CMake identity refactor (OHOS as its own OS, no Note This comment was drafted with AI assistance (Copilot/agent tooling) under the repository owner's direction. |
TARGET_LINUX / syscall audit — full report (as promised)OHOS TARGET_LINUX / Syscall Audit ReportDate: 2026-09-01 · Device: HarmonyOS, HongMeng Kernel 1.13.0 (aarch64) · Runtime: .NET 11.0.0-rc.1.26451.1-ohos (running on device) Purpose: Answer jkotas's review question — how many A. Hardcoded syscall numbers (
|
| # | File | Syscall | Number | On-device (HongMeng 1.13.0) | Verdict |
|---|---|---|---|---|---|
| 1 | System.Native/pal_process.c:303 |
close_range |
436 (fallback hardcode) | SIGSYS (all args) | 🔴 FIX NEEDED |
| 2 | System.Native/pal_io.c:1423 |
copy_file_range |
285 (aarch64 fallback) | allowed (EINVAL → reaches kernel) | ✅ OK |
| 3 | System.Native/pal_io.c:429/449 |
memfd_create |
header | ✅ works | ✅ OK |
| 4 | minipal/memorybarrierprocesswide.c + pal/src/thread/process.cpp:69 |
membarrier |
header | allowed (ret=25) | ✅ OK |
| 5 | gc/unix/numasupport.cpp:60/89 |
get_mempolicy/mbind |
header | SIGSYS / ENOSYS | ✅ already fixed (TARGET_OPENHARMONY) |
| 6 | coreclr/minipal/Unix/doublemapping.cpp |
memfd_create |
header | ✅ works | ✅ OK |
| 7 | eventpipe/ds-ipc.c |
memfd_create |
header | ✅ works | ✅ OK |
| 8 | minipal/cpufeatures.c |
riscv_hwprobe |
— | N/A (riscv only) | N/A |
| 9 | pal/src/thread/context.cpp:2204 |
riscv_flush_icache |
259 | N/A (riscv only) | N/A |
| 10-12 | libunwind hppa/ia64 |
rt_sigreturn/sigreturn/getunwind |
— | N/A (hppa/ia64) | N/A |
Syscall numbers match the Linux generic table on the tested kernel (verified empirically) — but this is not a contract (openharmony-linux / harmony-ohos / liteos kernels may differ).
B. Linux-specific paths (/proc, /sys, /etc) — 10 distinct paths
| Path | On-device | Used for |
|---|---|---|
/proc/self/mountinfo, /proc/self/cgroup, /proc/self/statm |
✅ | cgroup/limits detection |
/proc/mounts, /proc/self/stat |
✅ | mount/stat |
/proc/meminfo |
✅ | memory info |
/proc/self/maps (assumed), /proc/self/exe |
✅ | — |
/sys/fs/cgroup |
✅ | cgroup v1 (freezer/pids, sandbox paths) |
/sys/devices/system/node |
— | NUMA (already skipped on OHOS) |
/system/usr/icu/ |
— | ICU (OHOS has its own ICU) |
/etc/os-release |
❌ MISSING | distro detection — runtime falls back (RID comes from the graph, unaffected) |
Verdict: low risk — all runtime-critical proc/sys paths verified present.
C. TARGET_LINUX guard surface — 48 files total, 23 C/C++/H source files
| Area | Files with TARGET_LINUX |
|---|---|
src/native/libs |
7 |
src/coreclr/pal |
1 (plus build files) |
src/coreclr/gc |
3 |
src/coreclr/vm |
2 |
src/native/minipal, corehost, eventpipe |
1 each |
| build/config (cmake/props, not counted above) | rest of 48 |
Classification by content (sampled): most guards are plain POSIX/musl behavior (libc-level, valid on OHOS since its libc is musl-based — factual inheritance), not Linux-syscall or Linux-path specific. Deep per-guard review continues for the remaining files (will publish as follow-up).
D. Seccomp whitelist audit — 7 syscalls trapped (SIGSYS) on-device
| Syscall | Runtime usage | On-device | Handling | 7.1 policy* |
|---|---|---|---|---|
get_mempolicy (237) |
GC NUMA probe | SIGSYS | ✅ fixed (numasupport.cpp) | relaxed |
close_range (436) |
fork/exec cloexec sweep (pal_process.c) |
SIGSYS | 🔴 crash if reached (masked by posix_spawn today) | relaxed |
inotify_init1 (294) |
FileSystemWatcher backend (pal_io.c:1602) |
SIGSYS | 🔴 crash when used | not in bun's list — needs request or fallback |
rseq (293) |
TLS acceleration | SIGSYS | ✅ graceful (apps run) | stays blocked |
clone3 (435) |
thread creation | SIGSYS | ✅ musl falls back to clone |
relaxed |
openat2 (437) |
not used by runtime | SIGSYS | ✅ harmless | — |
signalfd4 (289) |
not used by runtime | SIGSYS | ✅ harmless | — |
* HarmonyOS 7.1 relaxation agreed with the HarmonyOS team during the Bun port covers clone3, get_mempolicy, close_range (everything except rseq). inotify_init1 is a .NET-specific gap — Bun doesn't use inotify, so it wasn't in the 7.1 list.
Other syscalls verified allowed (not SIGSYS): statx, pidfd_open, timerfd_create, eventfd2, getdents64, readlinkat, renameat2, epoll_create1, pipe2, dup3, gettid, set_robust_list, madvise, clock_gettime, nanosleep, wait4, rt_sigaction, ioctl, fcntl, socket, connect, accept4, recvmsg, sendmsg, mmap, munmap, openat, read, write, close, dup, rt_sigprocmask, memfd_create, copy_file_range, membarrier, futex, prctl, tgkill, epoll_pwait, ptrace, mprotect, mremap.
Required fixes (runtime)
close_range(pal_process.c): addTARGET_OPENHARMONYguard → skip syscall, useSetCloexecForAllFdsFallback(). Revisit after 7.1.inotify_init1(pal_io.c):TARGET_OPENHARMONYguard → returnENOTSUP(managedFileSystemWatcherreports unsupported; polling fallback can be added later). Also requestinotify_init1addition to the HarmonyOS whitelist.rseq: keep the graceful-degradation path permanently (7.1 keeps it blocked).- No other changes required from this audit; remaining C-category guard review is informational.
Conclusion
- Syscall numbers match Linux today (empirical, not contractual).
- 7 syscalls trapped by seccomp; 2 are real crash risks (
close_range,inotify_init1) → both getTARGET_OPENHARMONYguards. /proc//syssurface verified usable;/etc/os-releaseabsent (handled).- Approach: audit-driven, targeted
TARGET_OPENHARMONYhandling (same pattern as the NUMA fix), not blanketTARGET_LINUXinheritance.
Note
This comment was drafted with AI assistance (Copilot/agent tooling) under the repository owner's direction.
|
@jkotas — one more result from the audit, now implemented in the runtime (commit A general SIGSYS recovery mechanism — the same idea the Bun runtime uses on OpenHarmony, and what Android's bionic does internally: the PAL installs a Design detail: the handler sets only the return register and leaves the instruction pointer untouched. That matches the standard Linux seccomp TRAP contract (unchanged PC → the kernel returns The per-syscall guards ( Note This comment was drafted with AI assistance (Copilot/agent tooling) under the repository owner's direction. |
I guess we can pretend that ohos is linux flavor when compiling C/C++ code, Unlike the RID graph shape, this is a local decision that can be revisited later.
We are interested in hacks that are trying to leverage holes in seccomp enforcement. This should be done properly. |
Records the three post-upstream cleanups found in the plans history and the prepared artifacts: - pr/ohos-tls-flag-cleanup f9dffc0 (base pr/ohos-infra): drop the measured no-op -ftls-model=global-dynamic; gates on dotnet#132953. - pr/ohos-shims-tfm-cleanup 1157f1d (base pr/ohos-libs-tfm N15 stack top): compile shims in the linux TFM group so sfx-src no longer filters the 60 facades out; gates on dotnet#132953 + the N15 review. - pr/ohos-illink-ntlm f8495f4 (base main): isolated tools change for _UseManagedNtlm on openharmony; no PR exists yet, scope decision pending upstream (dotnet#132866 open question). Patch copies of all three commits live under docs/plans/patches/. No build was possible in this checkout (no .dotnet/artifacts); verification was diff-check + xmllint + read-back + remote SHA comparison. No upstream comment or PR was posted.
|
Friendly ping — is there anything else you'd like from my side before this can merge? Current state on head
Context: the follow-up OpenHarmony runtime-port PRs are prepared and ready to submit. |
…026-09-21) - archive the submission-ready PR texts in-repo (docs/plans/2026-09-21-ohos-pr-drafts.md), regenerated for the current tips and sizes; N2 no longer mentions the dropped configure.cmake exemption, N8 is scoped to OpenHarmony, N13 carries the openharmony-arm open item - plan: refresh §2 upstream status (reminder comments posted 09-21, dotnet#132953 renamed 09-16), §3 prepared tips/sizes, add the post-dotnet#132953 follow-up table and the 2026-09-21 rebase rehearsal (all CLEAN onto upstream/main 35423f1) - audit §32: note the reminder comments were sent
Per the supported-arch decision (arm64/x64 only, matching A1), remove openharmony-arm from the runtime and apphost pack RID lists in pr/ohos-packs (amended tip fed16fd, force-pushed) and re-run the 2026-09-21 rehearsal for the amended commit: CLEAN onto main (628239fd4d) and onto the post-dotnet#132953 state (67af5e8820). The RID graph keeps the RID as addressable.
…the path Verified from the SDK: the OHOS arm sysroot libc/libm carry no Tag_ABI_VFP_args (base/softfp ABI) and the NDK wrapper compiles with -mfloat-abi=softfp. CoreCLR already supports softfp arm32 via ARM_SOFTFP (Tizen armel / Android arm: JIT CORJIT_FLAG_SOFTFP_ABI + compUseSoftFP, callingconvention/callstub softfp branches, FEATURE_HFA off). OHOS only needs the openharmony+arm -> ARM_SOFTFP enablement (planned as a follow-up, not an edit to the open dotnet#132953), plus an arm32 signer and device validation. Adds the device readiness checklist and the probe commands.
|
|
…e.json is frozen) Per review feedback on dotnet#132953: runtime.json is frozen and must not be edited; the portable graph is the maintained source. Revert the runtime.json change and add the openharmony / openharmony-arm / openharmony-arm64 / openharmony-x64 entries to PortableRuntimeIdentifierGraph.json instead.
…e RID graph Mirror the dotnet#132953 review change: runtime.json is frozen (am11), so revert the openharmony entries there and add openharmony / openharmony-arm / openharmony-arm64 / openharmony-x64 to PortableRuntimeIdentifierGraph.json. Fork release outputs are unchanged: the SDK build still replaces both graphs with the fork snapshots via RidGraphOverrideRuntimeJson/PortableJson.
…aph move - per am11's review on dotnet#132953: runtime.json is frozen; the openharmony RIDs live in PortableRuntimeIdentifierGraph.json (PR head 9e4af17, feature branch a65f978) - §6.3: the portable override is upstream-bound; the legacy graph override is fork bootstrap plumbing only - S1a draft body updated to the same reading
| "unix-x64" | ||
| ] | ||
| }, | ||
| "openharmony": {}, |
There was a problem hiding this comment.
This should import any like other top-level OSes
There was a problem hiding this comment.
Fixed — openharmony now imports any, like the other non-unix top-level OS RIDs (win/browser/wasi), so the chain is openharmony-arm64 → openharmony → any → base:
"openharmony": {
"#import": [
"any"
]
},be8e6f6988d; the arch RIDs keep the parent-only shape (win-x64, browser-wasm).
Note
This comment was drafted with AI assistance (agent tooling) under the author's direction.
…he no-op TLS flag, and the duplicated find_program - eng/build.sh: remove the __PortableTargetOS pass-through. init-distro-rid.sh already exports the variable and MSBuild reads it from the environment, so the /p: was redundant; openharmony itself needs none of this (jkotas's thread asked exactly this). - configurecompiler.cmake: drop -ftls-model=global-dynamic. -fno-emulated-tls already makes the OHOS NDK clang use the global-dynamic model (measured byte-identical code), so the flag was a no-op. - configuretools.cmake: one find_program with a conditional HINTS value instead of two duplicated blocks.
…lag, find_program) Same three changes as the PR commit 8ef4e92: - drop the __PortableTargetOS /p: propagation (init-distro-rid.sh already exports it; MSBuild reads the environment), - drop -ftls-model=global-dynamic (-fno-emulated-tls is sufficient), - one find_program with an empty-on-other-platforms HINTS instead of two duplicated blocks.
…up superseded - dotnet#132953 now removes the redundant __PortableTargetOS propagation, the no-op -ftls-model=global-dynamic and the duplicated find_program (commit 8ef4e92; feature branch dc3b15b) - plan §6.1: the TLS cleanup item is DONE inside the PR; pr/ohos-tls-flag-cleanup is archived as superseded
Per jkotas's review: openharmony is a top-level OS RID and should fall back to any like win/browser/wasi. The arch RIDs keep the parent-only shape (win-x64/browser-wasm precedent).
…review fix) Mirrors the dotnet#132953 review fix: openharmony falls back to any like the other non-unix top-level OS RIDs (win/browser/wasi).
…mmon PR) - dotnet#132953: openharmony imports any (be8e6f6; feature 5a09652) - eng/common request handed off to dotnet/arcade#17608 (native host detection, openharmony.<api>-<arch> non-portable RID, OHOS NDK toolchain branch) - warn that the sdk-ohos override graphs still need the same any fallback
The override graphs carried "openharmony": {} with no fallback. Per the
dotnet/runtime#132953 review, the top-level openharmony RID imports any like
win/browser/wasi, and the arch RIDs keep the parent-only shape. Mirrors the
runtime commit be8e6f6988d.
The override graphs carried "openharmony": {} with no fallback. Per the
dotnet/runtime#132953 review, the top-level openharmony RID imports any like
win/browser/wasi, and the arch RIDs keep the parent-only shape. Mirrors the
runtime commit be8e6f6988d.
The override graphs carried "openharmony": {} with no fallback. Per the
dotnet/runtime#132953 review, the top-level openharmony RID imports any like
win/browser/wasi, and the arch RIDs keep the parent-only shape. Mirrors the
runtime commit be8e6f6988d.
|
@am11 — the
No If you prefer, I can also drop the same hunks into this PR to speed up the sync (like OpenBSD did) — otherwise waiting for the arcade sync is fine. Note This comment was drafted with AI assistance (agent tooling) under the author's direction. |
- sdk-ohos override graphs import any (737fc2a767e, 123a665d9b1, ce1846b0dfa) - dotnet#132953 replies posted (4 threads) and the description refreshed
- jkotas asked for the long name in arcade#17608; renamed in 4975a234c - dotnet#132953: 148 success, 4 red (2 chronic infra, osx sccache SIGSEGV flake)
- all held branches re-rehearsed CLEAN onto upstream/main 6f4751a; only the archived tls-flag-cleanup conflicts (its change is already inside dotnet#132953) - S1a tip 123a665d9b1 / S1b tip ce1846b0dfa (any follow-up), arm32 parked note, and a new A1 (aspnetcore) draft section
runtime.json is frozen upstream (dotnet/runtime#132953 review), so the SDK layout must always copy the Microsoft.NETCore.Platforms package copy. Only the portable graph is upstream-facing: keep RidGraphOverridePortableJson and remove the RidGraphOverrideRuntimeJson hook together with the checked-in eng/RuntimeIdentifierGraph.openharmony.json, which was bootstrap plumbing for the stock bootstrap SDK and does not belong upstream. The remaining override references only PortableRuntimeIdentifierGraph.openharmony.json; no other file in eng/ refers to the removed graph.
runtime.json is frozen upstream (dotnet/runtime#132953 review), so the SDK layout must always copy the Microsoft.NETCore.Platforms package copy. Only the portable graph is upstream-facing: keep RidGraphOverridePortableJson and remove the RidGraphOverrideRuntimeJson hook together with the checked-in eng/RuntimeIdentifierGraph.openharmony.json, which was bootstrap plumbing for the stock bootstrap SDK and does not belong upstream. The remaining override references only PortableRuntimeIdentifierGraph.openharmony.json; no other file in eng/ refers to the removed graph.
A separate unix shim TFM (LibrariesOpenHarmonyShimsTfm) made sfx-src's OmitIncompatibleProjectReferences drop all 60 shims from the linux-group shared-framework traversal: the facades (System, mscorlib, netstandard, ...) never reached the layout, which is why the OpenHarmony build script had to compile them and copy them in by hand (round-14d). Use the same linux group as the shared framework (LibrariesOpenHarmonySfxTfm) for the shims and drop the extra property. The references that made the unix shim TFM necessary still resolve from a linux-group consumer: unix-only libraries (System.IO.Compression, Brotli, ...) resolve via the unix flavor (verified for the shared framework in commit 2aff771) and the -linux/-osx libraries resolve exactly. Upstream dependency: applies on top of dotnet#132953 and the N15 libraries TFM mapping; re-evaluate the property name and shape with the reviewers before folding this into the libraries PR. No runtime build environment in this checkout, so the alignment is not build-verified here. RC-B (integration fold): applies the shims TFM cleanup to feature/openharmony per the recorded decision in docs/plans/2026-09-19-ohos-code-audit.md §32.1 item 2 / §32.4 item 1. Whether this lands inside the N15 libraries PR or immediately after, and the final property naming/shape, remain review calls. (cherry picked from commit 1157f1d)
runtime.json is frozen upstream (dotnet/runtime#132953 review), so the SDK layout must always copy the Microsoft.NETCore.Platforms package copy. Only the portable graph is upstream-facing: keep RidGraphOverridePortableJson and remove the RidGraphOverrideRuntimeJson hook together with the checked-in eng/RuntimeIdentifierGraph.openharmony.json, which was bootstrap plumbing for the stock bootstrap SDK and does not belong upstream. The remaining override references only PortableRuntimeIdentifierGraph.openharmony.json; no other file in eng/ refers to the removed graph. (cherry picked from commit 6396aa8)
Summary
First PR of the OpenHarmony (HarmonyOS) port series (tracking issue: #132866). This PR adds the build infrastructure for the
openharmonytarget so the runtime can be cross-built with the HarmonyOS NDK. It is a no-op on all existing platforms: every change is guarded byTargetsOpenHarmony(only set when the build targetsopenharmony), and the standard platform CI matrix stays green.Changes
eng/build.sh--os openharmony; skip the rootfs requirement (NDK-based toolchain)eng/RuntimeIdentifier.propsTargetsOpenHarmonyproperty;openharmonykeeps the Linux family flags (TargetsLinux) but is excluded fromTargetsLinuxGlibceng/Subsets.propsDefaultSubsetsfor OpenHarmony (CoreCLR + NativeAOT, no Mono dependency);UseNativeAotForComponentsexclusion (mirrors linux-bionic)eng/native/build-commons.shOHOS_NDK_HOME,ohos.toolchain.cmake,OHOS_ARCH); rootfs bypasseng/native/configureplatform.cmakeCMAKE_SYSTEM_NAME=OHOSto linux/musl;CLR_CMAKE_HOST_OPENHARMONY/CLR_CMAKE_TARGET_OPENHARMONYeng/native/configurecompiler.cmake-Qunused-arguments,-fno-emulated-tls);TARGET_OPENHARMONYdefine (mirrorsTARGET_ANDROID)eng/native/configuretools.cmakefind_programat the NDK compiler directory (empty hint on other platforms)eng/native/gen-buildsys.shbuild-commons.sh)src/libraries/Microsoft.NETCore.Platforms/src/PortableRuntimeIdentifierGraph.jsonopenharmony+ arch RIDs to the portable graph (openharmonyimportsany, the arch RIDs importopenharmony); the frozenruntime.jsonis untouchedsrc/native/libs/System.Native/CMakeLists.txtsrc/native/libs/build-native.shopenharmonylikelinux-bionicfor cross-build detectionImpact on existing platforms
None.
TargetsOpenHarmonyis only defined whenPortableOS == openharmony(i.e., when--os openharmonyis passed). Every guarded condition either adds a new branch or excludes OpenHarmony from an existing condition in a way that is logically equivalent for all other platforms.Validation
clr.native+libs+host+packs --os openharmony -arch arm64 --crosscross-build succeeds:0 Warning(s) 0 Error(s).runtime.jsonis not modified.eng/commonadditions for OpenHarmony hosts are intentionally not part of this PR: they are sent to dotnet/arcade as Add OpenHarmony support to eng/common arcade#17608 (init-os-and-arch.sh,init-distro-rid.sh,cross/toolchain.cmake) and sync back from there.Note
This PR was authored with AI assistance (Copilot/agent tooling) under the repository owner's direction.