aboutsummaryrefslogtreecommitdiffhomepage
path: root/internal
diff options
context:
space:
mode:
Diffstat (limited to 'internal')
-rw-r--r--internal/outcome/process.go2
-rw-r--r--internal/rosa/azalea/evaluate.go8
-rw-r--r--internal/rosa/package/curl.az4
-rw-r--r--internal/rosa/package/foot.az4
-rw-r--r--internal/rosa/package/gnu.az4
-rw-r--r--internal/rosa/package/go.az (renamed from internal/rosa/package/go/package.az)5
-rw-r--r--internal/rosa/package/go/820480.patch24
-rw-r--r--internal/rosa/package/hakurei.az4
-rw-r--r--internal/rosa/package/hwdata.az4
-rw-r--r--internal/rosa/package/iproute2.az4
-rw-r--r--internal/rosa/package/kernel/amd64.config2
-rw-r--r--internal/rosa/package/kernel/arm64.config2
-rw-r--r--internal/rosa/package/kernel/package.az6
-rw-r--r--internal/rosa/package/libexpat.az4
-rw-r--r--internal/rosa/package/mesa/package.az4
-rw-r--r--internal/rosa/package/netfilter/package.az4
-rw-r--r--internal/rosa/package/noto.az4
-rw-r--r--internal/rosa/package/pcre2.az4
-rw-r--r--internal/rosa/package/pipewire.az4
-rw-r--r--internal/rosa/package/python/package.az8
-rw-r--r--internal/rosa/package/spirv.az4
-rw-r--r--internal/rosa/package/tamago.az4
-rw-r--r--internal/rosa/package/util-linux/a323dddbcd1ed05a10e7e870b3e1a48b4ed44a43.patch35
-rw-r--r--internal/rosa/package/util-linux/package.az (renamed from internal/rosa/package/util-linux.az)5
-rw-r--r--internal/store/data.go10
-rw-r--r--internal/store/header.go3
-rw-r--r--internal/store/segment.go66
-rw-r--r--internal/store/segment_test.go78
-rw-r--r--internal/store/store.go80
29 files changed, 278 insertions, 112 deletions
diff --git a/internal/outcome/process.go b/internal/outcome/process.go
index 614b22fc..599af8f2 100644
--- a/internal/outcome/process.go
+++ b/internal/outcome/process.go
@@ -303,7 +303,7 @@ func (k *outcome) main(msg message.Msg, identifierFd int) {
)
for eh := range entries {
var et hst.Enablements
- if et, err = eh.Load(nil); err != nil {
+ if et, err = eh.Load(nil, syscall.Kill); err != nil {
perror(err, "read state header of instance "+eh.ID.String())
} else {
rt |= et
diff --git a/internal/rosa/azalea/evaluate.go b/internal/rosa/azalea/evaluate.go
index b35a056a..26a02c02 100644
--- a/internal/rosa/azalea/evaluate.go
+++ b/internal/rosa/azalea/evaluate.go
@@ -365,7 +365,13 @@ func evaluateAny(d PF, s []Frame, expr, rp any) bool {
panic(ErrInvalidSpecial)
}
farg.K = names[0]
- if err := storeE(&farg.V, arg.V[0]); err != nil {
+
+ v := arg.V[0]
+ if p, _ok := v.(Ident); _ok && p == "nil" {
+ v = Nil{}
+ }
+
+ if err := storeE(&farg.V, v); err != nil {
panic(err)
}
fargs = append(fargs, farg)
diff --git a/internal/rosa/package/curl.az b/internal/rosa/package/curl.az
index eee21bdd..58a0ad72 100644
--- a/internal/rosa/package/curl.az
+++ b/internal/rosa/package/curl.az
@@ -3,10 +3,10 @@ package curl {
website = "https://curl.se";
anitya = 381;
- version# = "8.21.0";
+ version# = "8.22.0";
source = remoteTar {
url = "https://curl.se/download/curl-"+version+".tar.bz2";
- checksum = "lJSm8bVjS0OmsarEdbvejdQdvXsb7yGarlr6oMtA9FW1EXOga8zZxa1LPtfaq_qX";
+ checksum = "zeIqlmHElDa3IPLZq86ICRxn1YoiXlNCdx30BuahcUToYqjSuyvu8AtRqbzKH_06";
compress = bzip2;
};
diff --git a/internal/rosa/package/foot.az b/internal/rosa/package/foot.az
index e3166db7..78ec76bb 100644
--- a/internal/rosa/package/foot.az
+++ b/internal/rosa/package/foot.az
@@ -3,11 +3,11 @@ package foot {
website = "https://codeberg.org/dnkl/foot";
anitya = 141611;
- version# = "1.27.0";
+ version# = "1.28.0";
source = remoteTar {
url = "https://codeberg.org/dnkl/foot/releases/download/"+version+
"/foot-"+version+".tar.gz";
- checksum = "22rG3rMuQI8Ae2XTcZgOJ-6AbF7Taex8XpgvD6Fyg1Mn5Va67FfUcK3tRaq61TFg";
+ checksum = "w16syUlOAYlsJZ-a4QY9dfu4ph3yFypw05RXocNmTrefghzmT-HhV1O89QPAj5mV";
compress = gzip;
};
diff --git a/internal/rosa/package/gnu.az b/internal/rosa/package/gnu.az
index b3ed798c..b2a0fd8f 100644
--- a/internal/rosa/package/gnu.az
+++ b/internal/rosa/package/gnu.az
@@ -507,10 +507,10 @@ package parallel {
website = "https://www.gnu.org/software/parallel";
anitya = 5448;
- version# = "20260722";
+ version# = "20260822";
source = remoteTar {
url = "https://mirrors.kernel.org/gnu/parallel/parallel-"+version+".tar.bz2";
- checksum = "liG9pBSRqUPqDuRXmnJPoVh-G53lDKkkO8GGabSxQnSho4b9BD0EaJDdScgVhnwj";
+ checksum = "zf-5ZEpAZ073coMSyOY7NRmXwCRPWvpjbjOMOvirU9fHlU0WWovwss-bAMrh0q_G";
compress = bzip2;
};
diff --git a/internal/rosa/package/go/package.az b/internal/rosa/package/go.az
index d06720b5..6efca245 100644
--- a/internal/rosa/package/go/package.az
+++ b/internal/rosa/package/go.az
@@ -3,13 +3,12 @@ package go {
website = "https://go.dev";
anitya = 1227;
- version# = "1.27.0";
+ version# = "1.27.1";
source = remoteTar {
url = "https://go.dev/dl/go"+version+".src.tar.gz";
- checksum = "Ookl2vP6KMfJuxaxX6nXZ1gnL43wZPl5GjpVsrI7IJiB4b3xr1PbnbYIOJ8v5jzG";
+ checksum = "Jw7OCTZbixLPF0E2WafFBh6DnxbsElvEg_RsMGkrzAmi0pyJTI3eQqLJsvXlVtbK";
compress = gzip;
};
- patches = [ "820480.patch" ];
env = [
"CC=cc",
diff --git a/internal/rosa/package/go/820480.patch b/internal/rosa/package/go/820480.patch
deleted file mode 100644
index 05459a80..00000000
--- a/internal/rosa/package/go/820480.patch
+++ /dev/null
@@ -1,24 +0,0 @@
-From fa10bbcce5635dd533ba933252e9dabd8a7f5e2a Mon Sep 17 00:00:00 2001
-From: David Chase <drchase@google.com>
-Date: Mon, 24 Aug 2026 15:20:40 -0400
-Subject: [PATCH] simd/archsimd: added PMULL gate on carryless multiply test
-
-Fixes #80991.
-
-Change-Id: I637de72acbb338c4c3b0a47f4a5520c33fe81fd2
----
-
-diff --git a/src/simd/archsimd/internal/simd_test/simd_arm64_test.go b/src/simd/archsimd/internal/simd_test/simd_arm64_test.go
-index f009488..7836fc8 100644
---- a/src/simd/archsimd/internal/simd_test/simd_arm64_test.go
-+++ b/src/simd/archsimd/internal/simd_test/simd_arm64_test.go
-@@ -22,6 +22,9 @@
- }
-
- func TestClMul(t *testing.T) {
-+ if !archsimd.ARM64.PMULL() {
-+ t.Skip("no carryless multiply")
-+ }
- var x = archsimd.LoadUint64x2([]uint64{1, 5})
- var y = archsimd.LoadUint64x2([]uint64{3, 9})
-
diff --git a/internal/rosa/package/hakurei.az b/internal/rosa/package/hakurei.az
index 24a2a7c9..0448c0f3 100644
--- a/internal/rosa/package/hakurei.az
+++ b/internal/rosa/package/hakurei.az
@@ -2,11 +2,11 @@ package hakurei-source {
description = "hakurei source tree";
exclude = true;
- version# = "0.4.7";
+ version# = "0.4.8";
output = remoteGit {
url = "https://git.gensokyo.uk/rosa/hakurei.git";
tag = "v"+version;
- checksum = "gQs-fBuPsYjGEBgxe3pSiqa7aMrqUkimi6iyjrhR6YKrOiZLfd4bFwiB9V8k3cKO";
+ checksum = "B6aoojyXblZ7eYwdc3Ak3wDbBpu63j8S79Gpiul9Obb8diqzBIJ2qNCgWVH6qLsc";
};
}
diff --git a/internal/rosa/package/hwdata.az b/internal/rosa/package/hwdata.az
index b826953c..4d552d5d 100644
--- a/internal/rosa/package/hwdata.az
+++ b/internal/rosa/package/hwdata.az
@@ -3,11 +3,11 @@ package hwdata {
website = "https://github.com/vcrhonek/hwdata";
anitya = 5387;
- version# = "0.410";
+ version# = "0.411";
source = remoteGitHub {
suffix = "vcrhonek/hwdata";
tag = "v"+version;
- checksum = "w1fbTz8NR7C6SYOupqTyNZGJHa_cDRAsGs4guZ3LddqlmawgEP_CWFw9-OYFKJ1q";
+ checksum = "5YWsZC8NgZShWWHmC66xqEkTJLAUYJoDt8kmstJyLWfsNqAWAhJZGkVUfgqbTv-6";
};
writable = true;
diff --git a/internal/rosa/package/iproute2.az b/internal/rosa/package/iproute2.az
index 3a5829df..2a31fc4b 100644
--- a/internal/rosa/package/iproute2.az
+++ b/internal/rosa/package/iproute2.az
@@ -3,11 +3,11 @@ package iproute2 {
website = "https://wiki.linuxfoundation.org/networking/iproute2";
anitya = 1392;
- version# = "7.1.0";
+ version# = "7.2.0";
source = remoteTar {
url = "https://git.kernel.org/pub/scm/network/iproute2/iproute2.git/"+
"snapshot/iproute2-"+version+".tar.gz";
- checksum = "yc6NdF6GtFUpKtKg6xwF_yxYGyj0eqFQW8RGsgBzKrOiVlE2bpVQlfeZf_ca5wJL";
+ checksum = "VECMJeSm-lHWpyJqnI-1CeHFejAgi_mb8LJjMGIx5rqww6AlZii3g_tUGPLu4npo";
compress = gzip;
};
diff --git a/internal/rosa/package/kernel/amd64.config b/internal/rosa/package/kernel/amd64.config
index d560bdb8..b52bfbd4 100644
--- a/internal/rosa/package/kernel/amd64.config
+++ b/internal/rosa/package/kernel/amd64.config
@@ -1,6 +1,6 @@
#
# Automatically generated file; DO NOT EDIT.
-# Linux/x86 6.18.47 Kernel Configuration
+# Linux/x86 6.18.49 Kernel Configuration
#
CONFIG_CC_VERSION_TEXT="clang version 23.1.0"
CONFIG_GCC_VERSION=0
diff --git a/internal/rosa/package/kernel/arm64.config b/internal/rosa/package/kernel/arm64.config
index c8658775..9c6951b7 100644
--- a/internal/rosa/package/kernel/arm64.config
+++ b/internal/rosa/package/kernel/arm64.config
@@ -1,6 +1,6 @@
#
# Automatically generated file; DO NOT EDIT.
-# Linux/arm64 6.18.47 Kernel Configuration
+# Linux/arm64 6.18.49 Kernel Configuration
#
CONFIG_CC_VERSION_TEXT="clang version 23.1.0"
CONFIG_GCC_VERSION=0
diff --git a/internal/rosa/package/kernel/package.az b/internal/rosa/package/kernel/package.az
index e2f6339e..b3af55d3 100644
--- a/internal/rosa/package/kernel/package.az
+++ b/internal/rosa/package/kernel/package.az
@@ -3,11 +3,11 @@ package kernel-source {
website = "https://kernel.org";
exclude = true;
- version# = "6.18.48";
+ version# = "6.18.49";
output = remoteTar {
url = "https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.git/"+
"snapshot/linux-"+version+".tar.gz";
- checksum = "XzcqKk0ODA4tTjl5tVQdckuLHVnITGalDH_EIYUC8WHimc7O6bbews-vFRHUK01m";
+ checksum = "J0FT9987a7mlYBGcACXWeTsmfScbS8FM_JAG9LLl917UdlcFRP_UDj73yR82bvGR";
compress = gzip;
};
}
@@ -48,7 +48,7 @@ cat \
amd64 = "uwTZX3iLp6iPsR0-F0Jz2aUviLMMqv4xGQHoKeemo2HrNLD7fDlIDqqYT--i_5HJ";
arm64 = "A9EWzTGEChVLJVm5BP1GzpibdUddXUN2hIjAGkD-KQr5sc6RuEeIQle8VAiAYUqp";
- riscv64 = "IB1oG3tEAN15wjYl8S5ekYXVFYN7-rb3m2f1Kdi58dGqnrIBTG2r1qb1utb5D1lb";
+ riscv64 = "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA";
};
inputs = [ rsync ];
}
diff --git a/internal/rosa/package/libexpat.az b/internal/rosa/package/libexpat.az
index 20e4f510..a79dcd30 100644
--- a/internal/rosa/package/libexpat.az
+++ b/internal/rosa/package/libexpat.az
@@ -3,7 +3,7 @@ package libexpat {
website = "https://libexpat.github.io";
anitya = 770;
- version# = "2.8.3";
+ version# = "2.8.4";
source = remoteGitHubRelease {
suffix = "libexpat/libexpat";
tag = "R_"+replace {
@@ -12,7 +12,7 @@ package libexpat {
new = "_";
};
name = "expat-"+version+".tar.bz2";
- checksum = "prHQc14YY3Gp6BfflneNcVyRXM-AxFCqiigxrGL9TT1sGhVODvI_9JNR2xnZlZSj";
+ checksum = "Nbi2wl8U9KHf3LVLczfAb5Kqr7HFv_myReVjxKXUkfhToWfL-pP2o44fDpWHJ4ig";
compress = bzip2;
};
diff --git a/internal/rosa/package/mesa/package.az b/internal/rosa/package/mesa/package.az
index 7967e3d7..8db6462e 100644
--- a/internal/rosa/package/mesa/package.az
+++ b/internal/rosa/package/mesa/package.az
@@ -4,12 +4,12 @@ package mesa {
anitya = 1970;
latest = anityaFallback;
- version# = "26.2.1";
+ version# = "26.2.2";
source = remoteGitLab {
domain = "gitlab.freedesktop.org";
suffix = "mesa/mesa";
ref = "mesa-"+version;
- checksum = "WZYAysQFZt8KMFAxQheKFZHarR1isgOeSw4LyfqAcmaHwXMCLiVao6eGuEuhJTJv";
+ checksum = "5mIdojhazcdAgbLW1v4d-7P5pIhu9wnGS3ek1QhJIPMJyFWhfKhiZCsd53WAHt1_";
};
patches = [ "include.patch" ];
diff --git a/internal/rosa/package/netfilter/package.az b/internal/rosa/package/netfilter/package.az
index 3dea2b87..9b6fedc1 100644
--- a/internal/rosa/package/netfilter/package.az
+++ b/internal/rosa/package/netfilter/package.az
@@ -29,11 +29,11 @@ package libnftnl {
website = "https://www.netfilter.org/projects/libnftnl";
anitya = 1681;
- version# = "1.3.1";
+ version# = "1.3.2";
source = remoteGit {
url = "https://git.netfilter.org/libnftnl.git";
tag = "libnftnl-"+version;
- checksum = "91ou66K-I17iX6DB6hiQkhhC_v4DFW5iDGzwjVRNbJNEmKqowLZBlh3FY-ZDO0r9";
+ checksum = "bW_GokelPejp2SKOo_OgFFYjf-7rn3GL6x1Z4kZb9NkfZe20WrRLNjQWVxxS9oII";
};
env = [
diff --git a/internal/rosa/package/noto.az b/internal/rosa/package/noto.az
index 64d27a58..e3bcc80b 100644
--- a/internal/rosa/package/noto.az
+++ b/internal/rosa/package/noto.az
@@ -3,11 +3,11 @@ package noto {
website = "https://fonts.google.com/noto";
anitya = 10671;
- version# = "2026.08.01";
+ version# = "2026.09.01";
source = remoteGitHub {
suffix = "notofonts/notofonts.github.io";
tag = "noto-monthly-release-"+version;
- checksum = "xTuvGQBtw9FWrbMQ0OHC-EVpUWYwLxNHPtaind_t6nP37En0r8orIY9N0X_YrPH7";
+ checksum = "ZITq5IyZNZovca3t7snPndDgjdzbCeBIoGYpY7bbnR-w9oAiz1vkN9zwRWz5JJw5";
};
enterSource = true;
diff --git a/internal/rosa/package/pcre2.az b/internal/rosa/package/pcre2.az
index 27f21bf7..0e7d1c68 100644
--- a/internal/rosa/package/pcre2.az
+++ b/internal/rosa/package/pcre2.az
@@ -3,12 +3,12 @@ package pcre2 {
website = "https://pcre2project.github.io/pcre2";
anitya = 5832;
- version# = "10.47";
+ version# = "10.48";
source = remoteGitHubRelease {
suffix = "PCRE2Project/pcre2";
tag = "pcre2-"+version;
name = "pcre2-"+version+".tar.bz2";
- checksum = "IbC24vVayju6nB9EhrBPSDexk22wDecdpyrjgC3nCZXkwTnUjq4CD2q5sopqu6CW";
+ checksum = "3HorftFDryXBh8JLSbEVWpU3OtSF_wUhtNZNCRvCDiGlBsMU150CxrDFKE8lVo6x";
compress = bzip2;
};
diff --git a/internal/rosa/package/pipewire.az b/internal/rosa/package/pipewire.az
index 1cbdeda9..2b971244 100644
--- a/internal/rosa/package/pipewire.az
+++ b/internal/rosa/package/pipewire.az
@@ -3,12 +3,12 @@ package wireplumber {
website = "https://gitlab.freedesktop.org/pipewire/wireplumber";
anitya = 235056;
- version# = "0.5.16";
+ version# = "0.5.17";
source = remoteGitLab {
domain = "gitlab.freedesktop.org";
suffix = "pipewire/wireplumber";
ref = version;
- checksum = "Ftt6s3tt5eDlJPizOWsvjHRfOQezVHOp3sDATJr2_B6MORbFW9XgWSHUNdy-dIp0";
+ checksum = "2vWxpOqnQmOlgMlNLYMu9ebPbF2y3W_eqDFM_bwAtCwnHhYE0S4kM8MkpFuXyVlu";
};
// OSError: [Errno 30] Read-only file system: '../../usr/src/wireplumber/po/conf.pot'
diff --git a/internal/rosa/package/python/package.az b/internal/rosa/package/python/package.az
index 525cb8c2..8182576d 100644
--- a/internal/rosa/package/python/package.az
+++ b/internal/rosa/package/python/package.az
@@ -197,11 +197,11 @@ package python-vcs-versioning {
website = "https://setuptools-scm.readthedocs.io/en/latest";
anitya = 389421;
- version# = "2.3.1";
+ version# = "2.3.4";
source = remoteGitHub {
suffix = "pypa/setuptools-scm";
tag = "vcs-versioning-v"+version;
- checksum = "rcbu8LlWlY6jmhC95pfnEKgGQuRxHY8_Pvo2jjmlJWSlyHSs1tFIRQ_FoMfi8YXo";
+ checksum = "TljjSQUxo07jMzfaVyieXD8dS_olgwEA2_RndGeIjlsdKWSa2oYZ5laMRjdgnXJS";
};
env = [
@@ -231,11 +231,11 @@ package python-setuptools-scm {
website = "https://setuptools-scm.readthedocs.io/en/latest";
anitya = 7874;
- version# = "10.2.1";
+ version# = "10.2.3";
source = remoteGitHub {
suffix = "pypa/setuptools-scm";
tag = "setuptools-scm-v"+version;
- checksum = "XnfdKDHzgtY3imPPz1lA1H0QHnjXlN5ZI-er0I-kfUq4w_a6RzUq8FCOJNBOkpK1";
+ checksum = "C76_jiIc_XanEZrpxLb47B3YArtmlt7HcpEOo0wZ5Z4mCFJb2HLIgOSOiRSfttpW";
};
env = [
diff --git a/internal/rosa/package/spirv.az b/internal/rosa/package/spirv.az
index cefa4d0a..21c07689 100644
--- a/internal/rosa/package/spirv.az
+++ b/internal/rosa/package/spirv.az
@@ -50,11 +50,11 @@ package spirv-llvm-translator {
website = "https://github.com/KhronosGroup/SPIRV-LLVM-Translator";
anitya = 227273;
- version# = "23.1.0";
+ version# = "23.1.1";
source = remoteGitHub {
suffix = "KhronosGroup/SPIRV-LLVM-Translator";
tag = "v"+version;
- checksum = "bKflf64sXw0NDhtqE_gT5cHrQV9JNZsAhvpTkDImp01xcyTXWPYoNB1CsbzGgFxh";
+ checksum = "8Sr087sQcaGw1yOodbRQAOv5bBj_QpxbOWGN75xxKqhRcuAUvdPZ9a009nlXZRwK";
};
// litArgs emits shell syntax
diff --git a/internal/rosa/package/tamago.az b/internal/rosa/package/tamago.az
index e0aca055..358c52a4 100644
--- a/internal/rosa/package/tamago.az
+++ b/internal/rosa/package/tamago.az
@@ -3,11 +3,11 @@ package tamago {
website = "https://github.com/usbarmory/tamago-go";
anitya = 388872;
- version# = "1.27.0";
+ version# = "1.27.1";
source = remoteGitHub {
suffix = "usbarmory/tamago-go";
tag = "tamago-go"+version;
- checksum = "PV8a5fccqZifVUG7HJ6jTFk_0x6YIu1BSgYByCdJoTllm4NuQc9-Ngk_nuS7Nb3i";
+ checksum = "TaWPzqqBMuhGslUm9CQvShJRjfONbFEr51mcM5zFlopYhYA6Tb58g8wRPc5a5lQ0";
};
env = [
diff --git a/internal/rosa/package/util-linux/a323dddbcd1ed05a10e7e870b3e1a48b4ed44a43.patch b/internal/rosa/package/util-linux/a323dddbcd1ed05a10e7e870b3e1a48b4ed44a43.patch
new file mode 100644
index 00000000..36d6f968
--- /dev/null
+++ b/internal/rosa/package/util-linux/a323dddbcd1ed05a10e7e870b3e1a48b4ed44a43.patch
@@ -0,0 +1,35 @@
+From a323dddbcd1ed05a10e7e870b3e1a48b4ed44a43 Mon Sep 17 00:00:00 2001
+From: Karel Zak <kzak@redhat.com>
+Date: Wed, 2 Sep 2026 13:32:27 +0200
+Subject: [PATCH] libmount: add missing fileutils.h include to hook_idmap.c
+
+The hook_idmap.c uses RESOLVE_NO_SYMLINKS (added by commit fb8e26535)
+but does not include fileutils.h, which provides the fallback #define
+for this constant.
+
+On Fedora (glibc 2.40+), this is masked because glibc's
+<bits/fcntl-linux.h> transitively includes <linux/openat2.h>, which
+defines RESOLVE_NO_SYMLINKS. On Ubuntu (and other distros with older
+glibc), <fcntl.h> does not pull in openat2.h, so the build fails:
+
+ hook_idmap.c:335:33: error: 'RESOLVE_NO_SYMLINKS' undeclared
+
+Fixes: fb8e26535 ("libmount: pin source path with openat2() for restricted users")
+Signed-off-by: Karel Zak <kzak@redhat.com>
+(cherry picked from commit 7e2e010874b10b3aabdc3c4c844c9ffc46a4a374)
+---
+ libmount/src/hook_idmap.c | 1 +
+ 1 file changed, 1 insertion(+)
+
+diff --git a/libmount/src/hook_idmap.c b/libmount/src/hook_idmap.c
+index 77494e29810..2c697b17154 100644
+--- a/libmount/src/hook_idmap.c
++++ b/libmount/src/hook_idmap.c
+@@ -23,6 +23,7 @@
+
+ #include "strutils.h"
+ #include "all-io.h"
++#include "fileutils.h"
+ #include "namespace.h"
+
+ #include "mountP.h"
diff --git a/internal/rosa/package/util-linux.az b/internal/rosa/package/util-linux/package.az
index 405f2ab7..f065718a 100644
--- a/internal/rosa/package/util-linux.az
+++ b/internal/rosa/package/util-linux/package.az
@@ -5,7 +5,7 @@ package util-linux {
// release candidates confuse Anitya
latest = anityaFallback;
- version# = "2.42.2";
+ version# = "2.42.3";
source = remoteTar {
url = "https://www.kernel.org/pub/linux/utils/util-linux/"+
"v"+join {
@@ -19,9 +19,10 @@ package util-linux {
};
sep = ".";
}+"/util-linux-"+version+".tar.gz";
- checksum = "Z4IZapPCKQP37aeWMDhxcvuOCy-IR_aHZvfUEMZ0T7trwC1znZACKH_3ddqXwBCg";
+ checksum = "VQ3NCM4kt0-TTrdJElBfckXNCGBv6UfXGTRm1poQ0XP0WBND4eG-O7n5Ly_a-Iw_";
compress = gzip;
};
+ patches = [ "a323dddbcd1ed05a10e7e870b3e1a48b4ed44a43.patch" ];
bin = [ "bash" ];
exec = make {
diff --git a/internal/store/data.go b/internal/store/data.go
index 34a0f261..380481a0 100644
--- a/internal/store/data.go
+++ b/internal/store/data.go
@@ -23,7 +23,8 @@ func entryEncode(w io.Writer, s *hst.State) error {
}
}
-// entryDecodeHeader calls entryReadHeader, returning [hst.AppError] for a non-nil error.
+// entryDecodeHeader calls entryReadHeader, returning [hst.AppError] for a
+// non-nil error.
func entryDecodeHeader(r io.Reader) (hst.Enablements, error) {
if et, err := entryReadHeader(r); err != nil {
return 0, &hst.AppError{Step: "decode state header", Err: err}
@@ -44,11 +45,14 @@ func entryDecode(r io.Reader, p *hst.State) (hst.Enablements, error) {
} else if err = p.Config.Validate(hst.VAllowInsecure); err != nil {
return et, err
} else if p.Enablements.Unwrap() != et {
- return et, &hst.AppError{Step: "validate state enablement", Err: os.ErrInvalid,
+ return et, &hst.AppError{
+ Step: "validate state enablement",
+ Err: os.ErrInvalid,
Msg: fmt.Sprintf(
"state entry %s has unexpected enablement byte %#x, %#x",
p.ID.String(), byte(p.Enablements.Unwrap()), byte(et),
- )}
+ ),
+ }
} else {
return et, nil
}
diff --git a/internal/store/header.go b/internal/store/header.go
index 5b5d73be..0e5a92a2 100644
--- a/internal/store/header.go
+++ b/internal/store/header.go
@@ -60,7 +60,8 @@ func (e *EntrySizeError) Error() string {
return "state entry file " + strconv.Quote(e.Name) + " is too short"
}
-// entryCheckFile checks whether [os.FileInfo] refers to a file that might hold [hst.State].
+// entryCheckFile checks whether [os.FileInfo] refers to a file that might hold
+// [hst.State].
func entryCheckFile(fi os.FileInfo) error {
if fi.IsDir() {
return syscall.EISDIR
diff --git a/internal/store/segment.go b/internal/store/segment.go
index 06849749..8b7dd0d6 100644
--- a/internal/store/segment.go
+++ b/internal/store/segment.go
@@ -7,6 +7,7 @@ import (
"os"
"strconv"
"sync"
+ "syscall"
"hakurei.app/check"
"hakurei.app/hst"
@@ -76,13 +77,20 @@ func (eh *EntryHandle) save(state *hst.State) error {
return err
}
+// KillFunc is the function signature of syscall.Kill.
+type KillFunc func(pid int, sig syscall.Signal) (err error)
+
// Load loads and validates the state entry header, and returns the
// [hst.Enablements] byte. For a non-nil v, the full state payload is decoded
-// and stored in the value pointed to by v.
+// and stored in the value pointed to by v, and if kill is non-nil, the presence
+// of the monitoring process is checked, and a stale entry is destroyed.
//
// Load validates the embedded [hst.Config] value. A non-nil error returned by
// Load is of type [hst.AppError].
-func (eh *EntryHandle) Load(v *hst.State) (hst.Enablements, error) {
+func (eh *EntryHandle) Load(
+ v *hst.State,
+ kill KillFunc,
+) (hst.Enablements, error) {
f, err := eh.open(os.O_RDONLY, 0)
if err != nil {
return 0, err
@@ -92,8 +100,41 @@ func (eh *EntryHandle) Load(v *hst.State) (hst.Enablements, error) {
if v != nil {
et, err = entryDecode(f, v)
if err == nil && v.ID != eh.ID {
- err = &hst.AppError{Step: "validate state identifier", Err: os.ErrInvalid,
- Msg: fmt.Sprintf("state entry %s has unexpected id %s", eh.ID.String(), v.ID.String())}
+ err = &hst.AppError{
+ Step: "validate state identifier",
+ Err: os.ErrInvalid,
+ Msg: fmt.Sprintf(
+ "state entry %s has unexpected id %s",
+ eh.ID.String(), v.ID.String(),
+ ),
+ }
+ }
+ if kill != nil {
+ errno := kill(v.PID, 0)
+ if errno != nil {
+ if !errors.Is(errno, syscall.ESRCH) {
+ err = &hst.AppError{
+ Step: "check monitor process",
+ Err: errno,
+ }
+ } else {
+ if err = eh.Destroy(); err != nil {
+ err = &hst.AppError{
+ Step: "destroy stale entry",
+ Err: err,
+ }
+ } else {
+ err = &hst.AppError{
+ Step: "load stale entry",
+ Err: errno,
+ Msg: fmt.Sprintf(
+ "stale entry %s",
+ eh.ID.String(),
+ ),
+ }
+ }
+ }
+ }
}
} else {
et, err = entryDecodeHeader(f)
@@ -127,7 +168,10 @@ type Handle struct {
// A non-nil error returned by Lock is of type [hst.AppError].
func (h *Handle) Lock() (unlock func(), err error) {
if unlock, err = h.fileMu.Lock(); err != nil {
- return nil, &hst.AppError{Step: "acquire lock on store segment " + strconv.Itoa(h.Identity), Err: err}
+ return nil, &hst.AppError{
+ Step: "acquire lock on store segment " + strconv.Itoa(h.Identity),
+ Err: err,
+ }
}
return
}
@@ -174,8 +218,11 @@ func (h *Handle) Entries() (iter.Seq[*EntryHandle], int, error) {
// this should never happen
if ent.IsDir() {
- eh.DecodeErr = &hst.AppError{Step: step,
- Err: errors.New("unexpected directory " + strconv.Quote(ent.Name()) + " in store")}
+ eh.DecodeErr = &hst.AppError{
+ Step: step,
+ Err: errors.New("unexpected directory " +
+ strconv.Quote(ent.Name()) + " in store"),
+ }
goto out
}
@@ -186,7 +233,10 @@ func (h *Handle) Entries() (iter.Seq[*EntryHandle], int, error) {
// this either indicates a serious bug or external interference
if err := eh.ID.UnmarshalText([]byte(ent.Name())); err != nil {
- eh.DecodeErr = &hst.AppError{Step: "decode store segment entry", Err: err}
+ eh.DecodeErr = &hst.AppError{
+ Step: "decode store segment entry",
+ Err: err,
+ }
goto out
}
diff --git a/internal/store/segment_test.go b/internal/store/segment_test.go
index a244fcdc..6316a278 100644
--- a/internal/store/segment_test.go
+++ b/internal/store/segment_test.go
@@ -2,6 +2,7 @@ package store_test
import (
"errors"
+ "fmt"
"io"
"iter"
"os"
@@ -55,7 +56,7 @@ func TestStateEntryHandle(t *testing.T) {
if err := save(&eh, nil); !reflect.DeepEqual(err, wantErr()) {
t.Errorf("save: error = %v, want %v", err, wantErr())
}
- if _, err := eh.Load(nil); !reflect.DeepEqual(err, wantErr()) {
+ if _, err := eh.Load(nil, nil); !reflect.DeepEqual(err, wantErr()) {
t.Errorf("load: error = %v, want %v", err, wantErr())
}
})
@@ -95,8 +96,10 @@ func TestStateEntryHandle(t *testing.T) {
t.Run("saveload", func(t *testing.T) {
t.Parallel()
- eh := store.EntryHandle{Pathname: check.MustAbs(t.TempDir()).Append("entry"),
- ID: store.NewTemplateState().ID}
+ eh := store.EntryHandle{
+ Pathname: check.MustAbs(t.TempDir()).Append("entry"),
+ ID: store.NewTemplateState().ID,
+ }
if err := save(&eh, store.NewTemplateState()); err != nil {
t.Fatalf("save: error = %v", err)
@@ -125,7 +128,7 @@ func TestStateEntryHandle(t *testing.T) {
t.Run("load header only", func(t *testing.T) {
t.Parallel()
- if et, err := eh.Load(nil); err != nil {
+ if et, err := eh.Load(nil, nil); err != nil {
t.Fatalf("load: error = %v", err)
} else if want := store.NewTemplateState().Enablements.Unwrap(); et != want {
t.Errorf("load: et = %x, want %x", et, want)
@@ -136,7 +139,7 @@ func TestStateEntryHandle(t *testing.T) {
t.Parallel()
var got hst.State
- if _, err := eh.Load(&got); err != nil {
+ if _, err := eh.Load(&got, nil); err != nil {
t.Fatalf("load: error = %v", err)
} else if want := store.NewTemplateState(); !reflect.DeepEqual(&got, want) {
t.Errorf("load: %#v, want %#v", &got, want)
@@ -145,11 +148,64 @@ func TestStateEntryHandle(t *testing.T) {
t.Run("load inconsistent", func(t *testing.T) {
t.Parallel()
- wantErr := &hst.AppError{Step: "validate state identifier", Err: os.ErrInvalid,
- Msg: "state entry 00000000000000000000000000000000 has unexpected id aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"}
+ wantErr := &hst.AppError{
+ Step: "validate state identifier",
+ Err: os.ErrInvalid,
+ Msg: "state entry 00000000000000000000000000000000 has unexpected id aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa",
+ }
ehi := store.EntryHandle{Pathname: eh.Pathname}
- if _, err := ehi.Load(new(hst.State)); !reflect.DeepEqual(err, wantErr) {
+ if _, err := ehi.Load(new(hst.State), nil); !reflect.DeepEqual(err, wantErr) {
+ t.Errorf("load: error = %#v, want %#v", err, wantErr)
+ }
+ })
+
+ t.Run("stale fault", func(t *testing.T) {
+ t.Parallel()
+ wantErr := &hst.AppError{
+ Step: "check monitor process",
+ Err: syscall.EFAULT,
+ }
+
+ if _, err := eh.Load(new(hst.State), func(pid int, sig syscall.Signal) (err error) {
+ if pid != store.NewTemplateState().PID {
+ return fmt.Errorf("bad pid %d", pid)
+ }
+ if sig != 0 {
+ return fmt.Errorf("bad signal %d", sig)
+ }
+ return syscall.EFAULT
+ }); !reflect.DeepEqual(err, wantErr) {
+ t.Errorf("load: error = %#v, want %#v", err, wantErr)
+ }
+ })
+
+ t.Run("stale", func(t *testing.T) {
+ t.Parallel()
+ wantErr := &hst.AppError{
+ Step: "load stale entry",
+ Err: syscall.ESRCH,
+ Msg: "stale entry aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa",
+ }
+
+ ehi := store.EntryHandle{
+ Pathname: check.MustAbs(t.TempDir()).Append("entry"),
+ ID: eh.ID,
+ }
+
+ if err := save(&ehi, store.NewTemplateState()); err != nil {
+ t.Fatalf("save: error = %v", err)
+ }
+
+ if _, err := ehi.Load(new(hst.State), func(pid int, sig syscall.Signal) (err error) {
+ if pid != store.NewTemplateState().PID {
+ return fmt.Errorf("bad pid %d", pid)
+ }
+ if sig != 0 {
+ return fmt.Errorf("bad signal %d", sig)
+ }
+ return syscall.ESRCH
+ }); !reflect.DeepEqual(err, wantErr) {
t.Errorf("load: error = %#v, want %#v", err, wantErr)
}
})
@@ -229,7 +285,9 @@ func TestSegmentHandle(t *testing.T) {
}
}
- slices.SortFunc(got, func(a, b *store.EntryHandle) int { return strings.Compare(a.Pathname.String(), b.Pathname.String()) })
+ slices.SortFunc(got, func(a, b *store.EntryHandle) int {
+ return strings.Compare(a.Pathname.String(), b.Pathname.String())
+ })
want := tc.want(func(err error, name string) *store.EntryHandle {
eh := store.EntryHandle{DecodeErr: err, Pathname: segment.Append(name)}
if err == nil {
@@ -247,6 +305,8 @@ func TestSegmentHandle(t *testing.T) {
}
t.Run("nonexistent", func(t *testing.T) {
+ t.Parallel()
+
var wantErr = &hst.AppError{Step: "read store segment entries", Err: &os.PathError{
Op: "open",
Path: "/proc/nonexistent",
diff --git a/internal/store/store.go b/internal/store/store.go
index 3604521c..eb9cec41 100644
--- a/internal/store/store.go
+++ b/internal/store/store.go
@@ -1,4 +1,5 @@
-// Package store implements cross-process state tracking for hakurei container instances.
+// Package store provides storage for hakurei instance states, safe for
+// concurrent and cross-process use.
package store
import (
@@ -15,11 +16,15 @@ import (
"hakurei.app/internal/lockedfile"
)
-// MutexName is the pathname of the file backing [lockedfile.Mutex] of a [Store] and [Handle].
+// MutexName is the pathname of the file backing [lockedfile.Mutex] of a [Store]
+// and [Handle].
const MutexName = "lock"
-// A Store keeps track of [hst.State] via a well-known filesystem accessible to all hakurei priv-side processes.
-// Access to store data and related resources are synchronised on a per-segment basis via [Handle].
+// A Store keeps track of [hst.State] via a well-known filesystem accessible to
+// all hakurei priv-side processes.
+//
+// Access to store data and related resources are synchronised on a per-segment
+// basis via [Handle].
type Store struct {
// Pathname of directory that the store is rooted in.
base *check.Absolute
@@ -28,8 +33,10 @@ type Store struct {
handles sync.Map
// Inter-process mutex to synchronise operations against the entire store.
- // Held during List and when initialising previously unknown identities during Do.
- // Must not be accessed directly. Callers should use the bigLock method instead.
+ //
+ // Held during List and when initialising previously unknown identities
+ // during Do. Must not be accessed directly. Callers should use the bigLock
+ // method instead.
fileMu *lockedfile.Mutex
// For creating the base directory.
@@ -43,11 +50,17 @@ type Store struct {
func (s *Store) bigLock() (unlock func(), err error) {
s.mkdirOnce.Do(func() { s.mkdirErr = os.MkdirAll(s.base.String(), 0700) })
if s.mkdirErr != nil {
- return nil, &hst.AppError{Step: "create state store directory", Err: s.mkdirErr}
+ return nil, &hst.AppError{
+ Step: "create state store directory",
+ Err: s.mkdirErr,
+ }
}
if unlock, err = s.fileMu.Lock(); err != nil {
- return nil, &hst.AppError{Step: "acquire lock on the state store", Err: err}
+ return nil, &hst.AppError{
+ Step: "acquire lock on the state store",
+ Err: err,
+ }
}
return
}
@@ -73,7 +86,10 @@ func (s *Store) Handle(identity int) (*Handle, error) {
if err != nil && !errors.Is(err, fs.ErrExist) {
// handle methods will likely return ENOENT
s.handles.CompareAndDelete(identity, h)
- return nil, &hst.AppError{Step: "create store segment directory", Err: err}
+ return nil, &hst.AppError{
+ Step: "create store segment directory",
+ Err: err,
+ }
}
}
return h, nil
@@ -88,8 +104,9 @@ type SegmentIdentity struct {
}
// Segments returns an iterator over all [SegmentIdentity] known to the [Store].
-// To obtain a [Handle] on a segment, caller must then call [Store.Handle].
-// A non-nil error returned by segments is of type [hst.AppError].
+//
+// To obtain a [Handle] on a segment, caller must then call [Store.Handle]. A
+// non-nil error returned by segments is of type [hst.AppError].
func (s *Store) Segments() (iter.Seq[SegmentIdentity], int, error) {
// read directory contents, should only contain storeMutexName and identity
var entries []os.DirEntry
@@ -102,7 +119,10 @@ func (s *Store) Segments() (iter.Seq[SegmentIdentity], int, error) {
unlock()
if err != nil && !errors.Is(err, os.ErrNotExist) {
- return nil, -1, &hst.AppError{Step: "read store segments", Err: err}
+ return nil, -1, &hst.AppError{
+ Step: "read store segments",
+ Err: err,
+ }
}
}
@@ -126,19 +146,25 @@ func (s *Store) Segments() (iter.Seq[SegmentIdentity], int, error) {
}
// this should never happen
- si.Err = &hst.AppError{Step: step, Err: syscall.ENOTDIR,
- Msg: "skipped non-directory entry " + strconv.Quote(ent.Name())}
+ si.Err = &hst.AppError{
+ Step: step, Err: syscall.ENOTDIR,
+ Msg: "skipped non-directory entry " + strconv.Quote(ent.Name()),
+ }
goto out
}
// failure paths either indicates a serious bug or external interference
if v, err := strconv.Atoi(ent.Name()); err != nil {
- si.Err = &hst.AppError{Step: step, Err: err,
- Msg: "skipped non-identity entry " + strconv.Quote(ent.Name())}
+ si.Err = &hst.AppError{
+ Step: step, Err: err,
+ Msg: "skipped non-identity entry " + strconv.Quote(ent.Name()),
+ }
goto out
} else if v < hst.IdentityStart || v > hst.IdentityEnd {
- si.Err = &hst.AppError{Step: step, Err: syscall.ERANGE,
- Msg: "skipped out of bounds entry " + strconv.Itoa(v)}
+ si.Err = &hst.AppError{
+ Step: step, Err: syscall.ERANGE,
+ Msg: "skipped out of bounds entry " + strconv.Itoa(v),
+ }
goto out
} else {
si.Identity = v
@@ -152,9 +178,12 @@ func (s *Store) Segments() (iter.Seq[SegmentIdentity], int, error) {
}, l, nil
}
-// All returns a non-reusable iterator over all [EntryHandle] known to this [Store].
-// Callers must call copyError after completing iteration and handle the error accordingly.
-// A non-nil error returned by copyError is of type [hst.AppError].
+// All returns a non-reusable iterator over all [EntryHandle] known to this
+// [Store]. The resulting handles may be retained, but are only safe to use
+// during the iteration producing them.
+//
+// Callers must call copyError after completing iteration and handle the error
+// accordingly. A non-nil error returned by copyError is of type [hst.AppError].
func (s *Store) All() (entries iter.Seq[*EntryHandle], copyError func() error) {
var savedErr error
return func(yield func(*EntryHandle) bool) {
@@ -197,7 +226,12 @@ func (s *Store) All() (entries iter.Seq[*EntryHandle], copyError func() error) {
}
// New returns the address of a new instance of [Store].
-// Multiple instances of [Store] rooted in the same directory is possible, but unsupported.
+//
+// Multiple instances of [Store] rooted in the same directory is possible, but
+// unsupported.
func New(base *check.Absolute) *Store {
- return &Store{base: base, fileMu: lockedfile.MutexAt(base.Append(MutexName).String())}
+ return &Store{
+ base: base,
+ fileMu: lockedfile.MutexAt(base.Append(MutexName).String()),
+ }
}