From 2900eaabec8927038b4037ac63be56e3aa565157 Mon Sep 17 00:00:00 2001 From: "red-hat-konflux[bot]" <126015336+red-hat-konflux[bot]@users.noreply.github.com> Date: Wed, 29 Oct 2025 04:20:47 +0000 Subject: [PATCH] chore(deps): update module github.com/containers/storage to v1.59.1 Signed-off-by: red-hat-konflux <126015336+red-hat-konflux[bot]@users.noreply.github.com> --- go.mod | 10 +- go.sum | 22 +- .../Microsoft/hcsshim/.clang-format | 12 + .../Microsoft/hcsshim/.golangci.yml | 43 +- vendor/github.com/Microsoft/hcsshim/Makefile | 116 +---- .../Microsoft/hcsshim/Makefile.bootfiles | 197 +++++++++ vendor/github.com/Microsoft/hcsshim/README.md | 2 +- .../Microsoft/hcsshim/internal/hcs/process.go | 9 +- .../hcsshim/internal/hcs/schema2/chipset.go | 2 + .../hcs/schema2/{cim_mount.go => cimfs.go} | 8 - .../hcsshim/internal/hcs/schema2/firmware.go | 8 + .../hcsshim/internal/hcs/schema2/memory_2.go | 49 --- .../hcs/schema2/memory_backing_type.go | 21 + .../hcsshim/internal/hcs/schema2/numa.go | 19 + .../hcsshim/internal/hcs/schema2/numa_node.go | 17 + .../internal/hcs/schema2/numa_node_memory.go | 19 + .../hcs/schema2/numa_node_processor.go | 17 + .../internal/hcs/schema2/numa_processors.go | 21 + .../internal/hcs/schema2/numa_setting.go | 21 + .../internal/hcs/schema2/processor_2.go | 23 - .../internal/hcs/schema2/properties.go | 2 + .../internal/hcs/schema2/property_type.go | 1 + .../hcsshim/internal/hcs/schema2/topology.go | 12 +- .../internal/hcs/schema2/virtual_machine.go | 39 +- .../hcs/schema2/virtual_machine_memory.go | 33 ++ .../hcs/schema2/virtual_machine_processor.go | 21 + .../hcs/schema2/virtual_pci_device.go | 3 +- .../internal/hcs/schema2/virtual_slit_type.go | 23 + .../hcs/schema2/windows_crash_reporting.go | 2 + .../Microsoft/hcsshim/internal/hcs/system.go | 21 +- .../hcsshim/internal/hns/hnsaccelnet.go | 4 +- .../hcsshim/internal/jobobject/jobobject.go | 20 +- .../hcsshim/internal/jobobject/limits.go | 1 + .../Microsoft/hcsshim/internal/log/context.go | 28 +- .../Microsoft/hcsshim/internal/log/format.go | 4 +- .../Microsoft/hcsshim/internal/log/scrub.go | 15 +- .../hcsshim/internal/vmcompute/vmcompute.go | 2 +- .../hcsshim/internal/wclayer/legacy.go | 1 + .../hcsshim/internal/winapi/cimfs.go | 11 + .../internal/winapi/zsyscall_windows.go | 146 +++++++ .../osversion/platform_compat_windows.go | 22 +- .../hcsshim/osversion/windowsbuilds.go | 7 + .../github.com/containers/storage/.cirrus.yml | 5 +- vendor/github.com/containers/storage/Makefile | 2 +- vendor/github.com/containers/storage/VERSION | 2 +- .../containers/storage/deprecated.go | 1 - .../containers/storage/drivers/aufs/aufs.go | 16 +- .../containers/storage/drivers/btrfs/btrfs.go | 12 + .../containers/storage/drivers/chown.go | 4 +- .../containers/storage/drivers/driver.go | 23 +- .../storage/drivers/overlay/overlay.go | 129 ++++-- .../containers/storage/drivers/vfs/driver.go | 48 ++- .../storage/drivers/windows/windows.go | 16 +- .../containers/storage/drivers/zfs/zfs.go | 12 + .../internal/rawfilelock/rawfilelock.go | 64 +++ .../internal/rawfilelock/rawfilelock_unix.go | 49 +++ .../rawfilelock/rawfilelock_windows.go | 48 +++ .../staging_lockfile/staging_lockfile.go | 147 +++++++ .../storage/internal/tempdir/tempdir.go | 243 +++++++++++ .../github.com/containers/storage/layers.go | 104 +++-- .../containers/storage/pkg/archive/archive.go | 395 ++++++++++-------- .../storage/pkg/archive/archive_unix.go | 2 +- .../storage/pkg/archive/archive_windows.go | 2 +- .../containers/storage/pkg/archive/changes.go | 8 +- .../storage/pkg/chunked/compression_linux.go | 101 ++++- .../pkg/chunked/compressor/compressor.go | 65 ++- .../chunked/internal/minimal/compression.go | 15 +- .../storage/pkg/chunked/storage_linux.go | 95 +++-- .../pkg/chunked/storage_unsupported.go | 5 +- .../storage/pkg/lockfile/lockfile.go | 97 ++--- .../storage/pkg/lockfile/lockfile_unix.go | 40 -- .../storage/pkg/lockfile/lockfile_windows.go | 36 -- vendor/github.com/containers/storage/store.go | 93 +++-- .../containers/storage/types/options.go | 24 +- .../github.com/containers/storage/userns.go | 2 +- .../tchap/go-patricia/v2/patricia/patricia.go | 2 +- vendor/golang.org/x/sync/errgroup/errgroup.go | 20 +- vendor/golang.org/x/sys/unix/zerrors_linux.go | 25 +- .../x/sys/unix/zerrors_linux_386.go | 1 + .../x/sys/unix/zerrors_linux_amd64.go | 1 + .../x/sys/unix/zerrors_linux_arm.go | 1 + .../x/sys/unix/zerrors_linux_arm64.go | 1 + .../x/sys/unix/zerrors_linux_loong64.go | 1 + .../x/sys/unix/zerrors_linux_mips.go | 1 + .../x/sys/unix/zerrors_linux_mips64.go | 1 + .../x/sys/unix/zerrors_linux_mips64le.go | 1 + .../x/sys/unix/zerrors_linux_mipsle.go | 1 + .../x/sys/unix/zerrors_linux_ppc.go | 1 + .../x/sys/unix/zerrors_linux_ppc64.go | 1 + .../x/sys/unix/zerrors_linux_ppc64le.go | 1 + .../x/sys/unix/zerrors_linux_riscv64.go | 1 + .../x/sys/unix/zerrors_linux_s390x.go | 1 + .../x/sys/unix/zerrors_linux_sparc64.go | 1 + vendor/golang.org/x/sys/unix/ztypes_linux.go | 108 ++++- .../golang.org/x/sys/unix/ztypes_linux_386.go | 16 + .../x/sys/unix/ztypes_linux_amd64.go | 16 + .../golang.org/x/sys/unix/ztypes_linux_arm.go | 16 + .../x/sys/unix/ztypes_linux_arm64.go | 16 + .../x/sys/unix/ztypes_linux_loong64.go | 16 + .../x/sys/unix/ztypes_linux_mips.go | 16 + .../x/sys/unix/ztypes_linux_mips64.go | 16 + .../x/sys/unix/ztypes_linux_mips64le.go | 16 + .../x/sys/unix/ztypes_linux_mipsle.go | 16 + .../golang.org/x/sys/unix/ztypes_linux_ppc.go | 16 + .../x/sys/unix/ztypes_linux_ppc64.go | 16 + .../x/sys/unix/ztypes_linux_ppc64le.go | 16 + .../x/sys/unix/ztypes_linux_riscv64.go | 16 + .../x/sys/unix/ztypes_linux_s390x.go | 16 + .../x/sys/unix/ztypes_linux_sparc64.go | 16 + vendor/modules.txt | 15 +- 110 files changed, 2526 insertions(+), 858 deletions(-) create mode 100644 vendor/github.com/Microsoft/hcsshim/.clang-format create mode 100644 vendor/github.com/Microsoft/hcsshim/Makefile.bootfiles rename vendor/github.com/Microsoft/hcsshim/internal/hcs/schema2/{cim_mount.go => cimfs.go} (70%) create mode 100644 vendor/github.com/Microsoft/hcsshim/internal/hcs/schema2/firmware.go delete mode 100644 vendor/github.com/Microsoft/hcsshim/internal/hcs/schema2/memory_2.go create mode 100644 vendor/github.com/Microsoft/hcsshim/internal/hcs/schema2/memory_backing_type.go create mode 100644 vendor/github.com/Microsoft/hcsshim/internal/hcs/schema2/numa.go create mode 100644 vendor/github.com/Microsoft/hcsshim/internal/hcs/schema2/numa_node.go create mode 100644 vendor/github.com/Microsoft/hcsshim/internal/hcs/schema2/numa_node_memory.go create mode 100644 vendor/github.com/Microsoft/hcsshim/internal/hcs/schema2/numa_node_processor.go create mode 100644 vendor/github.com/Microsoft/hcsshim/internal/hcs/schema2/numa_processors.go create mode 100644 vendor/github.com/Microsoft/hcsshim/internal/hcs/schema2/numa_setting.go delete mode 100644 vendor/github.com/Microsoft/hcsshim/internal/hcs/schema2/processor_2.go create mode 100644 vendor/github.com/Microsoft/hcsshim/internal/hcs/schema2/virtual_machine_memory.go create mode 100644 vendor/github.com/Microsoft/hcsshim/internal/hcs/schema2/virtual_machine_processor.go create mode 100644 vendor/github.com/Microsoft/hcsshim/internal/hcs/schema2/virtual_slit_type.go create mode 100644 vendor/github.com/containers/storage/internal/rawfilelock/rawfilelock.go create mode 100644 vendor/github.com/containers/storage/internal/rawfilelock/rawfilelock_unix.go create mode 100644 vendor/github.com/containers/storage/internal/rawfilelock/rawfilelock_windows.go create mode 100644 vendor/github.com/containers/storage/internal/staging_lockfile/staging_lockfile.go create mode 100644 vendor/github.com/containers/storage/internal/tempdir/tempdir.go diff --git a/go.mod b/go.mod index df92e6a4a..711ab8e04 100644 --- a/go.mod +++ b/go.mod @@ -23,7 +23,7 @@ require ( github.com/Azure/go-ansiterm v0.0.0-20250102033503-faa5f7b0171c // indirect github.com/BurntSushi/toml v1.5.0 // indirect github.com/Microsoft/go-winio v0.6.2 // indirect - github.com/Microsoft/hcsshim v0.12.9 // indirect + github.com/Microsoft/hcsshim v0.13.0 // indirect github.com/containerd/cgroups/v3 v3.0.5 // indirect github.com/containerd/errdefs v1.0.0 // indirect github.com/containerd/errdefs/pkg v0.3.0 // indirect @@ -31,7 +31,7 @@ require ( github.com/containerd/typeurl/v2 v2.2.3 // indirect github.com/containers/libtrust v0.0.0-20230121012942-c1716e8a8d01 // indirect github.com/containers/ocicrypt v1.2.1 // indirect - github.com/containers/storage v1.58.0 // indirect + github.com/containers/storage v1.59.1 // indirect github.com/cyphar/filepath-securejoin v0.4.1 // indirect github.com/docker/distribution v2.8.3+incompatible // indirect github.com/docker/docker-credential-helpers v0.9.3 // indirect @@ -66,7 +66,7 @@ require ( github.com/planetscale/vtprotobuf v0.6.1-0.20240319094008-0393e58bdf10 // indirect github.com/sirupsen/logrus v1.9.3 // indirect github.com/sylabs/sif/v2 v2.21.1 // indirect - github.com/tchap/go-patricia/v2 v2.3.2 // indirect + github.com/tchap/go-patricia/v2 v2.3.3 // indirect github.com/ulikunitz/xz v0.5.12 // indirect github.com/vbatts/tar-split v0.12.1 // indirect go.opencensus.io v0.24.0 // indirect @@ -76,8 +76,8 @@ require ( go.opentelemetry.io/otel/metric v1.37.0 // indirect go.opentelemetry.io/otel/trace v1.37.0 // indirect golang.org/x/mod v0.24.0 // indirect - golang.org/x/sync v0.13.0 // indirect - golang.org/x/sys v0.33.0 // indirect + golang.org/x/sync v0.16.0 // indirect + golang.org/x/sys v0.34.0 // indirect google.golang.org/genproto/googleapis/rpc v0.0.0-20250313205543-e70fdf4c4cb4 // indirect google.golang.org/grpc v1.71.0 // indirect google.golang.org/protobuf v1.36.6 // indirect diff --git a/go.sum b/go.sum index 24e657883..b97f053b3 100644 --- a/go.sum +++ b/go.sum @@ -10,8 +10,8 @@ github.com/BurntSushi/toml v1.5.0 h1:W5quZX/G/csjUnuI8SUYlsHs9M38FC7znL0lIO+DvMg github.com/BurntSushi/toml v1.5.0/go.mod h1:ukJfTF/6rtPPRCnwkur4qwRxa8vTRFBF0uk2lLoLwho= github.com/Microsoft/go-winio v0.6.2 h1:F2VQgta7ecxGYO8k3ZZz3RS8fVIXVxONVUPlNERoyfY= github.com/Microsoft/go-winio v0.6.2/go.mod h1:yd8OoFMLzJbo9gZq8j5qaps8bJ9aShtEA8Ipt1oGCvU= -github.com/Microsoft/hcsshim v0.12.9 h1:2zJy5KA+l0loz1HzEGqyNnjd3fyZA31ZBCGKacp6lLg= -github.com/Microsoft/hcsshim v0.12.9/go.mod h1:fJ0gkFAna6ukt0bLdKB8djt4XIJhF/vEPuoIWYVvZ8Y= +github.com/Microsoft/hcsshim v0.13.0 h1:/BcXOiS6Qi7N9XqUcv27vkIuVOkBEcWstd2pMlWSeaA= +github.com/Microsoft/hcsshim v0.13.0/go.mod h1:9KWJ/8DgU+QzYGupX4tzMhRQE8h6w90lH6HAaclpEok= github.com/beorn7/perks v1.0.1 h1:VlbKKnNfV8bJzeqoa4cOKqO6bYr3WgKZxO8Z16+hsOM= github.com/beorn7/perks v1.0.1/go.mod h1:G2ZrVWU2WbWT9wwq4/hrbKbnv/1ERSJQ0ibhJ6rlkpw= github.com/cenkalti/backoff/v4 v4.3.0 h1:MyRJ/UdXutAwSAT+s3wNd7MfTIcy71VQueUuFK343L8= @@ -39,8 +39,8 @@ github.com/containers/libtrust v0.0.0-20230121012942-c1716e8a8d01 h1:Qzk5C6cYgle github.com/containers/libtrust v0.0.0-20230121012942-c1716e8a8d01/go.mod h1:9rfv8iPl1ZP7aqh9YA68wnZv2NUDbXdcdPHVz0pFbPY= github.com/containers/ocicrypt v1.2.1 h1:0qIOTT9DoYwcKmxSt8QJt+VzMY18onl9jUXsxpVhSmM= github.com/containers/ocicrypt v1.2.1/go.mod h1:aD0AAqfMp0MtwqWgHM1bUwe1anx0VazI108CRrSKINQ= -github.com/containers/storage v1.58.0 h1:Q7SyyCCjqgT3wYNgRNIL8o/wUS92heIj2/cc8Sewvcc= -github.com/containers/storage v1.58.0/go.mod h1:w7Jl6oG+OpeLGLzlLyOZPkmUso40kjpzgrHUk5tyBlo= +github.com/containers/storage v1.59.1 h1:11Zu68MXsEQGBBd+GadPrHPpWeqjKS8hJDGiAHgIqDs= +github.com/containers/storage v1.59.1/go.mod h1:KoAYHnAjP3/cTsRS+mmWZGkufSY2GACiKQ4V3ZLQnR0= github.com/cpuguy83/go-md2man/v2 v2.0.6/go.mod h1:oOW0eioCTA6cOiMLiUPZOpcVxMig6NIQQ7OS05n1F4g= github.com/creack/pty v1.1.18 h1:n56/Zwd5o6whRC5PMGretI4IdRLlmBXYNjScPaBgsbY= github.com/creack/pty v1.1.18/go.mod h1:MOBLtS5ELjhRRrroQr9kyvTxUAFNvYEK993ew/Vr4O4= @@ -210,8 +210,8 @@ github.com/stretchr/testify v1.10.0 h1:Xv5erBjTwe/5IxqUQTdXv5kgmIvbHo3QQyRwhJsOf github.com/stretchr/testify v1.10.0/go.mod h1:r2ic/lqez/lEtzL7wO/rwa5dbSLXVDPFyf8C91i36aY= github.com/sylabs/sif/v2 v2.21.1 h1:GZ0b5//AFAqJEChd8wHV/uSKx/l1iuGYwjR8nx+4wPI= github.com/sylabs/sif/v2 v2.21.1/go.mod h1:YoqEGQnb5x/ItV653bawXHZJOXQaEWpGwHsSD3YePJI= -github.com/tchap/go-patricia/v2 v2.3.2 h1:xTHFutuitO2zqKAQ5rCROYgUb7Or/+IC3fts9/Yc7nM= -github.com/tchap/go-patricia/v2 v2.3.2/go.mod h1:VZRHKAb53DLaG+nA9EaYYiaEx6YztwDlLElMsnSHD4k= +github.com/tchap/go-patricia/v2 v2.3.3 h1:xfNEsODumaEcCcY3gI0hYPZ/PcpVv5ju6RMAhgwZDDc= +github.com/tchap/go-patricia/v2 v2.3.3/go.mod h1:VZRHKAb53DLaG+nA9EaYYiaEx6YztwDlLElMsnSHD4k= github.com/ulikunitz/xz v0.5.12 h1:37Nm15o69RwBkXM0J6A5OlE67RZTfzUxTj8fB3dfcsc= github.com/ulikunitz/xz v0.5.12/go.mod h1:nbz6k7qbPmH4IRqmfOplQw/tblSgqTqBwxkY0oWt/14= github.com/vbatts/tar-split v0.12.1 h1:CqKoORW7BUWBe7UL/iqTVvkTBOF8UvOMKOIZykxnnbo= @@ -266,16 +266,16 @@ golang.org/x/sync v0.0.0-20181108010431-42b317875d0f/go.mod h1:RxMgew5VJxzue5/jJ golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20190911185100-cd5d95a43a6e/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20201020160332-67f06af15bc9/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= -golang.org/x/sync v0.13.0 h1:AauUjRAJ9OSnvULf/ARrrVywoJDy0YS2AwQ98I37610= -golang.org/x/sync v0.13.0/go.mod h1:1dzgHSNfp02xaA81J2MS99Qcpr2w7fw1gpm99rleRqA= +golang.org/x/sync v0.16.0 h1:ycBJEhp9p4vXvUZNszeOq0kGTPghopOL8q0fq3vstxw= +golang.org/x/sync v0.16.0/go.mod h1:1dzgHSNfp02xaA81J2MS99Qcpr2w7fw1gpm99rleRqA= golang.org/x/sys v0.0.0-20180830151530-49385e6e1522/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200930185726-fdedc70b468f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20210616094352-59db8d763f22/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20220715151400-c0bba94af5f8/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.33.0 h1:q3i8TbbEz+JRD9ywIRlyRAQbM0qF7hu24q3teo2hbuw= -golang.org/x/sys v0.33.0/go.mod h1:BJP2sWEmIv4KK5OTEluFJCKSidICx8ciO85XgH3Ak8k= +golang.org/x/sys v0.34.0 h1:H5Y5sJ2L2JRdyv7ROF1he/lPdvFsd0mJHFw2ThKHxLA= +golang.org/x/sys v0.34.0/go.mod h1:BJP2sWEmIv4KK5OTEluFJCKSidICx8ciO85XgH3Ak8k= golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= golang.org/x/text v0.25.0 h1:qVyWApTSYLk/drJRO5mDlNYskwQznZmkpV2c8q9zls4= @@ -299,7 +299,7 @@ google.golang.org/appengine v1.4.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7 google.golang.org/genproto v0.0.0-20180817151627-c66870c02cf8/go.mod h1:JiN7NxoALGmiZfu7CAH4rXhgtRTLTxftemlI0sWmxmc= google.golang.org/genproto v0.0.0-20190819201941-24fa4b261c55/go.mod h1:DMBHOl98Agz4BDEuKkezgsaosCRResVns1a3J2ZsMNc= google.golang.org/genproto v0.0.0-20200526211855-cb27e3aa2013/go.mod h1:NbSheEEYHJ7i3ixzK3sjbqSGDJWnxyFXZblF3eUsNvo= -google.golang.org/genproto v0.0.0-20240123012728-ef4313101c80 h1:KAeGQVN3M9nD0/bQXnr/ClcEMJ968gUXJQ9pwfSynuQ= +google.golang.org/genproto v0.0.0-20240227224415-6ceb2ff114de h1:F6qOa9AZTYJXOUEr4jDysRDLrm4PHePlge4v4TGAlxY= google.golang.org/genproto/googleapis/api v0.0.0-20250303144028-a0af3efb3deb h1:p31xT4yrYrSM/G4Sn2+TNUkVhFCbG9y8itM2S6Th950= google.golang.org/genproto/googleapis/api v0.0.0-20250303144028-a0af3efb3deb/go.mod h1:jbe3Bkdp+Dh2IrslsFCklNhweNTBgSYanP1UXhJDhKg= google.golang.org/genproto/googleapis/rpc v0.0.0-20250313205543-e70fdf4c4cb4 h1:iK2jbkWL86DXjEx0qiHcRE9dE4/Ahua5k6V8OWFb//c= diff --git a/vendor/github.com/Microsoft/hcsshim/.clang-format b/vendor/github.com/Microsoft/hcsshim/.clang-format new file mode 100644 index 000000000..fd843ce39 --- /dev/null +++ b/vendor/github.com/Microsoft/hcsshim/.clang-format @@ -0,0 +1,12 @@ +Language: Cpp +BasedOnStyle: Microsoft +BreakBeforeBraces: Attach +PointerAlignment: Left +AllowShortFunctionsOnASingleLine: All +# match Go style +IndentCaseLabels: false +# don't break comments over line limit (needed for CodeQL exceptions) +ReflowComments: false +InsertNewlineAtEOF: true +KeepEmptyLines: + AtEndOfFile: true diff --git a/vendor/github.com/Microsoft/hcsshim/.golangci.yml b/vendor/github.com/Microsoft/hcsshim/.golangci.yml index 7d38a2fb9..113e6f07a 100644 --- a/vendor/github.com/Microsoft/hcsshim/.golangci.yml +++ b/vendor/github.com/Microsoft/hcsshim/.golangci.yml @@ -5,9 +5,6 @@ run: - admin - functional - integration - skip-dirs: - # paths are relative to module root - - cri-containerd/test-images linters: enable: @@ -34,13 +31,15 @@ linters-settings: # struct order is often for Win32 compat # also, ignore pointer bytes/GC issues for now until performance becomes an issue - fieldalignment - check-shadowing: true stylecheck: # https://staticcheck.io/docs/checks checks: ["all"] issues: + exclude-dirs: + # paths are relative to module root + - cri-containerd/test-images exclude-rules: # err is very often shadowed in nested scopes - linters: @@ -70,22 +69,22 @@ issues: - path: layer.go linters: - stylecheck - Text: "ST1003:" + text: "ST1003:" - path: hcsshim.go linters: - stylecheck - Text: "ST1003:" + text: "ST1003:" - path: cmd\\ncproxy\\nodenetsvc\\ linters: - stylecheck - Text: "ST1003:" + text: "ST1003:" - path: cmd\\ncproxy_mock\\ linters: - stylecheck - Text: "ST1003:" + text: "ST1003:" - path: internal\\hcs\\schema2\\ linters: @@ -95,67 +94,67 @@ issues: - path: internal\\wclayer\\ linters: - stylecheck - Text: "ST1003:" + text: "ST1003:" - path: hcn\\ linters: - stylecheck - Text: "ST1003:" + text: "ST1003:" - path: internal\\hcs\\schema1\\ linters: - stylecheck - Text: "ST1003:" + text: "ST1003:" - path: internal\\hns\\ linters: - stylecheck - Text: "ST1003:" + text: "ST1003:" - path: ext4\\internal\\compactext4\\ linters: - stylecheck - Text: "ST1003:" + text: "ST1003:" - path: ext4\\internal\\format\\ linters: - stylecheck - Text: "ST1003:" + text: "ST1003:" - path: internal\\guestrequest\\ linters: - stylecheck - Text: "ST1003:" + text: "ST1003:" - path: internal\\guest\\prot\\ linters: - stylecheck - Text: "ST1003:" + text: "ST1003:" - path: internal\\windevice\\ linters: - stylecheck - Text: "ST1003:" + text: "ST1003:" - path: internal\\winapi\\ linters: - stylecheck - Text: "ST1003:" + text: "ST1003:" - path: internal\\vmcompute\\ linters: - stylecheck - Text: "ST1003:" + text: "ST1003:" - path: internal\\regstate\\ linters: - stylecheck - Text: "ST1003:" + text: "ST1003:" - path: internal\\hcserror\\ linters: - stylecheck - Text: "ST1003:" + text: "ST1003:" # v0 APIs are deprecated, but still retained for backwards compatability - path: cmd\\ncproxy\\ @@ -171,4 +170,4 @@ issues: - path: internal\\vhdx\\info linters: - stylecheck - Text: "ST1003:" + text: "ST1003:" diff --git a/vendor/github.com/Microsoft/hcsshim/Makefile b/vendor/github.com/Microsoft/hcsshim/Makefile index de6435894..9a9f5b401 100644 --- a/vendor/github.com/Microsoft/hcsshim/Makefile +++ b/vendor/github.com/Microsoft/hcsshim/Makefile @@ -1,13 +1,20 @@ -BASE:=base.tar.gz -DEV_BUILD:=0 +include Makefile.bootfiles GO:=go GO_FLAGS:=-ldflags "-s -w" # strip Go binaries CGO_ENABLED:=0 GOMODVENDOR:= +KMOD:=0 CFLAGS:=-O2 -Wall -LDFLAGS:=-static -s # strip C binaries +LDFLAGS:=-static -s #strip C binaries +LDLIBS:= +PREPROCESSORFLAGS:= +ifeq "$(KMOD)" "1" +LDFLAGS:= -s +LDLIBS:= -lkmod +PREPROCESSORFLAGS:=-DMODULES=1 +endif GO_FLAGS_EXTRA:= ifeq "$(GOMODVENDOR)" "1" @@ -23,108 +30,14 @@ SRCROOT=$(dir $(abspath $(firstword $(MAKEFILE_LIST)))) # additional directories to search for rule prerequisites and targets VPATH=$(SRCROOT) -DELTA_TARGET=out/delta.tar.gz - -ifeq "$(DEV_BUILD)" "1" -DELTA_TARGET=out/delta-dev.tar.gz -endif - -ifeq "$(SNP_BUILD)" "1" -DELTA_TARGET=out/delta-snp.tar.gz -endif - # The link aliases for gcstools GCS_TOOLS=\ generichook \ install-drivers -# Common path prefix. -PATH_PREFIX:= -# These have PATH_PREFIX prepended to obtain the full path in recipies e.g. $(PATH_PREFIX)/$(VMGS_TOOL) -VMGS_TOOL:= -IGVM_TOOL:= -KERNEL_PATH:= - -.PHONY: all always rootfs test snp simple - -.DEFAULT_GOAL := all - -all: out/initrd.img out/rootfs.tar.gz - -clean: - find -name '*.o' -print0 | xargs -0 -r rm - rm -rf bin deps rootfs out - test: cd $(SRCROOT) && $(GO) test -v ./internal/guest/... -rootfs: out/rootfs.vhd - -snp: out/kernelinitrd.vmgs out/rootfs.hash.vhd out/rootfs.vhd out/v2056.vmgs - -simple: out/simple.vmgs snp - -%.vmgs: %.bin - rm -f $@ - # du -BM returns the size of the bin file in M, eg 7M. The sed command replaces the M with *1024*1024 and then bc does the math to convert to bytes - $(PATH_PREFIX)/$(VMGS_TOOL) create --filepath $@ --filesize `du -BM $< | sed "s/M.*/*1024*1024/" | bc` - $(PATH_PREFIX)/$(VMGS_TOOL) write --filepath $@ --datapath $< -i=8 - -# Simplest debug UVM used to test changes to the linux kernel. No dmverity protection. Boots an initramdisk rather than directly booting a vhd disk. -out/simple.bin: out/initrd.img $(PATH_PREFIX)/$(KERNEL_PATH) boot/startup_simple.sh - rm -f $@ - python3 $(PATH_PREFIX)/$(IGVM_TOOL) -o $@ -kernel $(PATH_PREFIX)/$(KERNEL_PATH) -append "8250_core.nr_uarts=0 panic=-1 debug loglevel=7 rdinit=/startup_simple.sh" -rdinit out/initrd.img -vtl 0 - -ROOTFS_DEVICE:=/dev/sda -VERITY_DEVICE:=/dev/sdb -# Debug build for use with uvmtester. UVM with dm-verity protected vhd disk mounted directly via the kernel command line. Ignores corruption in dm-verity protected disk. (Use dmesg to see if dm-verity is ignoring data corruption.) -out/v2056.bin: out/rootfs.vhd out/rootfs.hash.vhd $(PATH_PREFIX)/$(KERNEL_PATH) out/rootfs.hash.datasectors out/rootfs.hash.datablocksize out/rootfs.hash.hashblocksize out/rootfs.hash.datablocks out/rootfs.hash.rootdigest out/rootfs.hash.salt boot/startup_v2056.sh - rm -f $@ - python3 $(PATH_PREFIX)/$(IGVM_TOOL) -o $@ -kernel $(PATH_PREFIX)/$(KERNEL_PATH) -append "8250_core.nr_uarts=0 panic=-1 debug loglevel=7 root=/dev/dm-0 dm-mod.create=\"dmverity,,,ro,0 $(shell cat out/rootfs.hash.datasectors) verity 1 $(ROOTFS_DEVICE) $(VERITY_DEVICE) $(shell cat out/rootfs.hash.datablocksize) $(shell cat out/rootfs.hash.hashblocksize) $(shell cat out/rootfs.hash.datablocks) 0 sha256 $(shell cat out/rootfs.hash.rootdigest) $(shell cat out/rootfs.hash.salt) 1 ignore_corruption\" init=/startup_v2056.sh" -vtl 0 - -# Full UVM with dm-verity protected vhd disk mounted directly via the kernel command line. -out/kernelinitrd.bin: out/rootfs.vhd out/rootfs.hash.vhd out/rootfs.hash.datasectors out/rootfs.hash.datablocksize out/rootfs.hash.hashblocksize out/rootfs.hash.datablocks out/rootfs.hash.rootdigest out/rootfs.hash.salt $(PATH_PREFIX)/$(KERNEL_PATH) boot/startup.sh - rm -f $@ - python3 $(PATH_PREFIX)/$(IGVM_TOOL) -o $@ -kernel $(PATH_PREFIX)/$(KERNEL_PATH) -append "8250_core.nr_uarts=0 panic=-1 debug loglevel=7 root=/dev/dm-0 dm-mod.create=\"dmverity,,,ro,0 $(shell cat out/rootfs.hash.datasectors) verity 1 $(ROOTFS_DEVICE) $(VERITY_DEVICE) $(shell cat out/rootfs.hash.datablocksize) $(shell cat out/rootfs.hash.hashblocksize) $(shell cat out/rootfs.hash.datablocks) 0 sha256 $(shell cat out/rootfs.hash.rootdigest) $(shell cat out/rootfs.hash.salt)\" init=/startup.sh" -vtl 0 - -# Rule to make a vhd from a file. This is used to create the rootfs.hash.vhd from rootfs.hash. -%.vhd: % bin/cmd/tar2ext4 - ./bin/cmd/tar2ext4 -only-vhd -i $< -o $@ - -# Rule to make a vhd from an ext4 file. This is used to create the rootfs.vhd from rootfs.ext4. -%.vhd: %.ext4 bin/cmd/tar2ext4 - ./bin/cmd/tar2ext4 -only-vhd -i $< -o $@ - -%.hash %.hash.info %.hash.datablocks %.hash.rootdigest %hash.datablocksize %.hash.datasectors %.hash.hashblocksize: %.ext4 %.hash.salt - veritysetup format --no-superblock --salt $(shell cat out/rootfs.hash.salt) $< $*.hash > $*.hash.info - # Retrieve info required by dm-verity at boot time - # Get the blocksize of rootfs - cat $*.hash.info | awk '/^Root hash:/{ print $$3 }' > $*.hash.rootdigest - cat $*.hash.info | awk '/^Salt:/{ print $$2 }' > $*.hash.salt - cat $*.hash.info | awk '/^Data block size:/{ print $$4 }' > $*.hash.datablocksize - cat $*.hash.info | awk '/^Hash block size:/{ print $$4 }' > $*.hash.hashblocksize - cat $*.hash.info | awk '/^Data blocks:/{ print $$3 }' > $*.hash.datablocks - echo $$(( $$(cat $*.hash.datablocks) * $$(cat $*.hash.datablocksize) / 512 )) > $*.hash.datasectors - -out/rootfs.hash.salt: - hexdump -vn32 -e'8/4 "%08X" 1 "\n"' /dev/random > $@ - -out/rootfs.ext4: out/rootfs.tar.gz bin/cmd/tar2ext4 - gzip -f -d ./out/rootfs.tar.gz - ./bin/cmd/tar2ext4 -i ./out/rootfs.tar -o $@ - -out/rootfs.tar.gz: out/initrd.img - rm -rf rootfs-conv - mkdir rootfs-conv - gunzip -c out/initrd.img | (cd rootfs-conv && cpio -imd) - tar -zcf $@ -C rootfs-conv . - rm -rf rootfs-conv - -out/initrd.img: $(BASE) $(DELTA_TARGET) $(SRCROOT)/hack/catcpio.sh - $(SRCROOT)/hack/catcpio.sh "$(BASE)" $(DELTA_TARGET) > out/initrd.img.uncompressed - gzip -c out/initrd.img.uncompressed > $@ - rm out/initrd.img.uncompressed - # This target includes utilities which may be useful for testing purposes. out/delta-dev.tar.gz: out/delta.tar.gz bin/internal/tools/snp-report rm -rf rootfs-dev @@ -168,10 +81,7 @@ out/delta.tar.gz: bin/init bin/vsockexec bin/cmd/gcs bin/cmd/gcstools bin/cmd/ho tar -zcf $@ -C rootfs . rm -rf rootfs -out/containerd-shim-runhcs-v1.exe: - GOOS=windows $(GO_BUILD) -o $@ $(SRCROOT)/cmd/containerd-shim-runhcs-v1 - -bin/cmd/gcs bin/cmd/gcstools bin/cmd/hooks/wait-paths bin/cmd/tar2ext4 bin/internal/tools/snp-report bin/cmd/dmverity-vhd: +bin/cmd/gcs bin/cmd/gcstools bin/cmd/hooks/wait-paths bin/cmd/tar2ext4 bin/internal/tools/snp-report: @mkdir -p $(dir $@) GOOS=linux $(GO_BUILD) -o $@ $(SRCROOT)/$(@:bin/%=%) @@ -181,8 +91,8 @@ bin/vsockexec: vsockexec/vsockexec.o vsockexec/vsock.o bin/init: init/init.o vsockexec/vsock.o @mkdir -p bin - $(CC) $(LDFLAGS) -o $@ $^ + $(CC) $(LDFLAGS) -o $@ $^ $(LDLIBS) %.o: %.c @mkdir -p $(dir $@) - $(CC) $(CFLAGS) $(CPPFLAGS) -c -o $@ $< \ No newline at end of file + $(CC) $(PREPROCESSORFLAGS) $(CFLAGS) $(CPPFLAGS) -c -o $@ $< diff --git a/vendor/github.com/Microsoft/hcsshim/Makefile.bootfiles b/vendor/github.com/Microsoft/hcsshim/Makefile.bootfiles new file mode 100644 index 000000000..e6f06d491 --- /dev/null +++ b/vendor/github.com/Microsoft/hcsshim/Makefile.bootfiles @@ -0,0 +1,197 @@ +BASE:=base.tar.gz +DEV_BUILD:=0 + +DELTA_TARGET=out/delta.tar.gz + +ifeq "$(DEV_BUILD)" "1" +DELTA_TARGET=out/delta-dev.tar.gz +endif + +ifeq "$(SNP_BUILD)" "1" +DELTA_TARGET=out/delta-snp.tar.gz +endif + +SRCROOT=$(dir $(abspath $(firstword $(MAKEFILE_LIST)))) + +PATH_PREFIX:= +# These have PATH_PREFIX prepended to obtain the full path in recipies e.g. $(PATH_PREFIX)/$(VMGS_TOOL) +VMGS_TOOL:= +IGVM_TOOL:= +KERNEL_PATH:= +TAR2EXT4_TOOL:=bin/cmd/tar2ext4 + +ROOTFS_DEVICE:=/dev/sda +HASH_DEVICE:=/dev/sdb + +.PHONY: all always rootfs test snp simple + +.DEFAULT_GOAL := all + +all: out/initrd.img out/rootfs.tar.gz + +clean: + find -name '*.o' -print0 | xargs -0 -r rm + rm -rf bin rootfs out + +rootfs: out/rootfs.vhd + +snp: out/kernel.vmgs out/rootfs-verity.vhd out/v2056.vmgs out/v2056combined.vmgs + +simple: out/simple.vmgs snp + +%.vmgs: %.bin + rm -f $@ + # du -BM returns the size of the bin file in M, eg 7M. The sed command replaces the M with *1024*1024 and then bc does the math to convert to bytes + $(PATH_PREFIX)/$(VMGS_TOOL) create --filepath $@ --filesize `du -BM $< | sed "s/M.*/*1024*1024/" | bc` + $(PATH_PREFIX)/$(VMGS_TOOL) write --filepath $@ --datapath $< -i=8 + +# Simplest debug UVM used to test changes to the linux kernel. No dmverity protection. Boots an initramdisk rather than directly booting a vhd disk. +out/simple.bin: out/initrd.img $(PATH_PREFIX)/$(KERNEL_PATH) boot/startup_simple.sh + rm -f $@ + python3 $(PATH_PREFIX)/$(IGVM_TOOL) \ + -o $@ \ + -kernel $(PATH_PREFIX)/$(KERNEL_PATH) \ + -append "8250_core.nr_uarts=0 panic=-1 debug loglevel=7 rdinit=/startup_simple.sh" \ + -rdinit out/initrd.img \ + -vtl 0 + +# The boot performance is optimized by supplying rootfs as a SCSI attachment. In this case the kernel boots with +# dm-verity to ensure the integrity. Similar to layer VHDs the verity Merkle tree is appended to ext4 filesystem. +# It transpires that the /dev/sd* order is not deterministic wrt the scsi device order. Thus build a single userland +# fs + merkle tree device and boot that. +# +# From https://www.kernel.org/doc/html/latest/admin-guide/device-mapper/dm-init.html +# +# dm-mod.create=,,,,[,
+][;,,,,
[,
+]+] +# +# where: +# ::= The device name. +# ::= xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx | "" +# ::= The device minor number | "" +# ::= "ro" | "rw" +#
::= +# ::= "verity" | "linear" | ... (see list below) +# +# From https://docs.kernel.org/admin-guide/device-mapper/verity.html +# +# +# +# +# [<#opt_params> ] +# +# typical igvm tool line once all the macros are expanded +# python3 /home/user/igvmfile.py -o out/v2056.bin -kernel /hose/user/bzImage -append "8250_core.nr_uarts=0 panic=-1 debug loglevel=9 ignore_loglevel dev.scsi.logging_level=9411 root=/dev/dm-0 dm-mod.create=\"dmverity,,,ro,0 196744 verity 1 /dev/sda /dev/sdb 4096 4096 24593 0 sha256 6d625a306aafdf73125a84388b7bfdd2c3a154bd8d698955f4adffc736bdfd66 b9065c23231f0d8901cc3a68e1d3b8d624213e76d6f9f6d3ccbcb829f9c710ba 1 ignore_corruption\" init=/startup_v2056.sh" -vtl 0 +# +# so a kernel command line of: +# 8250_core.nr_uarts=0 panic=-1 debug loglevel=9 ignore_loglevel dev.scsi.logging_level=9411 root=/dev/dm-0 dm-mod.create=\"dmverity,,,ro,0 196744 verity 1 /dev/sda /dev/sdb 4096 4096 24593 0 sha256 6d625a306aafdf73125a84388b7bfdd2c3a154bd8d698955f4adffc736bdfd66 b9065c23231f0d8901cc3a68e1d3b8d624213e76d6f9f6d3ccbcb829f9c710ba 1 ignore_corruption\" init=/startup_v2056.sh +# +# and a dm-mod.create of: +# dmverity,,,ro,0 196744 verity 1 /dev/sda /dev/sdb 4096 4096 24593 0 sha256 6d625a306aafdf73125a84388b7bfdd2c3a154bd8d698955f4adffc736bdfd66 b9065c23231f0d8901cc3a68e1d3b8d624213e76d6f9f6d3ccbcb829f9c710ba 1 ignore_corruption +# +# which breaks down to: +# +# name = "dmverity" +# uuid = "" +# minor = "" +# flags = "ro" +# table = 0 196744 verity "args" +# start_sector = 0 +# num_sectors = 196744 +# target_type = verity +# target_args = 1 /dev/sda /dev/sdb 4096 4096 24593 0 sha256 6d625a306aafdf73125a84388b7bfdd2c3a154bd8d698955f4adffc736bdfd66 b9065c23231f0d8901cc3a68e1d3b8d624213e76d6f9f6d3ccbcb829f9c710ba 1 ignore_corruption +# args: +# version 1 +# dev /dev/sda +# hash_dev /dev/sdb +# data_block_size 4096 +# hash_block_size 4096 +# num_data_blocks 24593 +# hash_start_block 0 +# algorithm sha256 +# digest 6d625a306aafdf73125a84388b7bfdd2c3a154bd8d698955f4adffc736bdfd66 +# salt b9065c23231f0d8901cc3a68e1d3b8d624213e76d6f9f6d3ccbcb829f9c710ba +# opt_params +# count = 1 +# ignore_corruption +# +# combined typical (not bigger count of sectors for the whole device) +# dmverity,,,ro,0 199672 verity 1 /dev/sda /dev/sda 4096 4096 24959 24959 sha256 4aa6e79866ee946ddbd9cddd6554bc6449272942fcc65934326817785a3bd374 adc4956274489c936395bab046a2d476f21ef436e571ba53da2fdf3aee59bf0a +# +# A few notes: +# - num_sectors is the size of the final (aka target) verity device, i.e. the size of our rootfs excluding the Merkle +# tree. +# - We don't add verity superblock, so the will be exactly at the end of ext4 filesystem and equal +# to its size. In the case when verity superblock is present an extra block should be added to the offset value, +# i.e. 24959 becomes 24960. + + +# Debug build for use with uvmtester. UVM with dm-verity protected vhd disk mounted directly via the kernel command line. +# Ignores corruption in dm-verity protected disk. (Use dmesg to see if dm-verity is ignoring data corruption.) +out/v2056.bin: out/rootfs.vhd out/rootfs.hash.vhd $(PATH_PREFIX)/$(KERNEL_PATH) out/rootfs.hash.datasectors out/rootfs.hash.datablocksize out/rootfs.hash.hashblocksize out/rootfs.hash.datablocks out/rootfs.hash.rootdigest out/rootfs.hash.salt boot/startup_v2056.sh + rm -f $@ + python3 $(PATH_PREFIX)/$(IGVM_TOOL) \ + -o $@ \ + -kernel $(PATH_PREFIX)/$(KERNEL_PATH) \ + -append "8250_core.nr_uarts=0 panic=-1 debug loglevel=9 root=/dev/dm-0 dm-mod.create=\"dmverity,,,ro,0 $(shell cat out/rootfs.hash.datasectors) verity 1 $(ROOTFS_DEVICE) $(HASH_DEVICE) $(shell cat out/rootfs.hash.datablocksize) $(shell cat out/rootfs.hash.hashblocksize) $(shell cat out/rootfs.hash.datablocks) $(shell cat out/rootfs.hash.datablocks) sha256 $(shell cat out/rootfs.hash.rootdigest) $(shell cat out/rootfs.hash.salt) 1 ignore_corruption\" init=/startup_v2056.sh" \ + -vtl 0 + +out/v2056combined.bin: out/rootfs-verity.vhd $(PATH_PREFIX)/$(KERNEL_PATH) out/rootfs.hash.datablocksize out/rootfs.hash.hashblocksize out/rootfs.hash.datablocks out/rootfs.hash.rootdigest out/rootfs.hash.salt boot/startup_v2056.sh + rm -f $@ + echo root=/dev/dm-0 dm-mod.create=\"dmverity,,,ro,0 $(shell cat out/rootfs.hash.datasectors) verity 1 $(ROOTFS_DEVICE) $(ROOTFS_DEVICE) $(shell cat out/rootfs.hash.datablocksize) $(shell cat out/rootfs.hash.hashblocksize) $(shell cat out/rootfs.hash.datablocks) $(shell cat out/rootfs.hash.datablocks) sha256 $(shell cat out/rootfs.hash.rootdigest) $(shell cat out/rootfs.hash.salt) 1 ignore_corruption\" + python3 $(PATH_PREFIX)/$(IGVM_TOOL) \ + -o $@ \ + -kernel $(PATH_PREFIX)/$(KERNEL_PATH) \ + -append "8250_core.nr_uarts=0 panic=-1 debug loglevel=9 ignore_loglevel dev.scsi.logging_level=9411 root=/dev/dm-0 dm-mod.create=\"dmverity,,,ro,0 $(shell cat out/rootfs.hash.datasectors) verity 1 $(ROOTFS_DEVICE) $(ROOTFS_DEVICE) $(shell cat out/rootfs.hash.datablocksize) $(shell cat out/rootfs.hash.hashblocksize) $(shell cat out/rootfs.hash.datablocks) $(shell cat out/rootfs.hash.datablocks) sha256 $(shell cat out/rootfs.hash.rootdigest) $(shell cat out/rootfs.hash.salt) 1 ignore_corruption\" init=/startup_v2056.sh" \ + -vtl 0 + +# Full UVM with dm-verity protected vhd disk mounted directly via the kernel command line. +out/kernel.bin: out/rootfs-verity.vhd $(PATH_PREFIX)/$(KERNEL_PATH) out/rootfs.hash.datasectors out/rootfs.hash.datablocksize out/rootfs.hash.hashblocksize out/rootfs.hash.datablocks out/rootfs.hash.rootdigest out/rootfs.hash.salt boot/startup.sh + rm -f $@ + echo root=/dev/dm-0 dm-mod.create=\"dmverity,,,ro,0 $(shell cat out/rootfs.hash.datasectors) verity 1 $(ROOTFS_DEVICE) $(ROOTFS_DEVICE) $(shell cat out/rootfs.hash.datablocksize) $(shell cat out/rootfs.hash.hashblocksize) $(shell cat out/rootfs.hash.datablocks) $(shell cat out/rootfs.hash.datablocks) sha256 $(shell cat out/rootfs.hash.rootdigest) $(shell cat out/rootfs.hash.salt)\" + python3 $(PATH_PREFIX)/$(IGVM_TOOL) \ + -o $@ \ + -kernel $(PATH_PREFIX)/$(KERNEL_PATH) \ + -append "8250_core.nr_uarts=0 panic=-1 debug loglevel=7 root=/dev/dm-0 dm-mod.create=\"dmverity,,,ro,0 $(shell cat out/rootfs.hash.datasectors) verity 1 $(ROOTFS_DEVICE) $(ROOTFS_DEVICE) $(shell cat out/rootfs.hash.datablocksize) $(shell cat out/rootfs.hash.hashblocksize) $(shell cat out/rootfs.hash.datablocks) $(shell cat out/rootfs.hash.datablocks) sha256 $(shell cat out/rootfs.hash.rootdigest) $(shell cat out/rootfs.hash.salt)\" init=/startup.sh" \ + -vtl 0 + +# Rule to make a vhd from a file. This is used to create the rootfs.hash.vhd from rootfs.hash. +%.vhd: % $(TAR2EXT4_TOOL) + $(TAR2EXT4_TOOL) -only-vhd -i $< -o $@ + +# Rule to make a vhd from an ext4 file. This is used to create the rootfs.vhd from rootfs.ext4. +%.vhd: %.ext4 $(TAR2EXT4_TOOL) + $(TAR2EXT4_TOOL) -only-vhd -i $< -o $@ + +%.hash %.hash.info %.hash.datablocks %.hash.rootdigest %hash.datablocksize %.hash.datasectors %.hash.hashblocksize: %.ext4 %.hash.salt + veritysetup format --no-superblock --salt $(shell cat out/rootfs.hash.salt) $< $*.hash > $*.hash.info + # Retrieve info required by dm-verity at boot time + # Get the blocksize of rootfs + cat $*.hash.info | awk '/^Root hash:/{ print $$3 }' > $*.hash.rootdigest + cat $*.hash.info | awk '/^Salt:/{ print $$2 }' > $*.hash.salt + cat $*.hash.info | awk '/^Data block size:/{ print $$4 }' > $*.hash.datablocksize + cat $*.hash.info | awk '/^Hash block size:/{ print $$4 }' > $*.hash.hashblocksize + cat $*.hash.info | awk '/^Data blocks:/{ print $$3 }' > $*.hash.datablocks + echo $$(( $$(cat $*.hash.datablocks) * $$(cat $*.hash.datablocksize) / 512 )) > $*.hash.datasectors + +out/rootfs.hash.salt: + hexdump -vn32 -e'8/4 "%08X" 1 "\n"' /dev/random > $@ + +out/rootfs.ext4: out/rootfs.tar.gz $(TAR2EXT4_TOOL) + gzip -f -d ./out/rootfs.tar.gz + $(TAR2EXT4_TOOL) -i ./out/rootfs.tar -o $@ + +out/rootfs-verity.ext4: out/rootfs.ext4 out/rootfs.hash + cp out/rootfs.ext4 $@ + cat out/rootfs.hash >> $@ + +out/rootfs.tar.gz: out/initrd.img + rm -rf rootfs-conv + mkdir rootfs-conv + gunzip -c out/initrd.img | (cd rootfs-conv && cpio -imd) + tar -zcf $@ -C rootfs-conv . + rm -rf rootfs-conv + +out/initrd.img: $(BASE) $(DELTA_TARGET) $(SRCROOT)/hack/catcpio.sh + $(SRCROOT)/hack/catcpio.sh "$(BASE)" $(DELTA_TARGET) > out/initrd.img.uncompressed + gzip -c out/initrd.img.uncompressed > $@ + rm out/initrd.img.uncompressed diff --git a/vendor/github.com/Microsoft/hcsshim/README.md b/vendor/github.com/Microsoft/hcsshim/README.md index 320438048..ae6668263 100644 --- a/vendor/github.com/Microsoft/hcsshim/README.md +++ b/vendor/github.com/Microsoft/hcsshim/README.md @@ -44,7 +44,7 @@ delta.tar.gz initrd.img rootfs.tar.gz ### Containerd Shim -For info on the [Runtime V2 API](https://github.com/containerd/containerd/blob/master/runtime/v2/README.md). +For info on the [Runtime V2 API](https://github.com/containerd/containerd/blob/main/core/runtime/v2/README.md). Contrary to the typical Linux architecture of shim -> runc, the runhcs shim is used both to launch and manage the lifetime of containers. diff --git a/vendor/github.com/Microsoft/hcsshim/internal/hcs/process.go b/vendor/github.com/Microsoft/hcsshim/internal/hcs/process.go index 8ef611d6a..fef2bf546 100644 --- a/vendor/github.com/Microsoft/hcsshim/internal/hcs/process.go +++ b/vendor/github.com/Microsoft/hcsshim/internal/hcs/process.go @@ -63,10 +63,10 @@ func (process *Process) SystemID() string { } func (process *Process) processSignalResult(ctx context.Context, err error) (bool, error) { - switch err { //nolint:errorlint - case nil: + if err == nil { return true, nil - case ErrVmcomputeOperationInvalidState, ErrComputeSystemDoesNotExist, ErrElementNotFound: + } + if errors.Is(err, ErrVmcomputeOperationInvalidState) || errors.Is(err, ErrComputeSystemDoesNotExist) || errors.Is(err, ErrElementNotFound) { if !process.stopped() { // The process should be gone, but we have not received the notification. // After a second, force unblock the process wait to work around a possible @@ -82,9 +82,8 @@ func (process *Process) processSignalResult(ctx context.Context, err error) (boo }() } return false, nil - default: - return false, err } + return false, nil } // Signal signals the process with `options`. diff --git a/vendor/github.com/Microsoft/hcsshim/internal/hcs/schema2/chipset.go b/vendor/github.com/Microsoft/hcsshim/internal/hcs/schema2/chipset.go index ca75277a3..93857da69 100644 --- a/vendor/github.com/Microsoft/hcsshim/internal/hcs/schema2/chipset.go +++ b/vendor/github.com/Microsoft/hcsshim/internal/hcs/schema2/chipset.go @@ -24,4 +24,6 @@ type Chipset struct { // LinuxKernelDirect - Added in v2.2 Builds >=181117 LinuxKernelDirect *LinuxKernelDirect `json:"LinuxKernelDirect,omitempty"` + + FirmwareFile *FirmwareFile `json:"FirmwareFile,omitempty"` } diff --git a/vendor/github.com/Microsoft/hcsshim/internal/hcs/schema2/cim_mount.go b/vendor/github.com/Microsoft/hcsshim/internal/hcs/schema2/cimfs.go similarity index 70% rename from vendor/github.com/Microsoft/hcsshim/internal/hcs/schema2/cim_mount.go rename to vendor/github.com/Microsoft/hcsshim/internal/hcs/schema2/cimfs.go index 81865e7ea..52fb62a82 100644 --- a/vendor/github.com/Microsoft/hcsshim/internal/hcs/schema2/cim_mount.go +++ b/vendor/github.com/Microsoft/hcsshim/internal/hcs/schema2/cimfs.go @@ -9,14 +9,6 @@ package hcsschema -const ( - CimMountFlagNone uint32 = 0x0 - CimMountFlagChildOnly uint32 = 0x1 - CimMountFlagEnableDax uint32 = 0x2 - CimMountFlagCacheFiles uint32 = 0x4 - CimMountFlagCacheRegions uint32 = 0x8 -) - type CimMount struct { ImagePath string `json:"ImagePath,omitempty"` FileSystemName string `json:"FileSystemName,omitempty"` diff --git a/vendor/github.com/Microsoft/hcsshim/internal/hcs/schema2/firmware.go b/vendor/github.com/Microsoft/hcsshim/internal/hcs/schema2/firmware.go new file mode 100644 index 000000000..c27a13200 --- /dev/null +++ b/vendor/github.com/Microsoft/hcsshim/internal/hcs/schema2/firmware.go @@ -0,0 +1,8 @@ +package hcsschema + +type FirmwareFile struct { + // Parameters is an experimental/pre-release field. The field itself or its + // behavior can change in future iterations of the schema. Avoid taking a hard + // dependency on this field. + Parameters []byte `json:"Parameters,omitempty"` +} diff --git a/vendor/github.com/Microsoft/hcsshim/internal/hcs/schema2/memory_2.go b/vendor/github.com/Microsoft/hcsshim/internal/hcs/schema2/memory_2.go deleted file mode 100644 index 71224c75b..000000000 --- a/vendor/github.com/Microsoft/hcsshim/internal/hcs/schema2/memory_2.go +++ /dev/null @@ -1,49 +0,0 @@ -/* - * HCS API - * - * No description provided (generated by Swagger Codegen https://github.com/swagger-api/swagger-codegen) - * - * API version: 2.1 - * Generated by: Swagger Codegen (https://github.com/swagger-api/swagger-codegen.git) - */ - -package hcsschema - -type Memory2 struct { - SizeInMB uint64 `json:"SizeInMB,omitempty"` - - AllowOvercommit bool `json:"AllowOvercommit,omitempty"` - - EnableHotHint bool `json:"EnableHotHint,omitempty"` - - EnableColdHint bool `json:"EnableColdHint,omitempty"` - - EnableEpf bool `json:"EnableEpf,omitempty"` - - // EnableDeferredCommit is private in the schema. If regenerated need to add back. - EnableDeferredCommit bool `json:"EnableDeferredCommit,omitempty"` - - // EnableColdDiscardHint if enabled, then the memory cold discard hint feature is exposed - // to the VM, allowing it to trim non-zeroed pages from the working set (if supported by - // the guest operating system). - EnableColdDiscardHint bool `json:"EnableColdDiscardHint,omitempty"` - - // LowMmioGapInMB is the low MMIO region allocated below 4GB. - // - // TODO: This is pre-release support in schema 2.3. Need to add build number - // docs when a public build with this is out. - LowMMIOGapInMB uint64 `json:"LowMmioGapInMB,omitempty"` - - // HighMmioBaseInMB is the high MMIO region allocated above 4GB (base and - // size). - // - // TODO: This is pre-release support in schema 2.3. Need to add build number - // docs when a public build with this is out. - HighMMIOBaseInMB uint64 `json:"HighMmioBaseInMB,omitempty"` - - // HighMmioGapInMB is the high MMIO region. - // - // TODO: This is pre-release support in schema 2.3. Need to add build number - // docs when a public build with this is out. - HighMMIOGapInMB uint64 `json:"HighMmioGapInMB,omitempty"` -} diff --git a/vendor/github.com/Microsoft/hcsshim/internal/hcs/schema2/memory_backing_type.go b/vendor/github.com/Microsoft/hcsshim/internal/hcs/schema2/memory_backing_type.go new file mode 100644 index 000000000..41837416c --- /dev/null +++ b/vendor/github.com/Microsoft/hcsshim/internal/hcs/schema2/memory_backing_type.go @@ -0,0 +1,21 @@ +// Autogenerated code; DO NOT EDIT. + +/* + * Schema Open API + * + * No description provided (generated by Swagger Codegen https://github.com/swaggerapi/swaggercodegen) + * + * API version: 2.4 + * Generated by: Swagger Codegen (https://github.com/swaggerapi/swaggercodegen.git) + */ + +package hcsschema + +type MemoryBackingType string + +// List of MemoryBackingType +const ( + MemoryBackingType_PHYSICAL MemoryBackingType = "Physical" + MemoryBackingType_VIRTUAL MemoryBackingType = "Virtual" + MemoryBackingType_HYBRID MemoryBackingType = "Hybrid" +) diff --git a/vendor/github.com/Microsoft/hcsshim/internal/hcs/schema2/numa.go b/vendor/github.com/Microsoft/hcsshim/internal/hcs/schema2/numa.go new file mode 100644 index 000000000..70a139519 --- /dev/null +++ b/vendor/github.com/Microsoft/hcsshim/internal/hcs/schema2/numa.go @@ -0,0 +1,19 @@ +// Autogenerated code; DO NOT EDIT. + +/* + * Schema Open API + * + * No description provided (generated by Swagger Codegen https://github.com/swagger-api/swagger-codegen) + * + * API version: 2.4 + * Generated by: Swagger Codegen (https://github.com/swagger-api/swagger-codegen.git) + */ + +package hcsschema + +type Numa struct { + VirtualNodeCount uint8 `json:"VirtualNodeCount,omitempty"` + PreferredPhysicalNodes []int64 `json:"PreferredPhysicalNodes,omitempty"` + Settings []NumaSetting `json:"Settings,omitempty"` + MaxSizePerNode uint64 `json:"MaxSizePerNode,omitempty"` +} diff --git a/vendor/github.com/Microsoft/hcsshim/internal/hcs/schema2/numa_node.go b/vendor/github.com/Microsoft/hcsshim/internal/hcs/schema2/numa_node.go new file mode 100644 index 000000000..5984bdecd --- /dev/null +++ b/vendor/github.com/Microsoft/hcsshim/internal/hcs/schema2/numa_node.go @@ -0,0 +1,17 @@ +// Autogenerated code; DO NOT EDIT. + +/* + * Schema Open API + * + * No description provided (generated by Swagger Codegen https://github.com/swagger-api/swagger-codegen) + * + * API version: 2.4 + * Generated by: Swagger Codegen (https://github.com/swagger-api/swagger-codegen.git) + */ + +package hcsschema + +type NumaNode struct { + VirtualNodeIndex uint32 `json:"VirtualNodeIndex,omitempty"` + PhysicalNodeIndex uint32 `json:"PhysicalNodeIndex,omitempty"` +} diff --git a/vendor/github.com/Microsoft/hcsshim/internal/hcs/schema2/numa_node_memory.go b/vendor/github.com/Microsoft/hcsshim/internal/hcs/schema2/numa_node_memory.go new file mode 100644 index 000000000..88567f0f6 --- /dev/null +++ b/vendor/github.com/Microsoft/hcsshim/internal/hcs/schema2/numa_node_memory.go @@ -0,0 +1,19 @@ +// Autogenerated code; DO NOT EDIT. + +/* + * Schema Open API + * + * No description provided (generated by Swagger Codegen https://github.com/swagger-api/swagger-codegen) + * + * API version: 2.4 + * Generated by: Swagger Codegen (https://github.com/swagger-api/swagger-codegen.git) + */ + +package hcsschema + +type NumaNodeMemory struct { + // Total physical memory on on this physical NUMA node that is consumable by the VMs. + TotalConsumableMemoryInPages uint64 `json:"TotalConsumableMemoryInPages,omitempty"` + // Currently available physical memory on this physical NUMA node for the VMs. + AvailableMemoryInPages uint64 `json:"AvailableMemoryInPages,omitempty"` +} diff --git a/vendor/github.com/Microsoft/hcsshim/internal/hcs/schema2/numa_node_processor.go b/vendor/github.com/Microsoft/hcsshim/internal/hcs/schema2/numa_node_processor.go new file mode 100644 index 000000000..4b6795bb9 --- /dev/null +++ b/vendor/github.com/Microsoft/hcsshim/internal/hcs/schema2/numa_node_processor.go @@ -0,0 +1,17 @@ +// Autogenerated code; DO NOT EDIT. + +/* + * Schema Open API + * + * No description provided (generated by Swagger Codegen https://github.com/swagger-api/swagger-codegen) + * + * API version: 2.4 + * Generated by: Swagger Codegen (https://github.com/swagger-api/swagger-codegen.git) + */ + +package hcsschema + +type NumaNodeProcessor struct { + TotalAssignedProcessors uint32 `json:"TotalAssignedProcessors,omitempty"` + TotalAvailableProcessors uint32 `json:"TotalAvailableProcessors,omitempty"` +} diff --git a/vendor/github.com/Microsoft/hcsshim/internal/hcs/schema2/numa_processors.go b/vendor/github.com/Microsoft/hcsshim/internal/hcs/schema2/numa_processors.go new file mode 100644 index 000000000..bc3fba37a --- /dev/null +++ b/vendor/github.com/Microsoft/hcsshim/internal/hcs/schema2/numa_processors.go @@ -0,0 +1,21 @@ +// Autogenerated code; DO NOT EDIT. + +/* + * Schema Open API + * + * No description provided (generated by Swagger Codegen https://github.com/swagger-api/swagger-codegen) + * + * API version: 2.4 + * Generated by: Swagger Codegen (https://github.com/swagger-api/swagger-codegen.git) + */ + +package hcsschema + +type NumaProcessors struct { + CountPerNode Range `json:"count_per_node,omitempty"` + NodePerSocket uint32 `json:"node_per_socket,omitempty"` +} + +type Range struct { + Max uint32 `json:"max,omitempty"` +} diff --git a/vendor/github.com/Microsoft/hcsshim/internal/hcs/schema2/numa_setting.go b/vendor/github.com/Microsoft/hcsshim/internal/hcs/schema2/numa_setting.go new file mode 100644 index 000000000..3f27b2ca0 --- /dev/null +++ b/vendor/github.com/Microsoft/hcsshim/internal/hcs/schema2/numa_setting.go @@ -0,0 +1,21 @@ +// Autogenerated code; DO NOT EDIT. + +/* + * Schema Open API + * + * No description provided (generated by Swagger Codegen https://github.com/swagger-api/swagger-codegen) + * + * API version: 2.4 + * Generated by: Swagger Codegen (https://github.com/swagger-api/swagger-codegen.git) + */ + +package hcsschema + +type NumaSetting struct { + VirtualNodeNumber uint32 `json:"VirtualNodeNumber,omitempty"` + PhysicalNodeNumber uint32 `json:"PhysicalNodeNumber,omitempty"` + VirtualSocketNumber uint32 `json:"VirtualSocketNumber,omitempty"` + CountOfProcessors uint32 `json:"CountOfProcessors,omitempty"` + CountOfMemoryBlocks uint64 `json:"CountOfMemoryBlocks,omitempty"` + MemoryBackingType MemoryBackingType `json:"MemoryBackingType,omitempty"` +} diff --git a/vendor/github.com/Microsoft/hcsshim/internal/hcs/schema2/processor_2.go b/vendor/github.com/Microsoft/hcsshim/internal/hcs/schema2/processor_2.go deleted file mode 100644 index c64f335ec..000000000 --- a/vendor/github.com/Microsoft/hcsshim/internal/hcs/schema2/processor_2.go +++ /dev/null @@ -1,23 +0,0 @@ -/* - * HCS API - * - * No description provided (generated by Swagger Codegen https://github.com/swagger-api/swagger-codegen) - * - * API version: 2.5 - * Generated by: Swagger Codegen (https://github.com/swagger-api/swagger-codegen.git) - */ - -package hcsschema - -type Processor2 struct { - Count int32 `json:"Count,omitempty"` - - Limit int32 `json:"Limit,omitempty"` - - Weight int32 `json:"Weight,omitempty"` - - ExposeVirtualizationExtensions bool `json:"ExposeVirtualizationExtensions,omitempty"` - - // An optional object that configures the CPU Group to which a Virtual Machine is going to bind to. - CpuGroup *CpuGroup `json:"CpuGroup,omitempty"` -} diff --git a/vendor/github.com/Microsoft/hcsshim/internal/hcs/schema2/properties.go b/vendor/github.com/Microsoft/hcsshim/internal/hcs/schema2/properties.go index 0c7efe8d4..d4cb95bdd 100644 --- a/vendor/github.com/Microsoft/hcsshim/internal/hcs/schema2/properties.go +++ b/vendor/github.com/Microsoft/hcsshim/internal/hcs/schema2/properties.go @@ -26,6 +26,8 @@ type Properties struct { RuntimeId string `json:"RuntimeId,omitempty"` + SystemGUID string `json:"SystemGUID,omitempty"` + RuntimeTemplateId string `json:"RuntimeTemplateId,omitempty"` State string `json:"State,omitempty"` diff --git a/vendor/github.com/Microsoft/hcsshim/internal/hcs/schema2/property_type.go b/vendor/github.com/Microsoft/hcsshim/internal/hcs/schema2/property_type.go index 98f2c96ed..934f777fc 100644 --- a/vendor/github.com/Microsoft/hcsshim/internal/hcs/schema2/property_type.go +++ b/vendor/github.com/Microsoft/hcsshim/internal/hcs/schema2/property_type.go @@ -23,4 +23,5 @@ const ( PTICHeartbeatStatus PropertyType = "ICHeartbeatStatus" PTProcessorTopology PropertyType = "ProcessorTopology" PTCPUGroup PropertyType = "CpuGroup" + PTSystemGUID PropertyType = "SystemGUID" ) diff --git a/vendor/github.com/Microsoft/hcsshim/internal/hcs/schema2/topology.go b/vendor/github.com/Microsoft/hcsshim/internal/hcs/schema2/topology.go index 834869940..9cca85171 100644 --- a/vendor/github.com/Microsoft/hcsshim/internal/hcs/schema2/topology.go +++ b/vendor/github.com/Microsoft/hcsshim/internal/hcs/schema2/topology.go @@ -1,16 +1,18 @@ +// Autogenerated code; DO NOT EDIT. + /* - * HCS API + * Schema Open API * * No description provided (generated by Swagger Codegen https://github.com/swagger-api/swagger-codegen) * - * API version: 2.1 + * API version: 2.4 * Generated by: Swagger Codegen (https://github.com/swagger-api/swagger-codegen.git) */ package hcsschema type Topology struct { - Memory *Memory2 `json:"Memory,omitempty"` - - Processor *Processor2 `json:"Processor,omitempty"` + Memory *VirtualMachineMemory `json:"Memory,omitempty"` + Processor *VirtualMachineProcessor `json:"Processor,omitempty"` + Numa *Numa `json:"Numa,omitempty"` } diff --git a/vendor/github.com/Microsoft/hcsshim/internal/hcs/schema2/virtual_machine.go b/vendor/github.com/Microsoft/hcsshim/internal/hcs/schema2/virtual_machine.go index 1e0fab289..3f750466f 100644 --- a/vendor/github.com/Microsoft/hcsshim/internal/hcs/schema2/virtual_machine.go +++ b/vendor/github.com/Microsoft/hcsshim/internal/hcs/schema2/virtual_machine.go @@ -1,36 +1,29 @@ +// Autogenerated code; DO NOT EDIT. + /* - * HCS API + * Schema Open API * * No description provided (generated by Swagger Codegen https://github.com/swagger-api/swagger-codegen) * - * API version: 2.1 + * API version: 2.4 * Generated by: Swagger Codegen (https://github.com/swagger-api/swagger-codegen.git) */ package hcsschema +// Configuration of a virtual machine, used during its creation to set up and/or use resources. type VirtualMachine struct { - - // StopOnReset is private in the schema. If regenerated need to put back. - StopOnReset bool `json:"StopOnReset,omitempty"` - - Chipset *Chipset `json:"Chipset,omitempty"` - - ComputeTopology *Topology `json:"ComputeTopology,omitempty"` - - Devices *Devices `json:"Devices,omitempty"` - - GuestState *GuestState `json:"GuestState,omitempty"` - - RestoreState *RestoreState `json:"RestoreState,omitempty"` - + Version *Version `json:"Version,omitempty"` + // When set to true, the virtual machine will treat a reset as a stop, releasing resources and cleaning up state. + StopOnReset bool `json:"StopOnReset,omitempty"` + Chipset *Chipset `json:"Chipset,omitempty"` + ComputeTopology *Topology `json:"ComputeTopology,omitempty"` + Devices *Devices `json:"Devices,omitempty"` + GuestState *GuestState `json:"GuestState,omitempty"` + RestoreState *RestoreState `json:"RestoreState,omitempty"` RegistryChanges *RegistryChanges `json:"RegistryChanges,omitempty"` - - StorageQoS *StorageQoS `json:"StorageQoS,omitempty"` - + StorageQoS *StorageQoS `json:"StorageQoS,omitempty"` + DebugOptions *DebugOptions `json:"DebugOptions,omitempty"` GuestConnection *GuestConnection `json:"GuestConnection,omitempty"` - - SecuritySettings *SecuritySettings `json:"SecuritySettings,omitempty"` - - DebugOptions *DebugOptions `json:"DebugOptions,omitempty"` + SecuritySettings *SecuritySettings `json:"SecuritySettings,omitempty"` } diff --git a/vendor/github.com/Microsoft/hcsshim/internal/hcs/schema2/virtual_machine_memory.go b/vendor/github.com/Microsoft/hcsshim/internal/hcs/schema2/virtual_machine_memory.go new file mode 100644 index 000000000..17573c92a --- /dev/null +++ b/vendor/github.com/Microsoft/hcsshim/internal/hcs/schema2/virtual_machine_memory.go @@ -0,0 +1,33 @@ +// Autogenerated code; DO NOT EDIT. + +/* + * Schema Open API + * + * No description provided (generated by Swagger Codegen https://github.com/swagger-api/swagger-codegen) + * + * API version: 2.4 + * Generated by: Swagger Codegen (https://github.com/swagger-api/swagger-codegen.git) + */ + +package hcsschema + +type VirtualMachineMemory struct { + SizeInMB uint64 `json:"SizeInMB,omitempty"` + Backing *MemoryBackingType `json:"Backing,omitempty"` + // If enabled, then the VM's memory is backed by the Windows pagefile rather than physically backed, statically allocated memory. + AllowOvercommit bool `json:"AllowOvercommit,omitempty"` + // If enabled, then the memory hot hint feature is exposed to the VM, allowing it to prefetch pages into its working set. (if supported by the guest operating system). + EnableHotHint bool `json:"EnableHotHint,omitempty"` + // If enabled, then the memory cold hint feature is exposed to the VM, allowing it to trim zeroed pages from its working set (if supported by the guest operating system). + EnableColdHint bool `json:"EnableColdHint,omitempty"` + // If enabled, then the memory cold discard hint feature is exposed to the VM, allowing it to trim non-zeroed pages from the working set (if supported by the guest operating system). + EnableColdDiscardHint bool `json:"EnableColdDiscardHint,omitempty"` + // If enabled, then commit is not charged for each backing page until first access. + EnableDeferredCommit bool `json:"EnableDeferredCommit,omitempty"` + // Low MMIO region allocated below 4GB + LowMMIOGapInMB uint64 `json:"LowMmioGapInMB,omitempty"` + // High MMIO region allocated above 4GB (base and size) + HighMMIOBaseInMB uint64 `json:"HighMmioBaseInMB,omitempty"` + HighMMIOGapInMB uint64 `json:"HighMmioGapInMB,omitempty"` + SlitType *VirtualSlitType `json:"SlitType,omitempty"` +} diff --git a/vendor/github.com/Microsoft/hcsshim/internal/hcs/schema2/virtual_machine_processor.go b/vendor/github.com/Microsoft/hcsshim/internal/hcs/schema2/virtual_machine_processor.go new file mode 100644 index 000000000..619cd8340 --- /dev/null +++ b/vendor/github.com/Microsoft/hcsshim/internal/hcs/schema2/virtual_machine_processor.go @@ -0,0 +1,21 @@ +// Autogenerated code; DO NOT EDIT. + +/* + * Schema Open API + * + * No description provided (generated by Swagger Codegen https://github.com/swagger-api/swagger-codegen) + * + * API version: 2.4 + * Generated by: Swagger Codegen (https://github.com/swagger-api/swagger-codegen.git) + */ + +package hcsschema + +type VirtualMachineProcessor struct { + Count uint32 `json:"Count,omitempty"` + Limit uint64 `json:"Limit,omitempty"` + Weight uint64 `json:"Weight,omitempty"` + Reservation uint64 `json:"Reservation,omitempty"` + CpuGroup *CpuGroup `json:"CpuGroup,omitempty"` + NumaProcessorsSettings *NumaProcessors `json:"NumaProcessorsSettings,omitempty"` +} diff --git a/vendor/github.com/Microsoft/hcsshim/internal/hcs/schema2/virtual_pci_device.go b/vendor/github.com/Microsoft/hcsshim/internal/hcs/schema2/virtual_pci_device.go index f5e05903c..a4a62da16 100644 --- a/vendor/github.com/Microsoft/hcsshim/internal/hcs/schema2/virtual_pci_device.go +++ b/vendor/github.com/Microsoft/hcsshim/internal/hcs/schema2/virtual_pci_device.go @@ -9,8 +9,9 @@ package hcsschema -// TODO: This is pre-release support in schema 2.3. Need to add build number +// TODO: PropagateNumaAffinity is pre-release/experimental field in schema 2.11. Need to add build number // docs when a public build with this is out. type VirtualPciDevice struct { Functions []VirtualPciFunction `json:",omitempty"` + PropagateNumaAffinity *bool `json:"PropagateNumaAffinity,omitempty"` } diff --git a/vendor/github.com/Microsoft/hcsshim/internal/hcs/schema2/virtual_slit_type.go b/vendor/github.com/Microsoft/hcsshim/internal/hcs/schema2/virtual_slit_type.go new file mode 100644 index 000000000..dfad62313 --- /dev/null +++ b/vendor/github.com/Microsoft/hcsshim/internal/hcs/schema2/virtual_slit_type.go @@ -0,0 +1,23 @@ +// Autogenerated code; DO NOT EDIT. + +/* + * Schema Open API + * + * No description provided (generated by Swagger Codegen https://github.com/swagger-api/swagger-codegen) + * + * API version: 2.4 + * Generated by: Swagger Codegen (https://github.com/swagger-api/swagger-codegen.git) + */ + +package hcsschema + +// VirtualSlitType : Indicates if a virtual SLIT should ne enabled for a VM and the type of virtual SLIT to be enabled. +type VirtualSlitType string + +// List of VirtualSlitType +const ( + VirtualSlitType_NONE VirtualSlitType = "None" + VirtualSlitType_FIRMWARE VirtualSlitType = "Firmware" + VirtualSlitType_MEASURED VirtualSlitType = "Measured" + VirtualSlitType_FIRMWARE_FALLBACK_MEASURED VirtualSlitType = "FirmwareFallbackMeasured" +) diff --git a/vendor/github.com/Microsoft/hcsshim/internal/hcs/schema2/windows_crash_reporting.go b/vendor/github.com/Microsoft/hcsshim/internal/hcs/schema2/windows_crash_reporting.go index 8ed7e566d..ee85c43b3 100644 --- a/vendor/github.com/Microsoft/hcsshim/internal/hcs/schema2/windows_crash_reporting.go +++ b/vendor/github.com/Microsoft/hcsshim/internal/hcs/schema2/windows_crash_reporting.go @@ -13,4 +13,6 @@ type WindowsCrashReporting struct { DumpFileName string `json:"DumpFileName,omitempty"` MaxDumpSize int64 `json:"MaxDumpSize,omitempty"` + + DumpType string `json:"DumpType,omitempty"` } diff --git a/vendor/github.com/Microsoft/hcsshim/internal/hcs/system.go b/vendor/github.com/Microsoft/hcsshim/internal/hcs/system.go index 81d60ed43..b1597466f 100644 --- a/vendor/github.com/Microsoft/hcsshim/internal/hcs/system.go +++ b/vendor/github.com/Microsoft/hcsshim/internal/hcs/system.go @@ -238,9 +238,10 @@ func (computeSystem *System) Shutdown(ctx context.Context) error { resultJSON, err := vmcompute.HcsShutdownComputeSystem(ctx, computeSystem.handle, "") events := processHcsResult(ctx, resultJSON) - switch err { //nolint:errorlint - case nil, ErrVmcomputeAlreadyStopped, ErrComputeSystemDoesNotExist, ErrVmcomputeOperationPending: - default: + if err != nil && + !errors.Is(err, ErrVmcomputeAlreadyStopped) && + !errors.Is(err, ErrComputeSystemDoesNotExist) && + !errors.Is(err, ErrVmcomputeOperationPending) { return makeSystemError(computeSystem, operation, err, events) } return nil @@ -259,9 +260,10 @@ func (computeSystem *System) Terminate(ctx context.Context) error { resultJSON, err := vmcompute.HcsTerminateComputeSystem(ctx, computeSystem.handle, "") events := processHcsResult(ctx, resultJSON) - switch err { //nolint:errorlint - case nil, ErrVmcomputeAlreadyStopped, ErrComputeSystemDoesNotExist, ErrVmcomputeOperationPending: - default: + if err != nil && + !errors.Is(err, ErrVmcomputeAlreadyStopped) && + !errors.Is(err, ErrComputeSystemDoesNotExist) && + !errors.Is(err, ErrVmcomputeOperationPending) { return makeSystemError(computeSystem, operation, err, events) } return nil @@ -279,14 +281,13 @@ func (computeSystem *System) waitBackground() { span.AddAttributes(trace.StringAttribute("cid", computeSystem.id)) err := waitForNotification(ctx, computeSystem.callbackNumber, hcsNotificationSystemExited, nil) - switch err { //nolint:errorlint - case nil: + if err == nil { log.G(ctx).Debug("system exited") - case ErrVmcomputeUnexpectedExit: + } else if errors.Is(err, ErrVmcomputeUnexpectedExit) { log.G(ctx).Debug("unexpected system exit") computeSystem.exitError = makeSystemError(computeSystem, operation, err, nil) err = nil - default: + } else { err = makeSystemError(computeSystem, operation, err, nil) } computeSystem.closedWaitOnce.Do(func() { diff --git a/vendor/github.com/Microsoft/hcsshim/internal/hns/hnsaccelnet.go b/vendor/github.com/Microsoft/hcsshim/internal/hns/hnsaccelnet.go index 82ca5baef..4b1e51cb7 100644 --- a/vendor/github.com/Microsoft/hcsshim/internal/hns/hnsaccelnet.go +++ b/vendor/github.com/Microsoft/hcsshim/internal/hns/hnsaccelnet.go @@ -47,7 +47,7 @@ func (nnvManagementMacList *HNSNnvManagementMacList) Set() (*HNSNnvManagementMac func GetNnvManagementMacAddressList() (*HNSNnvManagementMacList, error) { operation := "Get" title := "hcsshim::nnvManagementMacList::" + operation - logrus.Debugf(title) + logrus.Debug(title) return HNSNnvManagementMacRequest("GET", "", "") } @@ -55,6 +55,6 @@ func GetNnvManagementMacAddressList() (*HNSNnvManagementMacList, error) { func DeleteNnvManagementMacAddressList() (*HNSNnvManagementMacList, error) { operation := "Delete" title := "hcsshim::nnvManagementMacList::" + operation - logrus.Debugf(title) + logrus.Debug(title) return HNSNnvManagementMacRequest("DELETE", "", "") } diff --git a/vendor/github.com/Microsoft/hcsshim/internal/jobobject/jobobject.go b/vendor/github.com/Microsoft/hcsshim/internal/jobobject/jobobject.go index b505731c3..3afa240aa 100644 --- a/vendor/github.com/Microsoft/hcsshim/internal/jobobject/jobobject.go +++ b/vendor/github.com/Microsoft/hcsshim/internal/jobobject/jobobject.go @@ -22,9 +22,8 @@ import ( // of the job and a mutex for synchronized handle access. type JobObject struct { handle windows.Handle - // All accesses to this MUST be done atomically except in `Open` as the object - // is being created in the function. 1 signifies that this job is currently a silo. - silo uint32 + // silo signifies that this job is currently a silo. + silo atomic.Bool mq *queue.MessageQueue handleLock sync.RWMutex } @@ -204,9 +203,7 @@ func Open(ctx context.Context, options *Options) (_ *JobObject, err error) { handle: jobHandle, } - if isJobSilo(jobHandle) { - job.silo = 1 - } + job.silo.Store(isJobSilo(jobHandle)) // If the IOCP we'll be using to receive messages for all jobs hasn't been // created, create it and start polling. @@ -479,7 +476,7 @@ func (job *JobObject) ApplyFileBinding(root, target string, readOnly bool) error return ErrAlreadyClosed } - if !job.isSilo() { + if !job.silo.Load() { return ErrNotSilo } @@ -546,7 +543,7 @@ func (job *JobObject) PromoteToSilo() error { return ErrAlreadyClosed } - if job.isSilo() { + if job.silo.Load() { return nil } @@ -569,15 +566,10 @@ func (job *JobObject) PromoteToSilo() error { return fmt.Errorf("failed to promote job to silo: %w", err) } - atomic.StoreUint32(&job.silo, 1) + job.silo.Store(true) return nil } -// isSilo returns if the job object is a silo. -func (job *JobObject) isSilo() bool { - return atomic.LoadUint32(&job.silo) == 1 -} - // QueryPrivateWorkingSet returns the private working set size for the job. This is calculated by adding up the // private working set for every process running in the job. func (job *JobObject) QueryPrivateWorkingSet() (uint64, error) { diff --git a/vendor/github.com/Microsoft/hcsshim/internal/jobobject/limits.go b/vendor/github.com/Microsoft/hcsshim/internal/jobobject/limits.go index e3b1a1edc..fedf8add6 100644 --- a/vendor/github.com/Microsoft/hcsshim/internal/jobobject/limits.go +++ b/vendor/github.com/Microsoft/hcsshim/internal/jobobject/limits.go @@ -150,6 +150,7 @@ func (job *JobObject) SetCPUAffinity(affinityBitMask uint64) error { return fmt.Errorf("affinity bitmask (%d) exceeds max allowable value (%d)", affinityBitMask, maxUintptr) } + // CodeQL [SM03681] checked against max value above (there is no math.MaxUintPtr ...) info.BasicLimitInformation.Affinity = uintptr(affinityBitMask) return job.setExtendedInformation(info) } diff --git a/vendor/github.com/Microsoft/hcsshim/internal/log/context.go b/vendor/github.com/Microsoft/hcsshim/internal/log/context.go index d17d909d9..4399cec6f 100644 --- a/vendor/github.com/Microsoft/hcsshim/internal/log/context.go +++ b/vendor/github.com/Microsoft/hcsshim/internal/log/context.go @@ -4,7 +4,6 @@ import ( "context" "github.com/sirupsen/logrus" - "go.opencensus.io/trace" ) type entryContextKeyType int @@ -20,13 +19,13 @@ var ( // Instead, use `L.With*` or `L.Dup()`. Or `G(context.Background())`. L = logrus.NewEntry(logrus.StandardLogger()) - // G is an alias for GetEntry + // G is an alias for GetEntry. G = GetEntry - // S is an alias for SetEntry + // S is an alias for SetEntry. S = SetEntry - // U is an alias for UpdateContext + // U is an alias for UpdateContext. U = UpdateContext ) @@ -83,7 +82,7 @@ func UpdateContext(ctx context.Context) context.Context { // WithContext returns a context that contains the provided log entry. // The entry can be extracted with `GetEntry` (`G`) // -// The entry in the context is a copy of `entry` (generated by `entry.WithContext`) +// The entry in the context is a copy of `entry` (generated by `entry.WithContext`). func WithContext(ctx context.Context, entry *logrus.Entry) (context.Context, *logrus.Entry) { // regardless of the order, entry.Context != GetEntry(ctx) // here, the returned entry will reference the supplied context @@ -93,25 +92,6 @@ func WithContext(ctx context.Context, entry *logrus.Entry) (context.Context, *lo return ctx, entry } -// Copy extracts the tracing Span and logging entry from the src Context, if they -// exist, and adds them to the dst Context. -// -// This is useful to share tracing and logging between contexts, but not the -// cancellation. For example, if the src Context has been cancelled but cleanup -// operations triggered by the cancellation require a non-cancelled context to -// execute. -func Copy(dst context.Context, src context.Context) context.Context { - if s := trace.FromContext(src); s != nil { - dst = trace.NewContext(dst, s) - } - - if e := fromContext(src); e != nil { - dst, _ = WithContext(dst, e) - } - - return dst -} - func fromContext(ctx context.Context) *logrus.Entry { e, _ := ctx.Value(_entryContextKey).(*logrus.Entry) return e diff --git a/vendor/github.com/Microsoft/hcsshim/internal/log/format.go b/vendor/github.com/Microsoft/hcsshim/internal/log/format.go index 1ceb26bad..f26316fab 100644 --- a/vendor/github.com/Microsoft/hcsshim/internal/log/format.go +++ b/vendor/github.com/Microsoft/hcsshim/internal/log/format.go @@ -103,9 +103,7 @@ func encode(v interface{}) (_ []byte, err error) { if jErr := enc.Encode(v); jErr != nil { if err != nil { - // TODO (go1.20): use multierror via fmt.Errorf("...: %w; ...: %w", ...) - //nolint:errorlint // non-wrapping format verb for fmt.Errorf - return nil, fmt.Errorf("protojson encoding: %v; json encoding: %w", err, jErr) + return nil, fmt.Errorf("protojson encoding: %w; json encoding: %w", err, jErr) } return nil, fmt.Errorf("json encoding: %w", jErr) } diff --git a/vendor/github.com/Microsoft/hcsshim/internal/log/scrub.go b/vendor/github.com/Microsoft/hcsshim/internal/log/scrub.go index 5a960e0d3..5346f9b7c 100644 --- a/vendor/github.com/Microsoft/hcsshim/internal/log/scrub.go +++ b/vendor/github.com/Microsoft/hcsshim/internal/log/scrub.go @@ -22,23 +22,14 @@ var ( // case sensitive keywords, so "env" is not a substring on "Environment" _scrubKeywords = [][]byte{[]byte("env"), []byte("Environment")} - _scrub int32 + _scrub atomic.Bool ) // SetScrubbing enables scrubbing -func SetScrubbing(enable bool) { - v := int32(0) // cant convert from bool to int32 directly - if enable { - v = 1 - } - atomic.StoreInt32(&_scrub, v) -} +func SetScrubbing(enable bool) { _scrub.Store(enable) } // IsScrubbingEnabled checks if scrubbing is enabled -func IsScrubbingEnabled() bool { - v := atomic.LoadInt32(&_scrub) - return v != 0 -} +func IsScrubbingEnabled() bool { return _scrub.Load() } // ScrubProcessParameters scrubs HCS Create Process requests with config parameters of // type internal/hcs/schema2.ScrubProcessParameters (aka hcsshema.ScrubProcessParameters) diff --git a/vendor/github.com/Microsoft/hcsshim/internal/vmcompute/vmcompute.go b/vendor/github.com/Microsoft/hcsshim/internal/vmcompute/vmcompute.go index 67ca897cf..965086a58 100644 --- a/vendor/github.com/Microsoft/hcsshim/internal/vmcompute/vmcompute.go +++ b/vendor/github.com/Microsoft/hcsshim/internal/vmcompute/vmcompute.go @@ -104,7 +104,7 @@ func execute(ctx gcontext.Context, timeout time.Duration, f func() error) error }() select { case <-ctx.Done(): - if ctx.Err() == gcontext.DeadlineExceeded { //nolint:errorlint + if ctx.Err() == gcontext.DeadlineExceeded { log.G(ctx).WithField(logfields.Timeout, trueTimeout). Warning("Syscall did not complete within operation timeout. This may indicate a platform issue. " + "If it appears to be making no forward progress, obtain the stacks and see if there is a syscall " + diff --git a/vendor/github.com/Microsoft/hcsshim/internal/wclayer/legacy.go b/vendor/github.com/Microsoft/hcsshim/internal/wclayer/legacy.go index fc12eeba4..627060cee 100644 --- a/vendor/github.com/Microsoft/hcsshim/internal/wclayer/legacy.go +++ b/vendor/github.com/Microsoft/hcsshim/internal/wclayer/legacy.go @@ -34,6 +34,7 @@ const ( UtilityVMPath = `UtilityVM` UtilityVMFilesPath = `UtilityVM\Files` RegFilesPath = `Files\Windows\System32\config` + BootDirRelativePath = `\EFI\Microsoft\Boot` BcdFilePath = `UtilityVM\Files\EFI\Microsoft\Boot\BCD` BootMgrFilePath = `UtilityVM\Files\EFI\Microsoft\Boot\bootmgfw.efi` ContainerBaseVhd = `blank-base.vhdx` diff --git a/vendor/github.com/Microsoft/hcsshim/internal/winapi/cimfs.go b/vendor/github.com/Microsoft/hcsshim/internal/winapi/cimfs.go index 21664577b..6c026d982 100644 --- a/vendor/github.com/Microsoft/hcsshim/internal/winapi/cimfs.go +++ b/vendor/github.com/Microsoft/hcsshim/internal/winapi/cimfs.go @@ -32,10 +32,16 @@ type CimFsFileMetadata struct { EACount uint32 } +type CimFsImagePath struct { + ImageDir *uint16 + ImageName *uint16 +} + //sys CimMountImage(imagePath string, fsName string, flags uint32, volumeID *g) (hr error) = cimfs.CimMountImage? //sys CimDismountImage(volumeID *g) (hr error) = cimfs.CimDismountImage? //sys CimCreateImage(imagePath string, oldFSName *uint16, newFSName *uint16, cimFSHandle *FsHandle) (hr error) = cimfs.CimCreateImage? +//sys CimCreateImage2(imagePath string, flags uint32, oldFSName *uint16, newFSName *uint16, cimFSHandle *FsHandle) (hr error) = cimfs.CimCreateImage2? //sys CimCloseImage(cimFSHandle FsHandle) = cimfs.CimCloseImage? //sys CimCommitImage(cimFSHandle FsHandle) (hr error) = cimfs.CimCommitImage? @@ -45,3 +51,8 @@ type CimFsFileMetadata struct { //sys CimDeletePath(cimFSHandle FsHandle, path string) (hr error) = cimfs.CimDeletePath? //sys CimCreateHardLink(cimFSHandle FsHandle, newPath string, oldPath string) (hr error) = cimfs.CimCreateHardLink? //sys CimCreateAlternateStream(cimFSHandle FsHandle, path string, size uint64, cimStreamHandle *StreamHandle) (hr error) = cimfs.CimCreateAlternateStream? +//sys CimAddFsToMergedImage(cimFSHandle FsHandle, path string) (hr error) = cimfs.CimAddFsToMergedImage? +//sys CimAddFsToMergedImage2(cimFSHandle FsHandle, path string, flags uint32) (hr error) = cimfs.CimAddFsToMergedImage2? +//sys CimMergeMountImage(numCimPaths uint32, backingImagePaths *CimFsImagePath, flags uint32, volumeID *g) (hr error) = cimfs.CimMergeMountImage? +//sys CimTombstoneFile(cimFSHandle FsHandle, path string) (hr error) = cimfs.CimTombstoneFile? +//sys CimCreateMergeLink(cimFSHandle FsHandle, newPath string, oldPath string) (hr error) = cimfs.CimCreateMergeLink? diff --git a/vendor/github.com/Microsoft/hcsshim/internal/winapi/zsyscall_windows.go b/vendor/github.com/Microsoft/hcsshim/internal/winapi/zsyscall_windows.go index ecdded312..2abdc2e07 100644 --- a/vendor/github.com/Microsoft/hcsshim/internal/winapi/zsyscall_windows.go +++ b/vendor/github.com/Microsoft/hcsshim/internal/winapi/zsyscall_windows.go @@ -53,6 +53,8 @@ var ( procCM_Get_Device_ID_ListA = modcfgmgr32.NewProc("CM_Get_Device_ID_ListA") procCM_Get_Device_ID_List_SizeA = modcfgmgr32.NewProc("CM_Get_Device_ID_List_SizeA") procCM_Locate_DevNodeW = modcfgmgr32.NewProc("CM_Locate_DevNodeW") + procCimAddFsToMergedImage = modcimfs.NewProc("CimAddFsToMergedImage") + procCimAddFsToMergedImage2 = modcimfs.NewProc("CimAddFsToMergedImage2") procCimCloseImage = modcimfs.NewProc("CimCloseImage") procCimCloseStream = modcimfs.NewProc("CimCloseStream") procCimCommitImage = modcimfs.NewProc("CimCommitImage") @@ -60,9 +62,13 @@ var ( procCimCreateFile = modcimfs.NewProc("CimCreateFile") procCimCreateHardLink = modcimfs.NewProc("CimCreateHardLink") procCimCreateImage = modcimfs.NewProc("CimCreateImage") + procCimCreateImage2 = modcimfs.NewProc("CimCreateImage2") + procCimCreateMergeLink = modcimfs.NewProc("CimCreateMergeLink") procCimDeletePath = modcimfs.NewProc("CimDeletePath") procCimDismountImage = modcimfs.NewProc("CimDismountImage") + procCimMergeMountImage = modcimfs.NewProc("CimMergeMountImage") procCimMountImage = modcimfs.NewProc("CimMountImage") + procCimTombstoneFile = modcimfs.NewProc("CimTombstoneFile") procCimWriteStream = modcimfs.NewProc("CimWriteStream") procSetJobCompartmentId = modiphlpapi.NewProc("SetJobCompartmentId") procClosePseudoConsole = modkernel32.NewProc("ClosePseudoConsole") @@ -181,6 +187,54 @@ func _CMLocateDevNode(pdnDevInst *uint32, pDeviceID *uint16, uFlags uint32) (hr return } +func CimAddFsToMergedImage(cimFSHandle FsHandle, path string) (hr error) { + var _p0 *uint16 + _p0, hr = syscall.UTF16PtrFromString(path) + if hr != nil { + return + } + return _CimAddFsToMergedImage(cimFSHandle, _p0) +} + +func _CimAddFsToMergedImage(cimFSHandle FsHandle, path *uint16) (hr error) { + hr = procCimAddFsToMergedImage.Find() + if hr != nil { + return + } + r0, _, _ := syscall.SyscallN(procCimAddFsToMergedImage.Addr(), uintptr(cimFSHandle), uintptr(unsafe.Pointer(path))) + if int32(r0) < 0 { + if r0&0x1fff0000 == 0x00070000 { + r0 &= 0xffff + } + hr = syscall.Errno(r0) + } + return +} + +func CimAddFsToMergedImage2(cimFSHandle FsHandle, path string, flags uint32) (hr error) { + var _p0 *uint16 + _p0, hr = syscall.UTF16PtrFromString(path) + if hr != nil { + return + } + return _CimAddFsToMergedImage2(cimFSHandle, _p0, flags) +} + +func _CimAddFsToMergedImage2(cimFSHandle FsHandle, path *uint16, flags uint32) (hr error) { + hr = procCimAddFsToMergedImage2.Find() + if hr != nil { + return + } + r0, _, _ := syscall.SyscallN(procCimAddFsToMergedImage2.Addr(), uintptr(cimFSHandle), uintptr(unsafe.Pointer(path)), uintptr(flags)) + if int32(r0) < 0 { + if r0&0x1fff0000 == 0x00070000 { + r0 &= 0xffff + } + hr = syscall.Errno(r0) + } + return +} + func CimCloseImage(cimFSHandle FsHandle) (err error) { err = procCimCloseImage.Find() if err != nil { @@ -321,6 +375,59 @@ func _CimCreateImage(imagePath *uint16, oldFSName *uint16, newFSName *uint16, ci return } +func CimCreateImage2(imagePath string, flags uint32, oldFSName *uint16, newFSName *uint16, cimFSHandle *FsHandle) (hr error) { + var _p0 *uint16 + _p0, hr = syscall.UTF16PtrFromString(imagePath) + if hr != nil { + return + } + return _CimCreateImage2(_p0, flags, oldFSName, newFSName, cimFSHandle) +} + +func _CimCreateImage2(imagePath *uint16, flags uint32, oldFSName *uint16, newFSName *uint16, cimFSHandle *FsHandle) (hr error) { + hr = procCimCreateImage2.Find() + if hr != nil { + return + } + r0, _, _ := syscall.SyscallN(procCimCreateImage2.Addr(), uintptr(unsafe.Pointer(imagePath)), uintptr(flags), uintptr(unsafe.Pointer(oldFSName)), uintptr(unsafe.Pointer(newFSName)), uintptr(unsafe.Pointer(cimFSHandle))) + if int32(r0) < 0 { + if r0&0x1fff0000 == 0x00070000 { + r0 &= 0xffff + } + hr = syscall.Errno(r0) + } + return +} + +func CimCreateMergeLink(cimFSHandle FsHandle, newPath string, oldPath string) (hr error) { + var _p0 *uint16 + _p0, hr = syscall.UTF16PtrFromString(newPath) + if hr != nil { + return + } + var _p1 *uint16 + _p1, hr = syscall.UTF16PtrFromString(oldPath) + if hr != nil { + return + } + return _CimCreateMergeLink(cimFSHandle, _p0, _p1) +} + +func _CimCreateMergeLink(cimFSHandle FsHandle, newPath *uint16, oldPath *uint16) (hr error) { + hr = procCimCreateMergeLink.Find() + if hr != nil { + return + } + r0, _, _ := syscall.SyscallN(procCimCreateMergeLink.Addr(), uintptr(cimFSHandle), uintptr(unsafe.Pointer(newPath)), uintptr(unsafe.Pointer(oldPath))) + if int32(r0) < 0 { + if r0&0x1fff0000 == 0x00070000 { + r0 &= 0xffff + } + hr = syscall.Errno(r0) + } + return +} + func CimDeletePath(cimFSHandle FsHandle, path string) (hr error) { var _p0 *uint16 _p0, hr = syscall.UTF16PtrFromString(path) @@ -360,6 +467,21 @@ func CimDismountImage(volumeID *g) (hr error) { return } +func CimMergeMountImage(numCimPaths uint32, backingImagePaths *CimFsImagePath, flags uint32, volumeID *g) (hr error) { + hr = procCimMergeMountImage.Find() + if hr != nil { + return + } + r0, _, _ := syscall.SyscallN(procCimMergeMountImage.Addr(), uintptr(numCimPaths), uintptr(unsafe.Pointer(backingImagePaths)), uintptr(flags), uintptr(unsafe.Pointer(volumeID))) + if int32(r0) < 0 { + if r0&0x1fff0000 == 0x00070000 { + r0 &= 0xffff + } + hr = syscall.Errno(r0) + } + return +} + func CimMountImage(imagePath string, fsName string, flags uint32, volumeID *g) (hr error) { var _p0 *uint16 _p0, hr = syscall.UTF16PtrFromString(imagePath) @@ -389,6 +511,30 @@ func _CimMountImage(imagePath *uint16, fsName *uint16, flags uint32, volumeID *g return } +func CimTombstoneFile(cimFSHandle FsHandle, path string) (hr error) { + var _p0 *uint16 + _p0, hr = syscall.UTF16PtrFromString(path) + if hr != nil { + return + } + return _CimTombstoneFile(cimFSHandle, _p0) +} + +func _CimTombstoneFile(cimFSHandle FsHandle, path *uint16) (hr error) { + hr = procCimTombstoneFile.Find() + if hr != nil { + return + } + r0, _, _ := syscall.SyscallN(procCimTombstoneFile.Addr(), uintptr(cimFSHandle), uintptr(unsafe.Pointer(path))) + if int32(r0) < 0 { + if r0&0x1fff0000 == 0x00070000 { + r0 &= 0xffff + } + hr = syscall.Errno(r0) + } + return +} + func CimWriteStream(cimStreamHandle StreamHandle, buffer uintptr, bufferSize uint32) (hr error) { hr = procCimWriteStream.Find() if hr != nil { diff --git a/vendor/github.com/Microsoft/hcsshim/osversion/platform_compat_windows.go b/vendor/github.com/Microsoft/hcsshim/osversion/platform_compat_windows.go index f8d411ad7..a7860895c 100644 --- a/vendor/github.com/Microsoft/hcsshim/osversion/platform_compat_windows.go +++ b/vendor/github.com/Microsoft/hcsshim/osversion/platform_compat_windows.go @@ -3,7 +3,8 @@ package osversion // List of stable ABI compliant ltsc releases // Note: List must be sorted in ascending order var compatLTSCReleases = []uint16{ - V21H2Server, + LTSC2022, + LTSC2025, } // CheckHostAndContainerCompat checks if given host and container @@ -20,16 +21,25 @@ func CheckHostAndContainerCompat(host, ctr OSVersion) bool { } // If host is < WS 2022, exact version match is required - if host.Build < V21H2Server { + if host.Build < LTSC2022 { return host.Build == ctr.Build } - var supportedLtscRelease uint16 + // Find the latest LTSC version that is earlier than the host version. + // This is the earliest version of container that the host can run. + // + // If the host version is an LTSC, then it supports compatibility with + // everything from the previous LTSC up to itself, so we want supportedLTSCRelease + // to be the previous entry. + // + // If no match is found, then we know that the host is LTSC2022 exactly, + // since we already checked that it's not less than LTSC2022. + var supportedLTSCRelease uint16 = LTSC2022 for i := len(compatLTSCReleases) - 1; i >= 0; i-- { - if host.Build >= compatLTSCReleases[i] { - supportedLtscRelease = compatLTSCReleases[i] + if host.Build > compatLTSCReleases[i] { + supportedLTSCRelease = compatLTSCReleases[i] break } } - return ctr.Build >= supportedLtscRelease && ctr.Build <= host.Build + return supportedLTSCRelease <= ctr.Build && ctr.Build <= host.Build } diff --git a/vendor/github.com/Microsoft/hcsshim/osversion/windowsbuilds.go b/vendor/github.com/Microsoft/hcsshim/osversion/windowsbuilds.go index 446369591..5392a4cea 100644 --- a/vendor/github.com/Microsoft/hcsshim/osversion/windowsbuilds.go +++ b/vendor/github.com/Microsoft/hcsshim/osversion/windowsbuilds.go @@ -81,4 +81,11 @@ const ( // V22H2Win11 corresponds to Windows 11 (2022 Update). V22H2Win11 = 22621 + + // V23H2 is the 23H2 release in the Windows Server annual channel. + V23H2 = 25398 + + // Windows Server 2025 build 26100 + V25H1Server = 26100 + LTSC2025 = V25H1Server ) diff --git a/vendor/github.com/containers/storage/.cirrus.yml b/vendor/github.com/containers/storage/.cirrus.yml index 2349eb7f3..623ede2dd 100644 --- a/vendor/github.com/containers/storage/.cirrus.yml +++ b/vendor/github.com/containers/storage/.cirrus.yml @@ -17,13 +17,13 @@ env: #### #### Cache-image names to test with (double-quotes around names are critical) ### - FEDORA_NAME: "fedora-41" + FEDORA_NAME: "fedora-42" DEBIAN_NAME: "debian-13" # GCE project where images live IMAGE_PROJECT: "libpod-218412" # VM Image built in containers/automation_images - IMAGE_SUFFIX: "c20250324t111922z-f41f40d13" + IMAGE_SUFFIX: "c20250422t130822z-f42f41d13" FEDORA_CACHE_IMAGE_NAME: "fedora-${IMAGE_SUFFIX}" DEBIAN_CACHE_IMAGE_NAME: "debian-${IMAGE_SUFFIX}" @@ -128,6 +128,7 @@ lint_task: apt-get update apt-get install -y libbtrfs-dev libsubid-dev test_script: | + [ -n "${CIRRUS_BASE_SHA}" ] && git fetch origin ${CIRRUS_BASE_SHA} # Make ${CIRRUS_BASE_SHA} resolvable for git-validation make TAGS=regex_precompile local-validate make lint make clean diff --git a/vendor/github.com/containers/storage/Makefile b/vendor/github.com/containers/storage/Makefile index cfd3ed2a4..5da38efdd 100644 --- a/vendor/github.com/containers/storage/Makefile +++ b/vendor/github.com/containers/storage/Makefile @@ -35,7 +35,7 @@ TESTFLAGS := $(shell $(GO) test -race $(BUILDFLAGS) ./pkg/stringutils 2>&1 > /de # N/B: This value is managed by Renovate, manual changes are # possible, as long as they don't disturb the formatting # (i.e. DO NOT ADD A 'v' prefix!) -GOLANGCI_LINT_VERSION := 2.0.2 +GOLANGCI_LINT_VERSION := 2.2.1 default all: local-binary docs local-validate local-cross ## validate all checks, build and cross-build\nbinaries and docs diff --git a/vendor/github.com/containers/storage/VERSION b/vendor/github.com/containers/storage/VERSION index 79f82f6b8..5b1ab2700 100644 --- a/vendor/github.com/containers/storage/VERSION +++ b/vendor/github.com/containers/storage/VERSION @@ -1 +1 @@ -1.58.0 +1.59.1 diff --git a/vendor/github.com/containers/storage/deprecated.go b/vendor/github.com/containers/storage/deprecated.go index 5fadc27df..beb82b6bf 100644 --- a/vendor/github.com/containers/storage/deprecated.go +++ b/vendor/github.com/containers/storage/deprecated.go @@ -207,7 +207,6 @@ type LayerStore interface { Mounted(id string) (int, error) ParentOwners(id string) (uids, gids []int, err error) ApplyDiff(to string, diff io.Reader) (int64, error) - ApplyDiffWithDiffer(to string, options *drivers.ApplyDiffOpts, differ drivers.Differ) (*drivers.DriverWithDifferOutput, error) DifferTarget(id string) (string, error) LoadLocked() error PutAdditionalLayer(id string, parentLayer *Layer, names []string, aLayer drivers.AdditionalLayer) (layer *Layer, err error) diff --git a/vendor/github.com/containers/storage/drivers/aufs/aufs.go b/vendor/github.com/containers/storage/drivers/aufs/aufs.go index 5231c6f55..5925c9da3 100644 --- a/vendor/github.com/containers/storage/drivers/aufs/aufs.go +++ b/vendor/github.com/containers/storage/drivers/aufs/aufs.go @@ -36,6 +36,7 @@ import ( "time" graphdriver "github.com/containers/storage/drivers" + "github.com/containers/storage/internal/tempdir" "github.com/containers/storage/pkg/archive" "github.com/containers/storage/pkg/chrootarchive" "github.com/containers/storage/pkg/directory" @@ -772,8 +773,8 @@ func (a *Driver) UpdateLayerIDMap(id string, toContainer, toHost *idtools.IDMapp return fmt.Errorf("aufs doesn't support changing ID mappings") } -// SupportsShifting tells whether the driver support shifting of the UIDs/GIDs in an userNS -func (a *Driver) SupportsShifting() bool { +// SupportsShifting tells whether the driver support shifting of the UIDs/GIDs to the provided mapping in an userNS +func (a *Driver) SupportsShifting(uidmap, gidmap []idtools.IDMap) bool { return false } @@ -781,3 +782,14 @@ func (a *Driver) SupportsShifting() bool { func (a *Driver) Dedup(req graphdriver.DedupArgs) (graphdriver.DedupResult, error) { return graphdriver.DedupResult{}, nil } + +// DeferredRemove is not implemented. +// It calls Remove directly. +func (a *Driver) DeferredRemove(id string) (tempdir.CleanupTempDirFunc, error) { + return nil, a.Remove(id) +} + +// GetTempDirRootDirs is not implemented. +func (a *Driver) GetTempDirRootDirs() []string { + return []string{} +} diff --git a/vendor/github.com/containers/storage/drivers/btrfs/btrfs.go b/vendor/github.com/containers/storage/drivers/btrfs/btrfs.go index 4a80339f4..95bbe8cc7 100644 --- a/vendor/github.com/containers/storage/drivers/btrfs/btrfs.go +++ b/vendor/github.com/containers/storage/drivers/btrfs/btrfs.go @@ -30,6 +30,7 @@ import ( "unsafe" graphdriver "github.com/containers/storage/drivers" + "github.com/containers/storage/internal/tempdir" "github.com/containers/storage/pkg/directory" "github.com/containers/storage/pkg/fileutils" "github.com/containers/storage/pkg/idtools" @@ -678,3 +679,14 @@ func (d *Driver) AdditionalImageStores() []string { func (d *Driver) Dedup(req graphdriver.DedupArgs) (graphdriver.DedupResult, error) { return graphdriver.DedupResult{}, nil } + +// DeferredRemove is not implemented. +// It calls Remove directly. +func (d *Driver) DeferredRemove(id string) (tempdir.CleanupTempDirFunc, error) { + return nil, d.Remove(id) +} + +// GetTempDirRootDirs is not implemented. +func (d *Driver) GetTempDirRootDirs() []string { + return []string{} +} diff --git a/vendor/github.com/containers/storage/drivers/chown.go b/vendor/github.com/containers/storage/drivers/chown.go index d728e919b..df602760e 100644 --- a/vendor/github.com/containers/storage/drivers/chown.go +++ b/vendor/github.com/containers/storage/drivers/chown.go @@ -131,7 +131,7 @@ func (n *naiveLayerIDMapUpdater) UpdateLayerIDMap(id string, toContainer, toHost return ChownPathByMaps(layerFs, toContainer, toHost) } -// SupportsShifting tells whether the driver support shifting of the UIDs/GIDs in an userNS -func (n *naiveLayerIDMapUpdater) SupportsShifting() bool { +// SupportsShifting tells whether the driver support shifting of the UIDs/GIDs to the provided mapping in an userNS +func (n *naiveLayerIDMapUpdater) SupportsShifting(uidmap, gidmap []idtools.IDMap) bool { return false } diff --git a/vendor/github.com/containers/storage/drivers/driver.go b/vendor/github.com/containers/storage/drivers/driver.go index 06263e750..553778081 100644 --- a/vendor/github.com/containers/storage/drivers/driver.go +++ b/vendor/github.com/containers/storage/drivers/driver.go @@ -9,6 +9,7 @@ import ( "strings" "github.com/containers/storage/internal/dedup" + "github.com/containers/storage/internal/tempdir" "github.com/containers/storage/pkg/archive" "github.com/containers/storage/pkg/directory" "github.com/containers/storage/pkg/fileutils" @@ -123,7 +124,17 @@ type ProtoDriver interface { // and parent, with contents identical to the specified template layer. CreateFromTemplate(id, template string, templateIDMappings *idtools.IDMappings, parent string, parentIDMappings *idtools.IDMappings, opts *CreateOpts, readWrite bool) error // Remove attempts to remove the filesystem layer with this id. + // This is soft-deprecated and should not get any new callers; use DeferredRemove. Remove(id string) error + // DeferredRemove is used to remove the filesystem layer with this id. + // This removal happen immediately (the layer is no longer usable), + // but physically deleting the files may be deferred. + // Caller MUST call returned Cleanup function EVEN IF the function returns an error. + DeferredRemove(id string) (tempdir.CleanupTempDirFunc, error) + // GetTempDirRootDirs returns the root directories for temporary directories. + // Multiple directories may be returned when drivers support different filesystems + // for layers (e.g., overlay with imageStore vs home directory). + GetTempDirRootDirs() []string // Get returns the mountpoint for the layered filesystem referred // to by this id. You can optionally specify a mountLabel or "". // Optionally it gets the mappings used to create the layer. @@ -193,8 +204,9 @@ type LayerIDMapUpdater interface { UpdateLayerIDMap(id string, toContainer, toHost *idtools.IDMappings, mountLabel string) error // SupportsShifting tells whether the driver support shifting of the UIDs/GIDs in a - // image and it is not required to Chown the files when running in an user namespace. - SupportsShifting() bool + // image to the provided mapping and it is not required to Chown the files when running in + // an user namespace. + SupportsShifting(uidmap, gidmap []idtools.IDMap) bool } // Driver is the interface for layered/snapshot file system drivers. @@ -216,8 +228,10 @@ type DriverWithDifferOutput struct { CompressedDigest digest.Digest Metadata string BigData map[string][]byte - TarSplit []byte // nil if not available - TOCDigest digest.Digest + // TarSplit is owned by the [DriverWithDifferOutput], and must be closed by calling one of + // [Store.ApplyStagedLayer]/[Store.CleanupStagedLayer]. It is nil if not available. + TarSplit *os.File + TOCDigest digest.Digest // RootDirMode is the mode of the root directory of the layer, if specified. RootDirMode *os.FileMode // Artifacts is a collection of additional artifacts @@ -267,6 +281,7 @@ type DifferOptions struct { // This API is experimental and can be changed without bumping the major version number. type Differ interface { ApplyDiff(dest string, options *archive.TarOptions, differOpts *DifferOptions) (DriverWithDifferOutput, error) + Close() error } // DriverWithDiffer is the interface for direct diff access. diff --git a/vendor/github.com/containers/storage/drivers/overlay/overlay.go b/vendor/github.com/containers/storage/drivers/overlay/overlay.go index 5345ff9d6..2bc115afd 100644 --- a/vendor/github.com/containers/storage/drivers/overlay/overlay.go +++ b/vendor/github.com/containers/storage/drivers/overlay/overlay.go @@ -23,6 +23,8 @@ import ( "github.com/containers/storage/drivers/overlayutils" "github.com/containers/storage/drivers/quota" "github.com/containers/storage/internal/dedup" + "github.com/containers/storage/internal/staging_lockfile" + "github.com/containers/storage/internal/tempdir" "github.com/containers/storage/pkg/archive" "github.com/containers/storage/pkg/chrootarchive" "github.com/containers/storage/pkg/directory" @@ -30,7 +32,6 @@ import ( "github.com/containers/storage/pkg/fsutils" "github.com/containers/storage/pkg/idmap" "github.com/containers/storage/pkg/idtools" - "github.com/containers/storage/pkg/lockfile" "github.com/containers/storage/pkg/mount" "github.com/containers/storage/pkg/parsers" "github.com/containers/storage/pkg/system" @@ -80,10 +81,11 @@ const ( // that mounts do not fail due to length. const ( - linkDir = "l" - stagingDir = "staging" - lowerFile = "lower" - maxDepth = 500 + linkDir = "l" + stagingDir = "staging" + tempDirName = "tempdirs" + lowerFile = "lower" + maxDepth = 500 stagingLockFile = "staging.lock" @@ -133,7 +135,7 @@ type Driver struct { stagingDirsLocksMutex sync.Mutex // stagingDirsLocks access is not thread safe, it is required that callers take // stagingDirsLocksMutex on each access to guard against concurrent map writes. - stagingDirsLocks map[string]*lockfile.LockFile + stagingDirsLocks map[string]*staging_lockfile.StagingLockFile supportsIDMappedMounts *bool } @@ -222,7 +224,7 @@ func checkAndRecordIDMappedSupport(home, runhome string) (bool, error) { return supportsIDMappedMounts, err } -func checkAndRecordOverlaySupport(fsMagic graphdriver.FsMagic, home, runhome string) (bool, error) { +func checkAndRecordOverlaySupport(home, runhome string) (bool, error) { var supportsDType bool if os.Geteuid() != 0 { @@ -242,7 +244,7 @@ func checkAndRecordOverlaySupport(fsMagic graphdriver.FsMagic, home, runhome str return false, errors.New(overlayCacheText) } } else { - supportsDType, err = supportsOverlay(home, fsMagic, 0, 0) + supportsDType, err = supportsOverlay(home, 0, 0) if err != nil { os.Remove(filepath.Join(home, linkDir)) os.Remove(home) @@ -388,7 +390,7 @@ func Init(home string, options graphdriver.Options) (graphdriver.Driver, error) t := true supportsVolatile = &t } else { - supportsDType, err = checkAndRecordOverlaySupport(fsMagic, home, runhome) + supportsDType, err = checkAndRecordOverlaySupport(home, runhome) if err != nil { return nil, err } @@ -442,7 +444,7 @@ func Init(home string, options graphdriver.Options) (graphdriver.Driver, error) usingComposefs: opts.useComposefs, options: *opts, stagingDirsLocksMutex: sync.Mutex{}, - stagingDirsLocks: make(map[string]*lockfile.LockFile), + stagingDirsLocks: make(map[string]*staging_lockfile.StagingLockFile), } d.naiveDiff = graphdriver.NewNaiveDiffDriver(d, graphdriver.NewNaiveLayerIDMapUpdater(d)) @@ -666,16 +668,11 @@ func SupportsNativeOverlay(home, runhome string) (bool, error) { } } - fsMagic, err := graphdriver.GetFSMagic(home) - if err != nil { - return false, err - } - - supportsDType, _ := checkAndRecordOverlaySupport(fsMagic, home, runhome) + supportsDType, _ := checkAndRecordOverlaySupport(home, runhome) return supportsDType, nil } -func supportsOverlay(home string, homeMagic graphdriver.FsMagic, rootUID, rootGID int) (supportsDType bool, err error) { +func supportsOverlay(home string, rootUID, rootGID int) (supportsDType bool, err error) { selinuxLabelTest := selinux.PrivContainerMountLabel() logLevel := logrus.ErrorLevel @@ -828,7 +825,7 @@ func (d *Driver) Status() [][2]string { {"Supports d_type", strconv.FormatBool(d.supportsDType)}, {"Native Overlay Diff", strconv.FormatBool(!d.useNaiveDiff())}, {"Using metacopy", strconv.FormatBool(d.usingMetacopy)}, - {"Supports shifting", strconv.FormatBool(d.SupportsShifting())}, + {"Supports shifting", strconv.FormatBool(d.SupportsShifting(nil, nil))}, {"Supports volatile", strconv.FormatBool(supportsVolatile)}, } } @@ -874,7 +871,9 @@ func (d *Driver) Cleanup() error { func (d *Driver) pruneStagingDirectories() bool { d.stagingDirsLocksMutex.Lock() for _, lock := range d.stagingDirsLocks { - lock.Unlock() + if err := lock.UnlockAndDelete(); err != nil { + logrus.Warnf("Failed to unlock and delete staging lock file: %v", err) + } } clear(d.stagingDirsLocks) d.stagingDirsLocksMutex.Unlock() @@ -886,17 +885,15 @@ func (d *Driver) pruneStagingDirectories() bool { if err == nil { for _, dir := range dirs { stagingDirToRemove := filepath.Join(stagingDirBase, dir.Name()) - lock, err := lockfile.GetLockFile(filepath.Join(stagingDirToRemove, stagingLockFile)) + lock, err := staging_lockfile.TryLockPath(filepath.Join(stagingDirToRemove, stagingLockFile)) if err != nil { anyPresent = true continue } - if err := lock.TryLock(); err != nil { - anyPresent = true - continue - } _ = os.RemoveAll(stagingDirToRemove) - lock.Unlock() + if err := lock.UnlockAndDelete(); err != nil { + logrus.Warnf("Failed to unlock and delete staging lock file: %v", err) + } } } return anyPresent @@ -1310,17 +1307,22 @@ func (d *Driver) optsAppendMappings(opts string, uidMaps, gidMaps []idtools.IDMa // Remove cleans the directories that are created for this id. func (d *Driver) Remove(id string) error { + return d.removeCommon(id, system.EnsureRemoveAll) +} + +func (d *Driver) removeCommon(id string, cleanup func(string) error) error { dir := d.dir(id) lid, err := os.ReadFile(path.Join(dir, "link")) if err == nil { - if err := os.RemoveAll(path.Join(d.home, linkDir, string(lid))); err != nil { + linkPath := path.Join(d.home, linkDir, string(lid)) + if err := cleanup(linkPath); err != nil { logrus.Debugf("Failed to remove link: %v", err) } } d.releaseAdditionalLayerByID(id) - if err := system.EnsureRemoveAll(dir); err != nil && !os.IsNotExist(err) { + if err := cleanup(dir); err != nil && !os.IsNotExist(err) { return err } if d.quotaCtl != nil { @@ -1332,6 +1334,41 @@ func (d *Driver) Remove(id string) error { return nil } +func (d *Driver) GetTempDirRootDirs() []string { + tempDirs := []string{filepath.Join(d.home, tempDirName)} + // Include imageStore temp directory if it's configured + // Writable layers can only be in d.home or d.imageStore, not in additional image stores + if d.imageStore != "" { + tempDirs = append(tempDirs, filepath.Join(d.imageStore, d.name, tempDirName)) + } + return tempDirs +} + +// Determine the correct temp directory root based on where the layer actually exists. +func (d *Driver) getTempDirRoot(id string) string { + layerDir := d.dir(id) + if d.imageStore != "" { + expectedLayerDir := path.Join(d.imageStore, d.name, id) + if layerDir == expectedLayerDir { + return filepath.Join(d.imageStore, d.name, tempDirName) + } + } + return filepath.Join(d.home, tempDirName) +} + +func (d *Driver) DeferredRemove(id string) (tempdir.CleanupTempDirFunc, error) { + tempDirRoot := d.getTempDirRoot(id) + t, err := tempdir.NewTempDir(tempDirRoot) + if err != nil { + return nil, err + } + + if err := d.removeCommon(id, t.StageDeletion); err != nil { + return t.Cleanup, fmt.Errorf("failed to add to stage directory: %w", err) + } + return t.Cleanup, nil +} + // recreateSymlinks goes through the driver's home directory and checks if the diff directory // under each layer has a symlink created for it under the linkDir. If the symlink does not // exist, it creates them @@ -1358,8 +1395,8 @@ func (d *Driver) recreateSymlinks() error { // Check that for each layer, there's a link in "l" with the name in // the layer's "link" file that points to the layer's "diff" directory. for _, dir := range dirs { - // Skip over the linkDir and anything that is not a directory - if dir.Name() == linkDir || !dir.IsDir() { + // Skip over the linkDir, stagingDir, tempDirName and anything that is not a directory + if dir.Name() == linkDir || dir.Name() == stagingDir || dir.Name() == tempDirName || !dir.IsDir() { continue } // Read the "link" file under each layer to get the name of the symlink @@ -1483,7 +1520,7 @@ func (d *Driver) get(id string, disableShifting bool, options graphdriver.MountO readWrite := !inAdditionalStore - if !d.SupportsShifting() || options.DisableShifting { + if !d.SupportsShifting(options.UidMaps, options.GidMaps) || options.DisableShifting { disableShifting = true } @@ -2027,7 +2064,7 @@ func (d *Driver) ListLayers() ([]string, error) { for _, entry := range entries { id := entry.Name() switch id { - case linkDir, stagingDir, quota.BackingFsBlockDeviceLink, mountProgramFlagFile: + case linkDir, stagingDir, tempDirName, quota.BackingFsBlockDeviceLink, mountProgramFlagFile: // expected, but not a layer. skip it continue default: @@ -2178,7 +2215,10 @@ func (d *Driver) CleanupStagingDirectory(stagingDirectory string) error { d.stagingDirsLocksMutex.Lock() if lock, ok := d.stagingDirsLocks[parentStagingDir]; ok { delete(d.stagingDirsLocks, parentStagingDir) - lock.Unlock() + if err := lock.UnlockAndDelete(); err != nil { + d.stagingDirsLocksMutex.Unlock() + return err + } } d.stagingDirsLocksMutex.Unlock() @@ -2233,7 +2273,7 @@ func (d *Driver) ApplyDiffWithDiffer(options *graphdriver.ApplyDiffWithDifferOpt return graphdriver.DriverWithDifferOutput{}, err } - lock, err := lockfile.GetLockFile(filepath.Join(layerDir, stagingLockFile)) + lock, err := staging_lockfile.TryLockPath(filepath.Join(layerDir, stagingLockFile)) if err != nil { return graphdriver.DriverWithDifferOutput{}, err } @@ -2242,13 +2282,14 @@ func (d *Driver) ApplyDiffWithDiffer(options *graphdriver.ApplyDiffWithDifferOpt d.stagingDirsLocksMutex.Lock() delete(d.stagingDirsLocks, layerDir) d.stagingDirsLocksMutex.Unlock() - lock.Unlock() + if err := lock.UnlockAndDelete(); err != nil { + errRet = errors.Join(errRet, err) + } } }() d.stagingDirsLocksMutex.Lock() d.stagingDirsLocks[layerDir] = lock d.stagingDirsLocksMutex.Unlock() - lock.Lock() logrus.Debugf("Applying differ in %s", applyDir) @@ -2274,7 +2315,7 @@ func (d *Driver) ApplyDiffWithDiffer(options *graphdriver.ApplyDiffWithDifferOpt } // ApplyDiffFromStagingDirectory applies the changes using the specified staging directory. -func (d *Driver) ApplyDiffFromStagingDirectory(id, parent string, diffOutput *graphdriver.DriverWithDifferOutput, options *graphdriver.ApplyDiffWithDifferOpts) error { +func (d *Driver) ApplyDiffFromStagingDirectory(id, parent string, diffOutput *graphdriver.DriverWithDifferOutput, options *graphdriver.ApplyDiffWithDifferOpts) (errRet error) { stagingDirectory := diffOutput.Target parentStagingDir := filepath.Dir(stagingDirectory) @@ -2282,7 +2323,9 @@ func (d *Driver) ApplyDiffFromStagingDirectory(id, parent string, diffOutput *gr d.stagingDirsLocksMutex.Lock() if lock, ok := d.stagingDirsLocks[parentStagingDir]; ok { delete(d.stagingDirsLocks, parentStagingDir) - lock.Unlock() + if err := lock.UnlockAndDelete(); err != nil { + errRet = errors.Join(errRet, err) + } } d.stagingDirsLocksMutex.Unlock() }() @@ -2553,12 +2596,20 @@ func (d *Driver) supportsIDmappedMounts() bool { return false } -// SupportsShifting tells whether the driver support shifting of the UIDs/GIDs in an userNS -func (d *Driver) SupportsShifting() bool { +// SupportsShifting tells whether the driver support shifting of the UIDs/GIDs to the provided mapping in an userNS +func (d *Driver) SupportsShifting(uidmap, gidmap []idtools.IDMap) bool { if os.Getenv("_CONTAINERS_OVERLAY_DISABLE_IDMAP") == "yes" { return false } if d.options.mountProgram != "" { + // fuse-overlayfs supports only contiguous mappings, since it performs the mapping on the + // upper layer too, to avoid https://github.com/containers/podman/issues/10272 + if !idtools.IsContiguous(uidmap) { + return false + } + if !idtools.IsContiguous(gidmap) { + return false + } return true } return d.supportsIDmappedMounts() diff --git a/vendor/github.com/containers/storage/drivers/vfs/driver.go b/vendor/github.com/containers/storage/drivers/vfs/driver.go index 98dc55b0e..7ad5186ae 100644 --- a/vendor/github.com/containers/storage/drivers/vfs/driver.go +++ b/vendor/github.com/containers/storage/drivers/vfs/driver.go @@ -11,6 +11,7 @@ import ( graphdriver "github.com/containers/storage/drivers" "github.com/containers/storage/internal/dedup" + "github.com/containers/storage/internal/tempdir" "github.com/containers/storage/pkg/archive" "github.com/containers/storage/pkg/directory" "github.com/containers/storage/pkg/fileutils" @@ -22,7 +23,10 @@ import ( "github.com/vbatts/tar-split/tar/storage" ) -const defaultPerms = os.FileMode(0o555) +const ( + defaultPerms = os.FileMode(0o555) + tempDirName = "tempdirs" +) func init() { graphdriver.MustRegister("vfs", Init) @@ -244,6 +248,42 @@ func (d *Driver) Remove(id string) error { return system.EnsureRemoveAll(d.dir(id)) } +func (d *Driver) GetTempDirRootDirs() []string { + tempDirs := []string{filepath.Join(d.home, tempDirName)} + // Include imageStore temp directory if it's configured + // Writable layers can only be in d.home or d.imageStore, not in additionalHomes (which are read-only) + if d.imageStore != "" { + tempDirs = append(tempDirs, filepath.Join(d.imageStore, d.String(), tempDirName)) + } + return tempDirs +} + +// Determine the correct temp directory root based on where the layer actually exists. +func (d *Driver) getTempDirRoot(id string) string { + layerDir := d.dir(id) + if d.imageStore != "" { + expectedLayerDir := filepath.Join(d.imageStore, d.String(), "dir", filepath.Base(id)) + if layerDir == expectedLayerDir { + return filepath.Join(d.imageStore, d.String(), tempDirName) + } + } + return filepath.Join(d.home, tempDirName) +} + +func (d *Driver) DeferredRemove(id string) (tempdir.CleanupTempDirFunc, error) { + tempDirRoot := d.getTempDirRoot(id) + t, err := tempdir.NewTempDir(tempDirRoot) + if err != nil { + return nil, err + } + + layerDir := d.dir(id) + if err := t.StageDeletion(layerDir); err != nil { + return t.Cleanup, err + } + return t.Cleanup, nil +} + // Get returns the directory for the given id. func (d *Driver) Get(id string, options graphdriver.MountOpts) (_ string, retErr error) { dir := d.dir(id) @@ -312,9 +352,9 @@ func (d *Driver) AdditionalImageStores() []string { return nil } -// SupportsShifting tells whether the driver support shifting of the UIDs/GIDs in an userNS -func (d *Driver) SupportsShifting() bool { - return d.updater.SupportsShifting() +// SupportsShifting tells whether the driver support shifting of the UIDs/GIDs to the provided mapping in an userNS +func (d *Driver) SupportsShifting(uidmap, gidmap []idtools.IDMap) bool { + return d.updater.SupportsShifting(uidmap, gidmap) } // UpdateLayerIDMap updates ID mappings in a from matching the ones specified diff --git a/vendor/github.com/containers/storage/drivers/windows/windows.go b/vendor/github.com/containers/storage/drivers/windows/windows.go index 59ed9a756..13bd75cfb 100644 --- a/vendor/github.com/containers/storage/drivers/windows/windows.go +++ b/vendor/github.com/containers/storage/drivers/windows/windows.go @@ -24,6 +24,7 @@ import ( "github.com/Microsoft/go-winio/backuptar" "github.com/Microsoft/hcsshim" graphdriver "github.com/containers/storage/drivers" + "github.com/containers/storage/internal/tempdir" "github.com/containers/storage/pkg/archive" "github.com/containers/storage/pkg/directory" "github.com/containers/storage/pkg/fileutils" @@ -986,8 +987,8 @@ func (d *Driver) UpdateLayerIDMap(id string, toContainer, toHost *idtools.IDMapp return fmt.Errorf("windows doesn't support changing ID mappings") } -// SupportsShifting tells whether the driver support shifting of the UIDs/GIDs in an userNS -func (d *Driver) SupportsShifting() bool { +// SupportsShifting tells whether the driver support shifting of the UIDs/GIDs to the provided mapping in an userNS +func (d *Driver) SupportsShifting(uidmap, gidmap []idtools.IDMap) bool { return false } @@ -1014,3 +1015,14 @@ func parseStorageOpt(storageOpt map[string]string) (*storageOptions, error) { } return &options, nil } + +// DeferredRemove is not implemented. +// It calls Remove directly. +func (d *Driver) DeferredRemove(id string) (tempdir.CleanupTempDirFunc, error) { + return nil, d.Remove(id) +} + +// GetTempDirRootDirs is not implemented. +func (d *Driver) GetTempDirRootDirs() []string { + return []string{} +} diff --git a/vendor/github.com/containers/storage/drivers/zfs/zfs.go b/vendor/github.com/containers/storage/drivers/zfs/zfs.go index f53b0e1b6..6be430b3e 100644 --- a/vendor/github.com/containers/storage/drivers/zfs/zfs.go +++ b/vendor/github.com/containers/storage/drivers/zfs/zfs.go @@ -13,6 +13,7 @@ import ( "time" graphdriver "github.com/containers/storage/drivers" + "github.com/containers/storage/internal/tempdir" "github.com/containers/storage/pkg/directory" "github.com/containers/storage/pkg/idtools" "github.com/containers/storage/pkg/mount" @@ -406,6 +407,12 @@ func (d *Driver) Remove(id string) error { return nil } +// DeferredRemove is not implemented. +// It calls Remove directly. +func (d *Driver) DeferredRemove(id string) (tempdir.CleanupTempDirFunc, error) { + return nil, d.Remove(id) +} + // Get returns the mountpoint for the given id after creating the target directories if necessary. func (d *Driver) Get(id string, options graphdriver.MountOpts) (_ string, retErr error) { mountpoint := d.mountPath(id) @@ -516,3 +523,8 @@ func (d *Driver) AdditionalImageStores() []string { func (d *Driver) Dedup(req graphdriver.DedupArgs) (graphdriver.DedupResult, error) { return graphdriver.DedupResult{}, nil } + +// GetTempDirRootDirs is not implemented. +func (d *Driver) GetTempDirRootDirs() []string { + return []string{} +} diff --git a/vendor/github.com/containers/storage/internal/rawfilelock/rawfilelock.go b/vendor/github.com/containers/storage/internal/rawfilelock/rawfilelock.go new file mode 100644 index 000000000..4f340ae3c --- /dev/null +++ b/vendor/github.com/containers/storage/internal/rawfilelock/rawfilelock.go @@ -0,0 +1,64 @@ +package rawfilelock + +import ( + "os" +) + +type LockType byte + +const ( + ReadLock LockType = iota + WriteLock +) + +type FileHandle = fileHandle + +// OpenLock opens a file for locking +// WARNING: This is the underlying file locking primitive of the OS; +// because closing FileHandle releases the lock, it is not suitable for use +// if there is any chance of two concurrent goroutines attempting to use the same lock. +// Most users should use the higher-level operations from internal/staging_lockfile or pkg/lockfile. +func OpenLock(path string, readOnly bool) (FileHandle, error) { + flags := os.O_CREATE + if readOnly { + flags |= os.O_RDONLY + } else { + flags |= os.O_RDWR + } + + fd, err := openHandle(path, flags) + if err == nil { + return fd, nil + } + + return fd, &os.PathError{Op: "open", Path: path, Err: err} +} + +// TryLockFile attempts to lock a file handle +func TryLockFile(fd FileHandle, lockType LockType) error { + return lockHandle(fd, lockType, true) +} + +// LockFile locks a file handle +func LockFile(fd FileHandle, lockType LockType) error { + return lockHandle(fd, lockType, false) +} + +// UnlockAndClose unlocks and closes a file handle +func UnlockAndCloseHandle(fd FileHandle) { + unlockAndCloseHandle(fd) +} + +// CloseHandle closes a file handle without unlocking +// +// WARNING: This is a last-resort function for error handling only! +// On Unix systems, closing a file descriptor automatically releases any locks, +// so "closing without unlocking" is impossible. This function will release +// the lock as a side effect of closing the file. +// +// This function should only be used in error paths where the lock state +// is already corrupted or when giving up on lock management entirely. +// Normal code should use UnlockAndCloseHandle instead. +func CloseHandle(fd FileHandle) { + closeHandle(fd) +} diff --git a/vendor/github.com/containers/storage/internal/rawfilelock/rawfilelock_unix.go b/vendor/github.com/containers/storage/internal/rawfilelock/rawfilelock_unix.go new file mode 100644 index 000000000..268554076 --- /dev/null +++ b/vendor/github.com/containers/storage/internal/rawfilelock/rawfilelock_unix.go @@ -0,0 +1,49 @@ +//go:build !windows + +package rawfilelock + +import ( + "time" + + "golang.org/x/sys/unix" +) + +type fileHandle uintptr + +func openHandle(path string, mode int) (fileHandle, error) { + mode |= unix.O_CLOEXEC + fd, err := unix.Open(path, mode, 0o644) + return fileHandle(fd), err +} + +func lockHandle(fd fileHandle, lType LockType, nonblocking bool) error { + fType := unix.F_RDLCK + if lType != ReadLock { + fType = unix.F_WRLCK + } + lk := unix.Flock_t{ + Type: int16(fType), + Whence: int16(unix.SEEK_SET), + Start: 0, + Len: 0, + } + cmd := unix.F_SETLKW + if nonblocking { + cmd = unix.F_SETLK + } + for { + err := unix.FcntlFlock(uintptr(fd), cmd, &lk) + if err == nil || nonblocking { + return err + } + time.Sleep(10 * time.Millisecond) + } +} + +func unlockAndCloseHandle(fd fileHandle) { + unix.Close(int(fd)) +} + +func closeHandle(fd fileHandle) { + unix.Close(int(fd)) +} diff --git a/vendor/github.com/containers/storage/internal/rawfilelock/rawfilelock_windows.go b/vendor/github.com/containers/storage/internal/rawfilelock/rawfilelock_windows.go new file mode 100644 index 000000000..9c0d692f8 --- /dev/null +++ b/vendor/github.com/containers/storage/internal/rawfilelock/rawfilelock_windows.go @@ -0,0 +1,48 @@ +//go:build windows + +package rawfilelock + +import ( + "golang.org/x/sys/windows" +) + +const ( + reserved = 0 + allBytes = ^uint32(0) +) + +type fileHandle windows.Handle + +func openHandle(path string, mode int) (fileHandle, error) { + mode |= windows.O_CLOEXEC + fd, err := windows.Open(path, mode, windows.S_IWRITE) + return fileHandle(fd), err +} + +func lockHandle(fd fileHandle, lType LockType, nonblocking bool) error { + flags := 0 + if lType != ReadLock { + flags = windows.LOCKFILE_EXCLUSIVE_LOCK + } + if nonblocking { + flags |= windows.LOCKFILE_FAIL_IMMEDIATELY + } + ol := new(windows.Overlapped) + if err := windows.LockFileEx(windows.Handle(fd), uint32(flags), reserved, allBytes, allBytes, ol); err != nil { + if nonblocking { + return err + } + panic(err) + } + return nil +} + +func unlockAndCloseHandle(fd fileHandle) { + ol := new(windows.Overlapped) + windows.UnlockFileEx(windows.Handle(fd), reserved, allBytes, allBytes, ol) + closeHandle(fd) +} + +func closeHandle(fd fileHandle) { + windows.Close(windows.Handle(fd)) +} diff --git a/vendor/github.com/containers/storage/internal/staging_lockfile/staging_lockfile.go b/vendor/github.com/containers/storage/internal/staging_lockfile/staging_lockfile.go new file mode 100644 index 000000000..1cb2a3327 --- /dev/null +++ b/vendor/github.com/containers/storage/internal/staging_lockfile/staging_lockfile.go @@ -0,0 +1,147 @@ +package staging_lockfile + +import ( + "fmt" + "os" + "path/filepath" + "sync" + + "github.com/containers/storage/internal/rawfilelock" +) + +// StagingLockFile represents a file lock used to coordinate access to staging areas. +// Typical usage is via CreateAndLock or TryLockPath, both of which return a StagingLockFile +// that must eventually be released with UnlockAndDelete. This ensures that access +// to the staging file is properly synchronized both within and across processes. +// +// WARNING: This struct MUST NOT be created manually. Use the provided helper functions instead. +type StagingLockFile struct { + // Locking invariant: If stagingLockFileLock is not locked, a StagingLockFile for a particular + // path exists if the current process currently owns the lock for that file, and it is recorded in stagingLockFiles. + // + // The following fields can only be accessed by the goroutine owning the lock. + // + // An empty string in the file field means that the lock has been released and the StagingLockFile is no longer valid. + file string // Also the key in stagingLockFiles + fd rawfilelock.FileHandle +} + +const maxRetries = 1000 + +var ( + stagingLockFiles map[string]*StagingLockFile + stagingLockFileLock sync.Mutex +) + +// tryAcquireLockForFile attempts to acquire a lock for the specified file path. +func tryAcquireLockForFile(path string) (*StagingLockFile, error) { + cleanPath, err := filepath.Abs(path) + if err != nil { + return nil, fmt.Errorf("ensuring that path %q is an absolute path: %w", path, err) + } + + stagingLockFileLock.Lock() + defer stagingLockFileLock.Unlock() + + if stagingLockFiles == nil { + stagingLockFiles = make(map[string]*StagingLockFile) + } + + if _, ok := stagingLockFiles[cleanPath]; ok { + return nil, fmt.Errorf("lock %q is used already with other thread", cleanPath) + } + + fd, err := rawfilelock.OpenLock(cleanPath, false) + if err != nil { + return nil, err + } + + if err = rawfilelock.TryLockFile(fd, rawfilelock.WriteLock); err != nil { + // Lock acquisition failed, but holding stagingLockFileLock ensures + // no other goroutine in this process could have obtained a lock for this file, + // so closing it is still safe. + rawfilelock.CloseHandle(fd) + return nil, fmt.Errorf("failed to acquire lock on %q: %w", cleanPath, err) + } + + lockFile := &StagingLockFile{ + file: cleanPath, + fd: fd, + } + + stagingLockFiles[cleanPath] = lockFile + return lockFile, nil +} + +// UnlockAndDelete releases the lock, removes the associated file from the filesystem. +// +// WARNING: After this operation, the StagingLockFile becomes invalid for further use. +func (l *StagingLockFile) UnlockAndDelete() error { + stagingLockFileLock.Lock() + defer stagingLockFileLock.Unlock() + + if l.file == "" { + // Panic when unlocking an unlocked lock. That's a violation + // of the lock semantics and will reveal such. + panic("calling Unlock on unlocked lock") + } + + defer func() { + // It’s important that this happens while we are still holding stagingLockFileLock, to ensure + // that no other goroutine has l.file open = that this close is not unlocking the lock under any + // other goroutine. (defer ordering is LIFO, so this will happen before we release the stagingLockFileLock) + rawfilelock.UnlockAndCloseHandle(l.fd) + delete(stagingLockFiles, l.file) + l.file = "" + }() + if err := os.Remove(l.file); err != nil && !os.IsNotExist(err) { + return err + } + return nil +} + +// CreateAndLock creates a new temporary file in the specified directory with the given pattern, +// then creates and locks a StagingLockFile for it. The file is created using os.CreateTemp. +// Typically, the caller would use the returned lock file path to derive a path to the lock-controlled resource +// (e.g. by replacing the "pattern" part of the returned file name with a different prefix) +// Caller MUST call UnlockAndDelete() on the returned StagingLockFile to release the lock and delete the file. +// +// Returns: +// - The locked StagingLockFile +// - The name of created lock file +// - Any error that occurred during the process +// +// If the file cannot be locked, this function will retry up to maxRetries times before failing. +func CreateAndLock(dir string, pattern string) (*StagingLockFile, string, error) { + for try := 0; ; try++ { + file, err := os.CreateTemp(dir, pattern) + if err != nil { + return nil, "", err + } + file.Close() + + path := file.Name() + l, err := tryAcquireLockForFile(path) + if err != nil { + if try < maxRetries { + continue // Retry if the lock cannot be acquired + } + return nil, "", fmt.Errorf( + "failed to allocate lock in %q after %d attempts; last failure on %q: %w", + dir, try, filepath.Base(path), err, + ) + } + + return l, filepath.Base(path), nil + } +} + +// TryLockPath attempts to acquire a lock on an specific path. If the file does not exist, +// it will be created. +// +// Warning: If acquiring a lock is successful, it returns a new StagingLockFile +// instance for the file. Caller MUST call UnlockAndDelete() on the returned StagingLockFile +// to release the lock and delete the file. +func TryLockPath(path string) (*StagingLockFile, error) { + return tryAcquireLockForFile(path) +} diff --git a/vendor/github.com/containers/storage/internal/tempdir/tempdir.go b/vendor/github.com/containers/storage/internal/tempdir/tempdir.go new file mode 100644 index 000000000..bb6d35616 --- /dev/null +++ b/vendor/github.com/containers/storage/internal/tempdir/tempdir.go @@ -0,0 +1,243 @@ +package tempdir + +import ( + "errors" + "fmt" + "os" + "path/filepath" + "strings" + + "github.com/containers/storage/internal/staging_lockfile" + "github.com/sirupsen/logrus" +) + +/* +Locking rules and invariants for TempDir and its recovery mechanism: + +1. TempDir Instance Locks: + - Path: 'RootDir/lock-XYZ' (in the root directory) + - Each TempDir instance creates and holds an exclusive lock on this file immediately + during NewTempDir() initialization. + - This lock signifies that the temporary directory is in active use by the + process/goroutine that holds the TempDir object. + +2. Stale Directory Recovery (separate operation): + - RecoverStaleDirs() can be called independently to identify and clean up stale + temporary directories. + - For each potential stale directory (found by listPotentialStaleDirs), it + attempts to TryLockPath() its instance lock file. + - If TryLockPath() succeeds: The directory is considered stale, and both the + directory and lock file are removed. + - If TryLockPath() fails: The directory is considered in active use by another + process/goroutine, and it's skipped. + +3. TempDir Usage: + - NewTempDir() immediately creates both the instance lock and the temporary directory. + - TempDir.StageDeletion() moves files into the existing temporary directory with counter-based naming. + - Files moved into the temporary directory are renamed with a counter-based prefix + to ensure uniqueness (e.g., "0-filename", "1-filename"). + - Once cleaned up, the TempDir instance cannot be reused - StageDeletion() will return an error. + +4. Cleanup Process: + - TempDir.Cleanup() removes both the temporary directory and its lock file. + - The instance lock is unlocked and deleted after cleanup operations are complete. + - The TempDir instance becomes inactive after cleanup (internal fields are reset). + - The TempDir instance cannot be reused after Cleanup() - StageDeletion() will fail. + +5. TempDir Lifetime: + - NewTempDir() creates both the TempDir manager and the actual temporary directory immediately. + - The temporary directory is created eagerly during NewTempDir(). + - During its lifetime, the temporary directory is protected by its instance lock. + - The temporary directory exists until Cleanup() is called, which removes both + the directory and its lock file. + - Multiple TempDir instances can coexist in the same RootDir, each with its own + unique subdirectory and lock. + - After cleanup, the TempDir instance cannot be reused. + +6. Example Directory Structure: + + RootDir/ + lock-ABC (instance lock for temp-dir-ABC) + temp-dir-ABC/ + 0-file1 + 1-file3 + lock-XYZ (instance lock for temp-dir-XYZ) + temp-dir-XYZ/ + 0-file2 +*/ +const ( + // tempDirPrefix is the prefix used for creating temporary directories. + tempDirPrefix = "temp-dir-" + // tempdirLockPrefix is the prefix used for creating lock files for temporary directories. + tempdirLockPrefix = "lock-" +) + +// TempDir represents a temporary directory that is created in a specified root directory. +// It manages the lifecycle of the temporary directory, including creation, locking, and cleanup. +// Each TempDir instance is associated with a unique subdirectory in the root directory. +// Warning: The TempDir instance should be used in a single goroutine. +type TempDir struct { + RootDir string + + tempDirPath string + // tempDirLock is a lock file (e.g., RootDir/lock-XYZ) specific to this + // TempDir instance, indicating it's in active use. + tempDirLock *staging_lockfile.StagingLockFile + tempDirLockPath string + + // counter is used to generate unique filenames for added files. + counter uint64 +} + +// CleanupTempDirFunc is a function type that can be returned by operations +// which need to perform cleanup actions later. +type CleanupTempDirFunc func() error + +// listPotentialStaleDirs scans the RootDir for directories that might be stale temporary directories. +// It identifies directories with the tempDirPrefix and their corresponding lock files with the tempdirLockPrefix. +// The function returns a map of IDs that correspond to both directories and lock files found. +// These IDs are extracted from the filenames by removing their respective prefixes. +func listPotentialStaleDirs(rootDir string) (map[string]struct{}, error) { + ids := make(map[string]struct{}) + + dirContent, err := os.ReadDir(rootDir) + if err != nil { + if os.IsNotExist(err) { + return nil, nil + } + return nil, fmt.Errorf("error reading temp dir %s: %w", rootDir, err) + } + + for _, entry := range dirContent { + if id, ok := strings.CutPrefix(entry.Name(), tempDirPrefix); ok { + ids[id] = struct{}{} + continue + } + + if id, ok := strings.CutPrefix(entry.Name(), tempdirLockPrefix); ok { + ids[id] = struct{}{} + } + } + return ids, nil +} + +// RecoverStaleDirs identifies and removes stale temporary directories in the root directory. +// A directory is considered stale if its lock file can be acquired (indicating no active use). +// The function attempts to remove both the directory and its lock file. +// If a directory's lock cannot be acquired, it is considered in use and is skipped. +func RecoverStaleDirs(rootDir string) error { + potentialStaleDirs, err := listPotentialStaleDirs(rootDir) + if err != nil { + return fmt.Errorf("error listing potential stale temp dirs in %s: %w", rootDir, err) + } + + if len(potentialStaleDirs) == 0 { + return nil + } + + var recoveryErrors []error + + for id := range potentialStaleDirs { + lockPath := filepath.Join(rootDir, tempdirLockPrefix+id) + tempDirPath := filepath.Join(rootDir, tempDirPrefix+id) + + // Try to lock the lock file. If it can be locked, the directory is stale. + instanceLock, err := staging_lockfile.TryLockPath(lockPath) + if err != nil { + continue + } + + if rmErr := os.RemoveAll(tempDirPath); rmErr != nil && !os.IsNotExist(rmErr) { + recoveryErrors = append(recoveryErrors, fmt.Errorf("error removing stale temp dir %s: %w", tempDirPath, rmErr)) + } + if unlockErr := instanceLock.UnlockAndDelete(); unlockErr != nil { + recoveryErrors = append(recoveryErrors, fmt.Errorf("error unlocking and deleting stale lock file %s: %w", lockPath, unlockErr)) + } + } + + return errors.Join(recoveryErrors...) +} + +// NewTempDir creates a TempDir and immediately creates both the temporary directory +// and its corresponding lock file in the specified RootDir. +// The RootDir itself will be created if it doesn't exist. +// Note: The caller MUST ensure that returned TempDir instance is cleaned up with .Cleanup(). +func NewTempDir(rootDir string) (*TempDir, error) { + if err := os.MkdirAll(rootDir, 0o700); err != nil { + return nil, fmt.Errorf("creating root temp directory %s failed: %w", rootDir, err) + } + + td := &TempDir{ + RootDir: rootDir, + } + tempDirLock, tempDirLockFileName, err := staging_lockfile.CreateAndLock(td.RootDir, tempdirLockPrefix) + if err != nil { + return nil, fmt.Errorf("creating and locking temp dir instance lock in %s failed: %w", td.RootDir, err) + } + td.tempDirLock = tempDirLock + td.tempDirLockPath = filepath.Join(td.RootDir, tempDirLockFileName) + + // Create the temporary directory that corresponds to the lock file + id := strings.TrimPrefix(tempDirLockFileName, tempdirLockPrefix) + actualTempDirPath := filepath.Join(td.RootDir, tempDirPrefix+id) + if err := os.MkdirAll(actualTempDirPath, 0o700); err != nil { + return nil, fmt.Errorf("creating temp directory %s failed: %w", actualTempDirPath, err) + } + td.tempDirPath = actualTempDirPath + td.counter = 0 + return td, nil +} + +// StageDeletion moves the specified file into the instance's temporary directory. +// The temporary directory must already exist (created during NewTempDir). +// Files are renamed with a counter-based prefix (e.g., "0-filename", "1-filename") to ensure uniqueness. +// Note: 'path' must be on the same filesystem as the TempDir for os.Rename to work. +// The caller MUST ensure .Cleanup() is called. +// If the TempDir has been cleaned up, this method will return an error. +func (td *TempDir) StageDeletion(path string) error { + if td.tempDirLock == nil { + return fmt.Errorf("temp dir instance not initialized or already cleaned up") + } + fileName := fmt.Sprintf("%d-", td.counter) + filepath.Base(path) + destPath := filepath.Join(td.tempDirPath, fileName) + td.counter++ + return os.Rename(path, destPath) +} + +// Cleanup removes the temporary directory and releases its instance lock. +// After cleanup, the TempDir instance becomes inactive and cannot be reused. +// Subsequent calls to StageDeletion() will fail. +// Multiple calls to Cleanup() are safe and will not return an error. +// Callers should typically defer Cleanup() to run after any application-level +// global locks are released to avoid holding those locks during potentially +// slow disk I/O. +func (td *TempDir) Cleanup() error { + if td.tempDirLock == nil { + logrus.Debug("Temp dir already cleaned up") + return nil + } + + if err := os.RemoveAll(td.tempDirPath); err != nil && !os.IsNotExist(err) { + return fmt.Errorf("removing temp dir %s failed: %w", td.tempDirPath, err) + } + + lock := td.tempDirLock + td.tempDirPath = "" + td.tempDirLock = nil + td.tempDirLockPath = "" + return lock.UnlockAndDelete() +} + +// CleanupTemporaryDirectories cleans up multiple temporary directories by calling their cleanup functions. +func CleanupTemporaryDirectories(cleanFuncs ...CleanupTempDirFunc) error { + var cleanupErrors []error + for _, cleanupFunc := range cleanFuncs { + if cleanupFunc == nil { + continue + } + if err := cleanupFunc(); err != nil { + cleanupErrors = append(cleanupErrors, err) + } + } + return errors.Join(cleanupErrors...) +} diff --git a/vendor/github.com/containers/storage/layers.go b/vendor/github.com/containers/storage/layers.go index e01edaec0..4d9e0b882 100644 --- a/vendor/github.com/containers/storage/layers.go +++ b/vendor/github.com/containers/storage/layers.go @@ -18,6 +18,7 @@ import ( "time" drivers "github.com/containers/storage/drivers" + "github.com/containers/storage/internal/tempdir" "github.com/containers/storage/pkg/archive" "github.com/containers/storage/pkg/idtools" "github.com/containers/storage/pkg/ioutils" @@ -38,6 +39,8 @@ import ( const ( tarSplitSuffix = ".tar-split.gz" + // tempDirPath is the subdirectory name used for storing temporary directories during layer deletion + tempDirPath = "tmp" incompleteFlag = "incomplete" // maxLayerStoreCleanupIterations is the number of times we try to clean up inconsistent layer store state // in readers (which, for implementation reasons, gives other writers the opportunity to create more inconsistent state) @@ -290,8 +293,14 @@ type rwLayerStore interface { // updateNames modifies names associated with a layer based on (op, names). updateNames(id string, names []string, op updateNameOperation) error - // Delete deletes a layer with the specified name or ID. - Delete(id string) error + // deleteWhileHoldingLock deletes a layer with the specified name or ID. + deleteWhileHoldingLock(id string) error + + // deferredDelete deletes a layer with the specified name or ID. + // This removal happen immediately (the layer is no longer usable), + // but physically deleting the files may be deferred. + // Caller MUST call all returned cleanup functions outside of the locks. + deferredDelete(id string) ([]tempdir.CleanupTempDirFunc, error) // Wipe deletes all layers. Wipe() error @@ -794,6 +803,17 @@ func (r *layerStore) load(lockedForWriting bool) (bool, error) { layers := []*Layer{} ids := make(map[string]*Layer) + if r.lockfile.IsReadWrite() { + if err := tempdir.RecoverStaleDirs(filepath.Join(r.layerdir, tempDirPath)); err != nil { + return false, err + } + for _, driverTempDirPath := range r.driver.GetTempDirRootDirs() { + if err := tempdir.RecoverStaleDirs(driverTempDirPath); err != nil { + return false, err + } + } + } + for locationIndex := range numLayerLocationIndex { location := layerLocationFromIndex(locationIndex) rpath := r.jsonPath[locationIndex] @@ -935,7 +955,12 @@ func (r *layerStore) load(lockedForWriting bool) (bool, error) { // Now actually delete the layers for _, layer := range layersToDelete { logrus.Warnf("Found incomplete layer %q, deleting it", layer.ID) - err := r.deleteInternal(layer.ID) + cleanFunctions, err := r.internalDelete(layer.ID) + defer func() { + if err := tempdir.CleanupTemporaryDirectories(cleanFunctions...); err != nil { + logrus.Errorf("Error cleaning up temporary directories: %v", err) + } + }() if err != nil { // Don't return the error immediately, because deleteInternal does not saveLayers(); // Even if deleting one incomplete layer fails, call saveLayers() so that other possible successfully @@ -1334,7 +1359,7 @@ func (r *layerStore) PutAdditionalLayer(id string, parentLayer *Layer, names []s r.bytocsum[layer.TOCDigest] = append(r.bytocsum[layer.TOCDigest], layer.ID) } if err := r.saveFor(layer); err != nil { - if e := r.Delete(layer.ID); e != nil { + if e := r.deleteWhileHoldingLock(layer.ID); e != nil { logrus.Errorf("While recovering from a failure to save layers, error deleting layer %#v: %v", id, e) } return nil, err @@ -1469,7 +1494,7 @@ func (r *layerStore) create(id string, parentLayer *Layer, names []string, mount if cleanupFailureContext == "" { cleanupFailureContext = "unknown: cleanupFailureContext not set at the failure site" } - if e := r.Delete(id); e != nil { + if e := r.deleteWhileHoldingLock(id); e != nil { logrus.Errorf("While recovering from a failure (%s), error deleting layer %#v: %v", cleanupFailureContext, id, e) } } @@ -1634,7 +1659,7 @@ func (r *layerStore) Mount(id string, options drivers.MountOpts) (string, error) options.MountLabel = layer.MountLabel } - if (options.UidMaps != nil || options.GidMaps != nil) && !r.driver.SupportsShifting() { + if (options.UidMaps != nil || options.GidMaps != nil) && !r.driver.SupportsShifting(options.UidMaps, options.GidMaps) { if !reflect.DeepEqual(options.UidMaps, layer.UIDMap) || !reflect.DeepEqual(options.GidMaps, layer.GIDMap) { return "", fmt.Errorf("cannot mount layer %v: shifting not enabled", layer.ID) } @@ -1920,13 +1945,15 @@ func layerHasIncompleteFlag(layer *Layer) bool { } // Requires startWriting. -func (r *layerStore) deleteInternal(id string) error { +// Caller MUST run all returned cleanup functions after this, EVEN IF the function returns an error. +// Ideally outside of the startWriting. +func (r *layerStore) internalDelete(id string) ([]tempdir.CleanupTempDirFunc, error) { if !r.lockfile.IsReadWrite() { - return fmt.Errorf("not allowed to delete layers at %q: %w", r.layerdir, ErrStoreIsReadOnly) + return nil, fmt.Errorf("not allowed to delete layers at %q: %w", r.layerdir, ErrStoreIsReadOnly) } layer, ok := r.lookup(id) if !ok { - return ErrLayerUnknown + return nil, ErrLayerUnknown } // Ensure that if we are interrupted, the layer will be cleaned up. if !layerHasIncompleteFlag(layer) { @@ -1935,16 +1962,30 @@ func (r *layerStore) deleteInternal(id string) error { } layer.Flags[incompleteFlag] = true if err := r.saveFor(layer); err != nil { - return err + return nil, err } } // We never unset incompleteFlag; below, we remove the entire object from r.layers. + tempDirectory, err := tempdir.NewTempDir(filepath.Join(r.layerdir, tempDirPath)) + cleanFunctions := []tempdir.CleanupTempDirFunc{} + cleanFunctions = append(cleanFunctions, tempDirectory.Cleanup) + if err != nil { + return nil, err + } id = layer.ID - if err := r.driver.Remove(id); err != nil && !errors.Is(err, os.ErrNotExist) { - return err + cleanFunc, err := r.driver.DeferredRemove(id) + cleanFunctions = append(cleanFunctions, cleanFunc) + if err != nil && !errors.Is(err, os.ErrNotExist) { + return cleanFunctions, err + } + + cleanFunctions = append(cleanFunctions, tempDirectory.Cleanup) + if err := tempDirectory.StageDeletion(r.tspath(id)); err != nil && !errors.Is(err, os.ErrNotExist) { + return cleanFunctions, err + } + if err := tempDirectory.StageDeletion(r.datadir(id)); err != nil && !errors.Is(err, os.ErrNotExist) { + return cleanFunctions, err } - os.Remove(r.tspath(id)) - os.RemoveAll(r.datadir(id)) delete(r.byid, id) for _, name := range layer.Names { delete(r.byname, name) @@ -1968,7 +2009,7 @@ func (r *layerStore) deleteInternal(id string) error { }) { selinux.ReleaseLabel(mountLabel) } - return nil + return cleanFunctions, nil } // Requires startWriting. @@ -1988,10 +2029,20 @@ func (r *layerStore) deleteInDigestMap(id string) { } // Requires startWriting. -func (r *layerStore) Delete(id string) error { +// This is soft-deprecated and should not have any new callers; use deferredDelete instead. +func (r *layerStore) deleteWhileHoldingLock(id string) error { + cleanupFunctions, deferErr := r.deferredDelete(id) + cleanupErr := tempdir.CleanupTemporaryDirectories(cleanupFunctions...) + return errors.Join(deferErr, cleanupErr) +} + +// Requires startWriting. +// Caller MUST run all returned cleanup functions after this, EVEN IF the function returns an error. +// Ideally outside of the startWriting. +func (r *layerStore) deferredDelete(id string) ([]tempdir.CleanupTempDirFunc, error) { layer, ok := r.lookup(id) if !ok { - return ErrLayerUnknown + return nil, ErrLayerUnknown } id = layer.ID // The layer may already have been explicitly unmounted, but if not, we @@ -2003,13 +2054,14 @@ func (r *layerStore) Delete(id string) error { break } if err != nil { - return err + return nil, err } } - if err := r.deleteInternal(id); err != nil { - return err + cleanFunctions, err := r.internalDelete(id) + if err != nil { + return cleanFunctions, err } - return r.saveFor(layer) + return cleanFunctions, r.saveFor(layer) } // Requires startReading or startWriting. @@ -2039,7 +2091,7 @@ func (r *layerStore) Wipe() error { return r.byid[ids[i]].Created.After(r.byid[ids[j]].Created) }) for _, id := range ids { - if err := r.Delete(id); err != nil { + if err := r.deleteWhileHoldingLock(id); err != nil { return err } } @@ -2550,10 +2602,14 @@ func (r *layerStore) applyDiffFromStagingDirectory(id string, diffOutput *driver if err != nil { compressor = pgzip.NewWriter(&tsdata) } + if _, err := diffOutput.TarSplit.Seek(0, io.SeekStart); err != nil { + return err + } + if err := compressor.SetConcurrency(1024*1024, 1); err != nil { // 1024*1024 is the hard-coded default; we're not changing that logrus.Infof("setting compression concurrency threads to 1: %v; ignoring", err) } - if _, err := compressor.Write(diffOutput.TarSplit); err != nil { + if _, err := diffOutput.TarSplit.WriteTo(compressor); err != nil { compressor.Close() return err } @@ -2567,7 +2623,7 @@ func (r *layerStore) applyDiffFromStagingDirectory(id string, diffOutput *driver } for k, v := range diffOutput.BigData { if err := r.SetBigData(id, k, bytes.NewReader(v)); err != nil { - if err2 := r.Delete(id); err2 != nil { + if err2 := r.deleteWhileHoldingLock(id); err2 != nil { logrus.Errorf("While recovering from a failure to set big data, error deleting layer %#v: %v", id, err2) } return err diff --git a/vendor/github.com/containers/storage/pkg/archive/archive.go b/vendor/github.com/containers/storage/pkg/archive/archive.go index aee06d71c..a66d2b891 100644 --- a/vendor/github.com/containers/storage/pkg/archive/archive.go +++ b/vendor/github.com/containers/storage/pkg/archive/archive.go @@ -528,11 +528,29 @@ func canonicalTarName(name string, isDir bool) (string, error) { return name, nil } -// addFile adds a file from `path` as `name` to the tar archive. -func (ta *tarWriter) addFile(path, name string) error { +type addFileData struct { + // The path from which to read contents. + path string + + // os.Stat for the above. + fi os.FileInfo + + // The file header of the above. + hdr *tar.Header + + // if present, an extra whiteout entry to write after the header. + extraWhiteout *tar.Header +} + +// prepareAddFile generates the tar file header(s) for adding a file +// from path as name to the tar archive, without writing to the +// tar stream. Thus, any error may be ignored without corrupting the +// tar file. A (nil, nil) return means that the file should be +// ignored for non-error reasons. +func (ta *tarWriter) prepareAddFile(path, name string) (*addFileData, error) { fi, err := os.Lstat(path) if err != nil { - return err + return nil, err } var link string @@ -540,26 +558,26 @@ func (ta *tarWriter) addFile(path, name string) error { var err error link, err = os.Readlink(path) if err != nil { - return err + return nil, err } } if fi.Mode()&os.ModeSocket != 0 { logrus.Infof("archive: skipping %q since it is a socket", path) - return nil + return nil, nil } hdr, err := FileInfoHeader(name, fi, link) if err != nil { - return err + return nil, err } if err := readSecurityXattrToTarHeader(path, hdr); err != nil { - return err + return nil, err } if err := readUserXattrToTarHeader(path, hdr); err != nil { - return err + return nil, err } if err := ReadFileFlagsToTarHeader(path, hdr); err != nil { - return err + return nil, err } if ta.CopyPass { copyPassHeader(hdr) @@ -568,18 +586,13 @@ func (ta *tarWriter) addFile(path, name string) error { // if it's not a directory and has more than 1 link, // it's hard linked, so set the type flag accordingly if !fi.IsDir() && hasHardlinks(fi) { - inode, err := getInodeFromStat(fi.Sys()) - if err != nil { - return err - } + inode := getInodeFromStat(fi.Sys()) // a link should have a name that it links too // and that linked name should be first in the tar archive if oldpath, ok := ta.SeenFiles[inode]; ok { hdr.Typeflag = tar.TypeLink hdr.Linkname = oldpath - hdr.Size = 0 // This Must be here for the writer math to add up! - } else { - ta.SeenFiles[inode] = name + hdr.Size = 0 // This must be here for the writer math to add up! } } @@ -589,11 +602,11 @@ func (ta *tarWriter) addFile(path, name string) error { if !strings.HasPrefix(filepath.Base(hdr.Name), WhiteoutPrefix) && !ta.IDMappings.Empty() { fileIDPair, err := getFileUIDGID(fi.Sys()) if err != nil { - return err + return nil, err } hdr.Uid, hdr.Gid, err = ta.IDMappings.ToContainer(fileIDPair) if err != nil { - return err + return nil, err } } @@ -616,26 +629,48 @@ func (ta *tarWriter) addFile(path, name string) error { maybeTruncateHeaderModTime(hdr) + result := &addFileData{ + path: path, + hdr: hdr, + fi: fi, + } if ta.WhiteoutConverter != nil { - wo, err := ta.WhiteoutConverter.ConvertWrite(hdr, path, fi) + // The WhiteoutConverter suggests a generic mechanism, + // but this code is only used to convert between + // overlayfs (on-disk) and AUFS (in the tar file) + // whiteouts, and is initiated because the overlayfs + // storage driver returns OverlayWhiteoutFormat from + // Driver.getWhiteoutFormat(). + // + // For AUFS, a directory with all its contents deleted + // should be represented as a directory containing a + // magic whiteout empty regular file, hence the + // extraWhiteout header returned here. + result.extraWhiteout, err = ta.WhiteoutConverter.ConvertWrite(hdr, path, fi) if err != nil { - return err + return nil, err } + } - // If a new whiteout file exists, write original hdr, then - // replace hdr with wo to be written after. Whiteouts should - // always be written after the original. Note the original - // hdr may have been updated to be a whiteout with returning - // a whiteout header - if wo != nil { - if err := ta.TarWriter.WriteHeader(hdr); err != nil { - return err - } - if hdr.Typeflag == tar.TypeReg && hdr.Size > 0 { - return fmt.Errorf("tar: cannot use whiteout for non-empty file") - } - hdr = wo + return result, nil +} + +// addFile performs the write. An error here corrupts the tar file. +func (ta *tarWriter) addFile(headers *addFileData) error { + hdr := headers.hdr + if headers.extraWhiteout != nil { + if hdr.Typeflag == tar.TypeReg && hdr.Size > 0 { + // If we write hdr with hdr.Size > 0, we have + // to write the body before we can write the + // extraWhiteout header. This can only happen + // if the contract for WhiteoutConverter is + // not honored, so bail out. + return fmt.Errorf("tar: cannot use extra whiteout with non-empty file %s", hdr.Name) + } + if err := ta.TarWriter.WriteHeader(hdr); err != nil { + return err } + hdr = headers.extraWhiteout } if err := ta.TarWriter.WriteHeader(hdr); err != nil { @@ -643,7 +678,7 @@ func (ta *tarWriter) addFile(path, name string) error { } if hdr.Typeflag == tar.TypeReg && hdr.Size > 0 { - file, err := os.Open(path) + file, err := os.Open(headers.path) if err != nil { return err } @@ -661,6 +696,13 @@ func (ta *tarWriter) addFile(path, name string) error { } } + if !headers.fi.IsDir() && hasHardlinks(headers.fi) { + ino := getInodeFromStat(headers.fi.Sys()) + if _, seen := ta.SeenFiles[ino]; !seen { + ta.SeenFiles[ino] = headers.hdr.Name + } + } + return nil } @@ -853,184 +895,189 @@ func extractTarFileEntry(path, extractDir string, hdr *tar.Header, reader io.Rea } // Tar creates an archive from the directory at `path`, and returns it as a -// stream of bytes. +// stream of bytes. This is a convenience wrapper for [TarWithOptions]. func Tar(path string, compression Compression) (io.ReadCloser, error) { return TarWithOptions(path, &TarOptions{Compression: compression}) } -// TarWithOptions creates an archive from the directory at `path`, only including files whose relative -// paths are included in `options.IncludeFiles` (if non-nil) or not in `options.ExcludePatterns`. -func TarWithOptions(srcPath string, options *TarOptions) (io.ReadCloser, error) { - tarWithOptionsTo := func(dest io.WriteCloser, srcPath string, options *TarOptions) (result error) { - // Fix the source path to work with long path names. This is a no-op - // on platforms other than Windows. - srcPath = fixVolumePathPrefix(srcPath) - defer func() { - if err := dest.Close(); err != nil && result == nil { - result = err - } - }() - - pm, err := fileutils.NewPatternMatcher(options.ExcludePatterns) - if err != nil { - return err +func tarWithOptionsTo(dest io.WriteCloser, srcPath string, options *TarOptions) (result error) { + // Fix the source path to work with long path names. This is a no-op + // on platforms other than Windows. + srcPath = fixVolumePathPrefix(srcPath) + defer func() { + if err := dest.Close(); err != nil && result == nil { + result = err } + }() - compressWriter, err := CompressStream(dest, options.Compression) - if err != nil { - return err - } + pm, err := fileutils.NewPatternMatcher(options.ExcludePatterns) + if err != nil { + return err + } - ta := newTarWriter( - idtools.NewIDMappingsFromMaps(options.UIDMaps, options.GIDMaps), - compressWriter, - options.ChownOpts, - options.Timestamp, - ) - ta.WhiteoutConverter = GetWhiteoutConverter(options.WhiteoutFormat, options.WhiteoutData) - ta.CopyPass = options.CopyPass + compressWriter, err := CompressStream(dest, options.Compression) + if err != nil { + return err + } - includeFiles := options.IncludeFiles - defer func() { - if err := compressWriter.Close(); err != nil && result == nil { - result = err - } - }() + ta := newTarWriter( + idtools.NewIDMappingsFromMaps(options.UIDMaps, options.GIDMaps), + compressWriter, + options.ChownOpts, + options.Timestamp, + ) + ta.WhiteoutConverter = GetWhiteoutConverter(options.WhiteoutFormat, options.WhiteoutData) + ta.CopyPass = options.CopyPass - // this buffer is needed for the duration of this piped stream - defer pools.BufioWriter32KPool.Put(ta.Buffer) + includeFiles := options.IncludeFiles + defer func() { + if err := compressWriter.Close(); err != nil && result == nil { + result = err + } + }() - // In general we log errors here but ignore them because - // during e.g. a diff operation the container can continue - // mutating the filesystem and we can see transient errors - // from this + // this buffer is needed for the duration of this piped stream + defer pools.BufioWriter32KPool.Put(ta.Buffer) - stat, err := os.Lstat(srcPath) - if err != nil { - return err - } + // In general we log errors here but ignore them because + // during e.g. a diff operation the container can continue + // mutating the filesystem and we can see transient errors + // from this - if !stat.IsDir() { - // We can't later join a non-dir with any includes because the - // 'walk' will error if "file/." is stat-ed and "file" is not a - // directory. So, we must split the source path and use the - // basename as the include. - if len(includeFiles) > 0 { - logrus.Warn("Tar: Can't archive a file with includes") - } + stat, err := os.Lstat(srcPath) + if err != nil { + return err + } - dir, base := SplitPathDirEntry(srcPath) - srcPath = dir - includeFiles = []string{base} + if !stat.IsDir() { + // We can't later join a non-dir with any includes because the + // 'walk' will error if "file/." is stat-ed and "file" is not a + // directory. So, we must split the source path and use the + // basename as the include. + if len(includeFiles) > 0 { + logrus.Warn("Tar: Can't archive a file with includes") } - if len(includeFiles) == 0 { - includeFiles = []string{"."} - } + dir, base := SplitPathDirEntry(srcPath) + srcPath = dir + includeFiles = []string{base} + } - seen := make(map[string]bool) + if len(includeFiles) == 0 { + includeFiles = []string{"."} + } - for _, include := range includeFiles { - rebaseName := options.RebaseNames[include] + seen := make(map[string]bool) - walkRoot := getWalkRoot(srcPath, include) - if err := filepath.WalkDir(walkRoot, func(filePath string, d fs.DirEntry, err error) error { - if err != nil { - logrus.Errorf("Tar: Can't stat file %s to tar: %s", srcPath, err) - return nil - } + for _, include := range includeFiles { + rebaseName := options.RebaseNames[include] - relFilePath, err := filepath.Rel(srcPath, filePath) - if err != nil || (!options.IncludeSourceDir && relFilePath == "." && d.IsDir()) { - // Error getting relative path OR we are looking - // at the source directory path. Skip in both situations. - return nil //nolint: nilerr - } + walkRoot := getWalkRoot(srcPath, include) + if err := filepath.WalkDir(walkRoot, func(filePath string, d fs.DirEntry, err error) error { + if err != nil { + logrus.Errorf("Tar: Can't stat file %s to tar: %s", srcPath, err) + return nil + } - if options.IncludeSourceDir && include == "." && relFilePath != "." { - relFilePath = strings.Join([]string{".", relFilePath}, string(filepath.Separator)) - } + relFilePath, err := filepath.Rel(srcPath, filePath) + if err != nil || (!options.IncludeSourceDir && relFilePath == "." && d.IsDir()) { + // Error getting relative path OR we are looking + // at the source directory path. Skip in both situations. + return nil //nolint: nilerr + } + + if options.IncludeSourceDir && include == "." && relFilePath != "." { + relFilePath = strings.Join([]string{".", relFilePath}, string(filepath.Separator)) + } - skip := false + skip := false - // If "include" is an exact match for the current file - // then even if there's an "excludePatterns" pattern that - // matches it, don't skip it. IOW, assume an explicit 'include' - // is asking for that file no matter what - which is true - // for some files, like .dockerignore and Dockerfile (sometimes) - if include != relFilePath { - matches, err := pm.IsMatch(relFilePath) - if err != nil { - return fmt.Errorf("matching %s: %w", relFilePath, err) - } - skip = matches + // If "include" is an exact match for the current file + // then even if there's an "excludePatterns" pattern that + // matches it, don't skip it. IOW, assume an explicit 'include' + // is asking for that file no matter what - which is true + // for some files, like .dockerignore and Dockerfile (sometimes) + if include != relFilePath { + matches, err := pm.IsMatch(relFilePath) + if err != nil { + return fmt.Errorf("matching %s: %w", relFilePath, err) } + skip = matches + } - if skip { - // If we want to skip this file and its a directory - // then we should first check to see if there's an - // excludes pattern (e.g. !dir/file) that starts with this - // dir. If so then we can't skip this dir. + if skip { + // If we want to skip this file and its a directory + // then we should first check to see if there's an + // excludes pattern (e.g. !dir/file) that starts with this + // dir. If so then we can't skip this dir. - // Its not a dir then so we can just return/skip. - if !d.IsDir() { - return nil - } + // Its not a dir then so we can just return/skip. + if !d.IsDir() { + return nil + } - // No exceptions (!...) in patterns so just skip dir - if !pm.Exclusions() { - return filepath.SkipDir - } + // No exceptions (!...) in patterns so just skip dir + if !pm.Exclusions() { + return filepath.SkipDir + } - dirSlash := relFilePath + string(filepath.Separator) + dirSlash := relFilePath + string(filepath.Separator) - for _, pat := range pm.Patterns() { - if !pat.Exclusion() { - continue - } - if strings.HasPrefix(pat.String()+string(filepath.Separator), dirSlash) { - // found a match - so can't skip this dir - return nil - } + for _, pat := range pm.Patterns() { + if !pat.Exclusion() { + continue + } + if strings.HasPrefix(pat.String()+string(filepath.Separator), dirSlash) { + // found a match - so can't skip this dir + return nil } - - // No matching exclusion dir so just skip dir - return filepath.SkipDir } - if seen[relFilePath] { - return nil - } - seen[relFilePath] = true - - // Rename the base resource. - if rebaseName != "" { - var replacement string - if rebaseName != string(filepath.Separator) { - // Special case the root directory to replace with an - // empty string instead so that we don't end up with - // double slashes in the paths. - replacement = rebaseName - } + // No matching exclusion dir so just skip dir + return filepath.SkipDir + } - relFilePath = strings.Replace(relFilePath, include, replacement, 1) + if seen[relFilePath] { + return nil + } + seen[relFilePath] = true + + // Rename the base resource. + if rebaseName != "" { + var replacement string + if rebaseName != string(filepath.Separator) { + // Special case the root directory to replace with an + // empty string instead so that we don't end up with + // double slashes in the paths. + replacement = rebaseName } - if err := ta.addFile(filePath, relFilePath); err != nil { - logrus.Errorf("Can't add file %s to tar: %s", filePath, err) - // if pipe is broken, stop writing tar stream to it - if err == io.ErrClosedPipe { - return err - } + relFilePath = strings.Replace(relFilePath, include, replacement, 1) + } + + headers, err := ta.prepareAddFile(filePath, relFilePath) + if err != nil { + logrus.Errorf("Can't add file %s to tar: %s; skipping", filePath, err) + } else if headers != nil { + if err := ta.addFile(headers); err != nil { + return err } - return nil - }); err != nil { - return err } + return nil + }); err != nil { + return err } - return ta.TarWriter.Close() } + return ta.TarWriter.Close() +} +// TarWithOptions creates an archive from the directory at `path`, only including files whose relative +// paths are included in `options.IncludeFiles` (if non-nil) or not in `options.ExcludePatterns`. +// +// If used on a file system being modified concurrently, +// TarWithOptions will create a valid tar archive, but may leave out +// some files. +func TarWithOptions(srcPath string, options *TarOptions) (io.ReadCloser, error) { pipeReader, pipeWriter := io.Pipe() go func() { err := tarWithOptionsTo(pipeWriter, srcPath, options) @@ -1446,7 +1493,7 @@ func NewTempArchive(src io.Reader, dir string) (*TempArchive, error) { if _, err := io.Copy(f, src); err != nil { return nil, err } - if _, err := f.Seek(0, 0); err != nil { + if _, err := f.Seek(0, io.SeekStart); err != nil { return nil, err } st, err := f.Stat() diff --git a/vendor/github.com/containers/storage/pkg/archive/archive_unix.go b/vendor/github.com/containers/storage/pkg/archive/archive_unix.go index 3a02a88c1..d9bcb97ba 100644 --- a/vendor/github.com/containers/storage/pkg/archive/archive_unix.go +++ b/vendor/github.com/containers/storage/pkg/archive/archive_unix.go @@ -82,7 +82,7 @@ func setHeaderForSpecialDevice(hdr *tar.Header, name string, stat any) (err erro return } -func getInodeFromStat(stat any) (inode uint64, err error) { +func getInodeFromStat(stat any) (inode uint64) { s, ok := stat.(*syscall.Stat_t) if ok { diff --git a/vendor/github.com/containers/storage/pkg/archive/archive_windows.go b/vendor/github.com/containers/storage/pkg/archive/archive_windows.go index 6db31cf4c..e98782869 100644 --- a/vendor/github.com/containers/storage/pkg/archive/archive_windows.go +++ b/vendor/github.com/containers/storage/pkg/archive/archive_windows.go @@ -57,7 +57,7 @@ func setHeaderForSpecialDevice(hdr *tar.Header, name string, stat interface{}) ( return } -func getInodeFromStat(stat interface{}) (inode uint64, err error) { +func getInodeFromStat(stat interface{}) (inode uint64) { // do nothing. no notion of Inode in stat on Windows return } diff --git a/vendor/github.com/containers/storage/pkg/archive/changes.go b/vendor/github.com/containers/storage/pkg/archive/changes.go index a5847cca5..76edac85d 100644 --- a/vendor/github.com/containers/storage/pkg/archive/changes.go +++ b/vendor/github.com/containers/storage/pkg/archive/changes.go @@ -481,8 +481,14 @@ func ExportChanges(dir string, changes []Change, uidMaps, gidMaps []idtools.IDMa } } else { path := filepath.Join(dir, change.Path) - if err := ta.addFile(path, change.Path[1:]); err != nil { + headers, err := ta.prepareAddFile(path, change.Path[1:]) + if err != nil { logrus.Debugf("Can't add file %s to tar: %s", path, err) + } else if headers != nil { + if err := ta.addFile(headers); err != nil { + writer.CloseWithError(err) + return + } } } } diff --git a/vendor/github.com/containers/storage/pkg/chunked/compression_linux.go b/vendor/github.com/containers/storage/pkg/chunked/compression_linux.go index 62dd22dfb..ddd7ff53b 100644 --- a/vendor/github.com/containers/storage/pkg/chunked/compression_linux.go +++ b/vendor/github.com/containers/storage/pkg/chunked/compression_linux.go @@ -7,6 +7,7 @@ import ( "fmt" "io" "maps" + "os" "slices" "strconv" "time" @@ -18,6 +19,7 @@ import ( "github.com/vbatts/tar-split/archive/tar" "github.com/vbatts/tar-split/tar/asm" "github.com/vbatts/tar-split/tar/storage" + "golang.org/x/sys/unix" ) const ( @@ -157,10 +159,36 @@ func readEstargzChunkedManifest(blobStream ImageSourceSeekable, blobSize int64, return manifestUncompressed, tocOffset, nil } +func openTmpFile(tmpDir string) (*os.File, error) { + file, err := os.OpenFile(tmpDir, unix.O_TMPFILE|unix.O_RDWR|unix.O_CLOEXEC|unix.O_EXCL, 0o600) + if err == nil { + return file, nil + } + return openTmpFileNoTmpFile(tmpDir) +} + +// openTmpFileNoTmpFile is a fallback used by openTmpFile when the underlying file system does not +// support O_TMPFILE. +func openTmpFileNoTmpFile(tmpDir string) (*os.File, error) { + file, err := os.CreateTemp(tmpDir, ".tmpfile") + if err != nil { + return nil, err + } + // Unlink the file immediately so that only the open fd refers to it. + _ = os.Remove(file.Name()) + return file, nil +} + // readZstdChunkedManifest reads the zstd:chunked manifest from the seekable stream blobStream. -// Returns (manifest blob, parsed manifest, tar-split blob or nil, manifest offset). +// tmpDir is a directory where the tar-split temporary file is written to. The file is opened with +// O_TMPFILE so that it is automatically removed when it is closed. +// Returns (manifest blob, parsed manifest, tar-split file or nil, manifest offset). +// The opened tar-split file’s position is unspecified. // It may return an error matching ErrFallbackToOrdinaryLayerDownload / errFallbackCanConvert. -func readZstdChunkedManifest(blobStream ImageSourceSeekable, tocDigest digest.Digest, annotations map[string]string) (_ []byte, _ *minimal.TOC, _ []byte, _ int64, retErr error) { +// The compressed parameter indicates whether the manifest and tar-split data are zstd-compressed +// (true) or stored uncompressed (false). Uncompressed data is used only for an optimization to convert +// a regular OCI layer to zstd:chunked when convert_images is set, and it is not used for distributed images. +func readZstdChunkedManifest(tmpDir string, blobStream ImageSourceSeekable, tocDigest digest.Digest, annotations map[string]string, compressed bool) (_ []byte, _ *minimal.TOC, _ *os.File, _ int64, retErr error) { offsetMetadata := annotations[minimal.ManifestInfoKey] if offsetMetadata == "" { return nil, nil, nil, 0, fmt.Errorf("%q annotation missing", minimal.ManifestInfoKey) @@ -236,7 +264,7 @@ func readZstdChunkedManifest(blobStream ImageSourceSeekable, tocDigest digest.Di return nil, nil, nil, 0, err } - decodedBlob, err := decodeAndValidateBlob(manifest, manifestLengthUncompressed, tocDigest.String()) + decodedBlob, err := decodeAndValidateBlob(manifest, manifestLengthUncompressed, tocDigest.String(), compressed) if err != nil { return nil, nil, nil, 0, fmt.Errorf("validating and decompressing TOC: %w", err) } @@ -245,7 +273,7 @@ func readZstdChunkedManifest(blobStream ImageSourceSeekable, tocDigest digest.Di return nil, nil, nil, 0, fmt.Errorf("unmarshaling TOC: %w", err) } - var decodedTarSplit []byte = nil + var decodedTarSplit *os.File if toc.TarSplitDigest != "" { if tarSplitChunk.Offset <= 0 { return nil, nil, nil, 0, fmt.Errorf("TOC requires a tar-split, but the %s annotation does not describe a position", minimal.TarSplitInfoKey) @@ -254,8 +282,16 @@ func readZstdChunkedManifest(blobStream ImageSourceSeekable, tocDigest digest.Di if err != nil { return nil, nil, nil, 0, err } - decodedTarSplit, err = decodeAndValidateBlob(tarSplit, tarSplitLengthUncompressed, toc.TarSplitDigest.String()) + decodedTarSplit, err = openTmpFile(tmpDir) if err != nil { + return nil, nil, nil, 0, err + } + defer func() { + if retErr != nil { + decodedTarSplit.Close() + } + }() + if err := decodeAndValidateBlobToStream(tarSplit, decodedTarSplit, toc.TarSplitDigest.String(), compressed); err != nil { return nil, nil, nil, 0, fmt.Errorf("validating and decompressing tar-split: %w", err) } // We use the TOC for creating on-disk files, but the tar-split for creating metadata @@ -274,11 +310,11 @@ func readZstdChunkedManifest(blobStream ImageSourceSeekable, tocDigest digest.Di return nil, nil, nil, 0, err } } - return decodedBlob, toc, decodedTarSplit, int64(manifestChunk.Offset), err + return decodedBlob, toc, decodedTarSplit, int64(manifestChunk.Offset), nil } // ensureTOCMatchesTarSplit validates that toc and tarSplit contain _exactly_ the same entries. -func ensureTOCMatchesTarSplit(toc *minimal.TOC, tarSplit []byte) error { +func ensureTOCMatchesTarSplit(toc *minimal.TOC, tarSplit *os.File) error { pendingFiles := map[string]*minimal.FileMetadata{} // Name -> an entry in toc.Entries for i := range toc.Entries { e := &toc.Entries[i] @@ -290,7 +326,11 @@ func ensureTOCMatchesTarSplit(toc *minimal.TOC, tarSplit []byte) error { } } - unpacker := storage.NewJSONUnpacker(bytes.NewReader(tarSplit)) + if _, err := tarSplit.Seek(0, io.SeekStart); err != nil { + return err + } + + unpacker := storage.NewJSONUnpacker(tarSplit) if err := asm.IterateHeaders(unpacker, func(hdr *tar.Header) error { e, ok := pendingFiles[hdr.Name] if !ok { @@ -320,10 +360,10 @@ func ensureTOCMatchesTarSplit(toc *minimal.TOC, tarSplit []byte) error { } // tarSizeFromTarSplit computes the total tarball size, using only the tarSplit metadata -func tarSizeFromTarSplit(tarSplit []byte) (int64, error) { +func tarSizeFromTarSplit(tarSplit io.Reader) (int64, error) { var res int64 = 0 - unpacker := storage.NewJSONUnpacker(bytes.NewReader(tarSplit)) + unpacker := storage.NewJSONUnpacker(tarSplit) for { entry, err := unpacker.Next() if err != nil { @@ -433,22 +473,33 @@ func ensureFileMetadataAttributesMatch(a, b *minimal.FileMetadata) error { return nil } -func decodeAndValidateBlob(blob []byte, lengthUncompressed uint64, expectedCompressedChecksum string) ([]byte, error) { +func validateBlob(blob []byte, expectedCompressedChecksum string) error { d, err := digest.Parse(expectedCompressedChecksum) if err != nil { - return nil, fmt.Errorf("invalid digest %q: %w", expectedCompressedChecksum, err) + return fmt.Errorf("invalid digest %q: %w", expectedCompressedChecksum, err) } blobDigester := d.Algorithm().Digester() blobChecksum := blobDigester.Hash() if _, err := blobChecksum.Write(blob); err != nil { - return nil, err + return err } if blobDigester.Digest() != d { - return nil, fmt.Errorf("invalid blob checksum, expected checksum %s, got %s", d, blobDigester.Digest()) + return fmt.Errorf("invalid blob checksum, expected checksum %s, got %s", d, blobDigester.Digest()) } + return nil +} - decoder, err := zstd.NewReader(nil) //nolint:contextcheck +func decodeAndValidateBlob(blob []byte, lengthUncompressed uint64, expectedCompressedChecksum string, compressed bool) ([]byte, error) { + if err := validateBlob(blob, expectedCompressedChecksum); err != nil { + return nil, err + } + + if !compressed { + return blob, nil + } + + decoder, err := zstd.NewReader(nil) if err != nil { return nil, err } @@ -457,3 +508,23 @@ func decodeAndValidateBlob(blob []byte, lengthUncompressed uint64, expectedCompr b := make([]byte, 0, lengthUncompressed) return decoder.DecodeAll(blob, b) } + +func decodeAndValidateBlobToStream(blob []byte, w *os.File, expectedCompressedChecksum string, compressed bool) error { + if err := validateBlob(blob, expectedCompressedChecksum); err != nil { + return err + } + + if !compressed { + _, err := w.Write(blob) + return err + } + + decoder, err := zstd.NewReader(bytes.NewReader(blob)) + if err != nil { + return err + } + defer decoder.Close() + + _, err = decoder.WriteTo(w) + return err +} diff --git a/vendor/github.com/containers/storage/pkg/chunked/compressor/compressor.go b/vendor/github.com/containers/storage/pkg/chunked/compressor/compressor.go index 0de063a24..2930723aa 100644 --- a/vendor/github.com/containers/storage/pkg/chunked/compressor/compressor.go +++ b/vendor/github.com/containers/storage/pkg/chunked/compressor/compressor.go @@ -11,7 +11,6 @@ import ( "github.com/containers/storage/pkg/chunked/internal/minimal" "github.com/containers/storage/pkg/ioutils" - "github.com/klauspost/compress/zstd" "github.com/opencontainers/go-digest" "github.com/vbatts/tar-split/archive/tar" "github.com/vbatts/tar-split/tar/asm" @@ -202,15 +201,15 @@ type tarSplitData struct { compressed *bytes.Buffer digester digest.Digester uncompressedCounter *ioutils.WriteCounter - zstd *zstd.Encoder + zstd minimal.ZstdWriter packer storage.Packer } -func newTarSplitData(level int) (*tarSplitData, error) { +func newTarSplitData(createZstdWriter minimal.CreateZstdWriterFunc) (*tarSplitData, error) { compressed := bytes.NewBuffer(nil) digester := digest.Canonical.Digester() - zstdWriter, err := minimal.ZstdWriterWithLevel(io.MultiWriter(compressed, digester.Hash()), level) + zstdWriter, err := createZstdWriter(io.MultiWriter(compressed, digester.Hash())) if err != nil { return nil, err } @@ -227,11 +226,11 @@ func newTarSplitData(level int) (*tarSplitData, error) { }, nil } -func writeZstdChunkedStream(destFile io.Writer, outMetadata map[string]string, reader io.Reader, level int) error { +func writeZstdChunkedStream(destFile io.Writer, outMetadata map[string]string, reader io.Reader, createZstdWriter minimal.CreateZstdWriterFunc) error { // total written so far. Used to retrieve partial offsets in the file dest := ioutils.NewWriteCounter(destFile) - tarSplitData, err := newTarSplitData(level) + tarSplitData, err := newTarSplitData(createZstdWriter) if err != nil { return err } @@ -251,7 +250,7 @@ func writeZstdChunkedStream(destFile io.Writer, outMetadata map[string]string, r buf := make([]byte, 4096) - zstdWriter, err := minimal.ZstdWriterWithLevel(dest, level) + zstdWriter, err := createZstdWriter(dest) if err != nil { return err } @@ -404,18 +403,11 @@ func writeZstdChunkedStream(destFile io.Writer, outMetadata map[string]string, r return err } - if err := zstdWriter.Flush(); err != nil { - zstdWriter.Close() - return err - } if err := zstdWriter.Close(); err != nil { return err } zstdWriter = nil - if err := tarSplitData.zstd.Flush(); err != nil { - return err - } if err := tarSplitData.zstd.Close(); err != nil { return err } @@ -427,7 +419,7 @@ func writeZstdChunkedStream(destFile io.Writer, outMetadata map[string]string, r UncompressedSize: tarSplitData.uncompressedCounter.Count, } - return minimal.WriteZstdChunkedManifest(dest, outMetadata, uint64(dest.Count), &ts, metadata, level) + return minimal.WriteZstdChunkedManifest(dest, outMetadata, uint64(dest.Count), &ts, metadata, createZstdWriter) } type zstdChunkedWriter struct { @@ -454,7 +446,7 @@ func (w zstdChunkedWriter) Write(p []byte) (int, error) { } } -// zstdChunkedWriterWithLevel writes a zstd compressed tarball where each file is +// makeZstdChunkedWriter writes a zstd compressed tarball where each file is // compressed separately so it can be addressed separately. Idea based on CRFS: // https://github.com/google/crfs // The difference with CRFS is that the zstd compression is used instead of gzip. @@ -469,12 +461,12 @@ func (w zstdChunkedWriter) Write(p []byte) (int, error) { // [SKIPPABLE FRAME 1]: [ZSTD SKIPPABLE FRAME, SIZE=MANIFEST LENGTH][MANIFEST] // [SKIPPABLE FRAME 2]: [ZSTD SKIPPABLE FRAME, SIZE=16][MANIFEST_OFFSET][MANIFEST_LENGTH][MANIFEST_LENGTH_UNCOMPRESSED][MANIFEST_TYPE][CHUNKED_ZSTD_MAGIC_NUMBER] // MANIFEST_OFFSET, MANIFEST_LENGTH, MANIFEST_LENGTH_UNCOMPRESSED and CHUNKED_ZSTD_MAGIC_NUMBER are 64 bits unsigned in little endian format. -func zstdChunkedWriterWithLevel(out io.Writer, metadata map[string]string, level int) (io.WriteCloser, error) { +func makeZstdChunkedWriter(out io.Writer, metadata map[string]string, createZstdWriter minimal.CreateZstdWriterFunc) (io.WriteCloser, error) { ch := make(chan error, 1) r, w := io.Pipe() go func() { - ch <- writeZstdChunkedStream(out, metadata, r, level) + ch <- writeZstdChunkedStream(out, metadata, r, createZstdWriter) _, _ = io.Copy(io.Discard, r) // Ordinarily writeZstdChunkedStream consumes all of r. If it fails, ensure the write end never blocks and eventually terminates. r.Close() close(ch) @@ -493,5 +485,40 @@ func ZstdCompressor(r io.Writer, metadata map[string]string, level *int) (io.Wri level = &l } - return zstdChunkedWriterWithLevel(r, metadata, *level) + createZstdWriter := func(dest io.Writer) (minimal.ZstdWriter, error) { + return minimal.ZstdWriterWithLevel(dest, *level) + } + + return makeZstdChunkedWriter(r, metadata, createZstdWriter) +} + +type noCompression struct { + dest io.Writer +} + +func (n *noCompression) Write(p []byte) (int, error) { + return n.dest.Write(p) +} + +func (n *noCompression) Close() error { + return nil +} + +func (n *noCompression) Flush() error { + return nil +} + +func (n *noCompression) Reset(dest io.Writer) { + n.dest = dest +} + +// NoCompression writes directly to the output file without any compression +// +// Such an output does not follow the zstd:chunked spec and cannot be generally consumed; this function +// only exists for internal purposes and should not be called from outside c/storage. +func NoCompression(r io.Writer, metadata map[string]string) (io.WriteCloser, error) { + createZstdWriter := func(dest io.Writer) (minimal.ZstdWriter, error) { + return &noCompression{dest: dest}, nil + } + return makeZstdChunkedWriter(r, metadata, createZstdWriter) } diff --git a/vendor/github.com/containers/storage/pkg/chunked/internal/minimal/compression.go b/vendor/github.com/containers/storage/pkg/chunked/internal/minimal/compression.go index f85c5973c..4191524cc 100644 --- a/vendor/github.com/containers/storage/pkg/chunked/internal/minimal/compression.go +++ b/vendor/github.com/containers/storage/pkg/chunked/internal/minimal/compression.go @@ -20,6 +20,15 @@ import ( "github.com/vbatts/tar-split/archive/tar" ) +// ZstdWriter is an interface that wraps standard io.WriteCloser and Reset() to reuse the compressor with a new writer. +type ZstdWriter interface { + io.WriteCloser + Reset(dest io.Writer) +} + +// CreateZstdWriterFunc is a function that creates a ZstdWriter for the provided destination writer. +type CreateZstdWriterFunc func(dest io.Writer) (ZstdWriter, error) + // TOC is short for Table of Contents and is used by the zstd:chunked // file format to effectively add an overall index into the contents // of a tarball; it also includes file metadata. @@ -179,7 +188,7 @@ type TarSplitData struct { UncompressedSize int64 } -func WriteZstdChunkedManifest(dest io.Writer, outMetadata map[string]string, offset uint64, tarSplitData *TarSplitData, metadata []FileMetadata, level int) error { +func WriteZstdChunkedManifest(dest io.Writer, outMetadata map[string]string, offset uint64, tarSplitData *TarSplitData, metadata []FileMetadata, createZstdWriter CreateZstdWriterFunc) error { // 8 is the size of the zstd skippable frame header + the frame size const zstdSkippableFrameHeader = 8 manifestOffset := offset + zstdSkippableFrameHeader @@ -198,7 +207,7 @@ func WriteZstdChunkedManifest(dest io.Writer, outMetadata map[string]string, off } var compressedBuffer bytes.Buffer - zstdWriter, err := ZstdWriterWithLevel(&compressedBuffer, level) + zstdWriter, err := createZstdWriter(&compressedBuffer) if err != nil { return err } @@ -244,7 +253,7 @@ func WriteZstdChunkedManifest(dest io.Writer, outMetadata map[string]string, off return appendZstdSkippableFrame(dest, manifestDataLE) } -func ZstdWriterWithLevel(dest io.Writer, level int) (*zstd.Encoder, error) { +func ZstdWriterWithLevel(dest io.Writer, level int) (ZstdWriter, error) { el := zstd.EncoderLevelFromZstd(level) return zstd.NewWriter(dest, zstd.WithEncoderLevel(el)) } diff --git a/vendor/github.com/containers/storage/pkg/chunked/storage_linux.go b/vendor/github.com/containers/storage/pkg/chunked/storage_linux.go index 75148bf2b..f23a96b7a 100644 --- a/vendor/github.com/containers/storage/pkg/chunked/storage_linux.go +++ b/vendor/github.com/containers/storage/pkg/chunked/storage_linux.go @@ -2,7 +2,6 @@ package chunked import ( archivetar "archive/tar" - "bytes" "context" "encoding/base64" "errors" @@ -81,7 +80,7 @@ type chunkedDiffer struct { convertToZstdChunked bool // Chunked metadata - // This is usually set in GetDiffer, but if convertToZstdChunked, it is only computed in chunkedDiffer.ApplyDiff + // This is usually set in NewDiffer, but if convertToZstdChunked, it is only computed in chunkedDiffer.ApplyDiff // ========== // tocDigest is the digest of the TOC document when the layer // is partially pulled, or "" if not relevant to consumers. @@ -89,14 +88,14 @@ type chunkedDiffer struct { tocOffset int64 manifest []byte toc *minimal.TOC // The parsed contents of manifest, or nil if not yet available - tarSplit []byte + tarSplit *os.File uncompressedTarSize int64 // -1 if unknown // skipValidation is set to true if the individual files in // the layer are trusted and should not be validated. skipValidation bool // Long-term caches - // This is set in GetDiffer, when the caller must not hold any storage locks, and later consumed in .ApplyDiff() + // This is set in NewDiffer, when the caller must not hold any storage locks, and later consumed in .ApplyDiff() // ========== layersCache *layersCache copyBuffer []byte @@ -109,6 +108,7 @@ type chunkedDiffer struct { zstdReader *zstd.Decoder rawReader io.Reader useFsVerity graphdriver.DifferFsVerity + used bool // the differ object was already used and cannot be used again for .ApplyDiff } var xattrsToIgnore = map[string]any{ @@ -164,16 +164,13 @@ func (c *chunkedDiffer) convertTarToZstdChunked(destDirectory string, payload *o defer diff.Close() - fd, err := unix.Open(destDirectory, unix.O_TMPFILE|unix.O_RDWR|unix.O_CLOEXEC, 0o600) + f, err := openTmpFile(destDirectory) if err != nil { - return 0, nil, "", nil, &fs.PathError{Op: "open", Path: destDirectory, Err: err} + return 0, nil, "", nil, err } - f := os.NewFile(uintptr(fd), destDirectory) - newAnnotations := make(map[string]string) - level := 1 - chunked, err := compressor.ZstdCompressor(f, newAnnotations, &level) + chunked, err := compressor.NoCompression(f, newAnnotations) if err != nil { f.Close() return 0, nil, "", nil, err @@ -193,10 +190,20 @@ func (c *chunkedDiffer) convertTarToZstdChunked(destDirectory string, payload *o return copied, newSeekableFile(f), convertedOutputDigester.Digest(), newAnnotations, nil } -// GetDiffer returns a differ than can be used with ApplyDiffWithDiffer. +func (c *chunkedDiffer) Close() error { + if c.tarSplit != nil { + err := c.tarSplit.Close() + c.tarSplit = nil + return err + } + return nil +} + +// NewDiffer returns a differ than can be used with [Store.PrepareStagedLayer]. // If it returns an error that matches ErrFallbackToOrdinaryLayerDownload, the caller can // retry the operation with a different method. -func GetDiffer(ctx context.Context, store storage.Store, blobDigest digest.Digest, blobSize int64, annotations map[string]string, iss ImageSourceSeekable) (graphdriver.Differ, error) { +// The caller must call Close() on the returned Differ. +func NewDiffer(ctx context.Context, store storage.Store, blobDigest digest.Digest, blobSize int64, annotations map[string]string, iss ImageSourceSeekable) (graphdriver.Differ, error) { pullOptions := parsePullOptions(store) if !pullOptions.enablePartialImages { @@ -259,7 +266,7 @@ func (e errFallbackCanConvert) Unwrap() error { return e.err } -// getProperDiffer is an implementation detail of GetDiffer. +// getProperDiffer is an implementation detail of NewDiffer. // It returns a “proper” differ (not a convert_images one) if possible. // May return an error matching ErrFallbackToOrdinaryLayerDownload if a fallback to an alternative // (either makeConvertFromRawDiffer, or a non-partial pull) is permissible. @@ -332,14 +339,22 @@ func makeConvertFromRawDiffer(store storage.Store, blobDigest digest.Digest, blo // makeZstdChunkedDiffer sets up a chunkedDiffer for a zstd:chunked layer. // It may return an error matching ErrFallbackToOrdinaryLayerDownload / errFallbackCanConvert. -func makeZstdChunkedDiffer(store storage.Store, blobSize int64, tocDigest digest.Digest, annotations map[string]string, iss ImageSourceSeekable, pullOptions pullOptions) (*chunkedDiffer, error) { - manifest, toc, tarSplit, tocOffset, err := readZstdChunkedManifest(iss, tocDigest, annotations) +func makeZstdChunkedDiffer(store storage.Store, blobSize int64, tocDigest digest.Digest, annotations map[string]string, iss ImageSourceSeekable, pullOptions pullOptions) (_ *chunkedDiffer, retErr error) { + manifest, toc, tarSplit, tocOffset, err := readZstdChunkedManifest(store.RunRoot(), iss, tocDigest, annotations, true) if err != nil { // May be ErrFallbackToOrdinaryLayerDownload / errFallbackCanConvert return nil, fmt.Errorf("read zstd:chunked manifest: %w", err) } + defer func() { + if tarSplit != nil && retErr != nil { + tarSplit.Close() + } + }() var uncompressedTarSize int64 = -1 if tarSplit != nil { + if _, err := tarSplit.Seek(0, io.SeekStart); err != nil { + return nil, err + } uncompressedTarSize, err = tarSizeFromTarSplit(tarSplit) if err != nil { return nil, fmt.Errorf("computing size from tar-split: %w", err) @@ -643,27 +658,24 @@ func (o *originFile) OpenFile() (io.ReadCloser, error) { return nil, err } - if _, err := srcFile.Seek(o.Offset, 0); err != nil { + if _, err := srcFile.Seek(o.Offset, io.SeekStart); err != nil { srcFile.Close() return nil, err } return srcFile, nil } -func (c *chunkedDiffer) prepareCompressedStreamToFile(partCompression compressedFileType, from io.Reader, mf *missingFileChunk) (compressedFileType, error) { +func (c *chunkedDiffer) prepareCompressedStreamToFile(partCompression compressedFileType, mf *missingFileChunk) (compressedFileType, error) { switch { case partCompression == fileTypeHole: // The entire part is a hole. Do not need to read from a file. - c.rawReader = nil return fileTypeHole, nil case mf.Hole: // Only the missing chunk in the requested part refers to a hole. // The received data must be discarded. - limitReader := io.LimitReader(from, mf.CompressedSize) - _, err := io.CopyBuffer(io.Discard, limitReader, c.copyBuffer) + _, err := io.CopyBuffer(io.Discard, c.rawReader, c.copyBuffer) return fileTypeHole, err case partCompression == fileTypeZstdChunked: - c.rawReader = io.LimitReader(from, mf.CompressedSize) if c.zstdReader == nil { r, err := zstd.NewReader(c.rawReader) if err != nil { @@ -676,7 +688,6 @@ func (c *chunkedDiffer) prepareCompressedStreamToFile(partCompression compressed } } case partCompression == fileTypeEstargz: - c.rawReader = io.LimitReader(from, mf.CompressedSize) if c.gzipReader == nil { r, err := pgzip.NewReader(c.rawReader) if err != nil { @@ -689,7 +700,7 @@ func (c *chunkedDiffer) prepareCompressedStreamToFile(partCompression compressed } } case partCompression == fileTypeNoCompression: - c.rawReader = io.LimitReader(from, mf.UncompressedSize) + return fileTypeNoCompression, nil default: return partCompression, fmt.Errorf("unknown file type %q", c.fileType) } @@ -889,6 +900,7 @@ func (c *chunkedDiffer) storeMissingFiles(streams chan io.ReadCloser, errs chan for _, missingPart := range missingParts { var part io.ReadCloser partCompression := c.fileType + readingFromLocalFile := false switch { case missingPart.Hole: partCompression = fileTypeHole @@ -899,6 +911,7 @@ func (c *chunkedDiffer) storeMissingFiles(streams chan io.ReadCloser, errs chan return err } partCompression = fileTypeNoCompression + readingFromLocalFile = true case missingPart.SourceChunk != nil: select { case p := <-streams: @@ -932,7 +945,18 @@ func (c *chunkedDiffer) storeMissingFiles(streams chan io.ReadCloser, errs chan goto exit } - compression, err := c.prepareCompressedStreamToFile(partCompression, part, &mf) + c.rawReader = nil + if part != nil { + limit := mf.CompressedSize + // If we are reading from a source file, use the uncompressed size to limit the reader, because + // the compressed size refers to the original layer stream. + if readingFromLocalFile { + limit = mf.UncompressedSize + } + c.rawReader = io.LimitReader(part, limit) + } + + compression, err := c.prepareCompressedStreamToFile(partCompression, &mf) if err != nil { Err = err goto exit @@ -1374,6 +1398,11 @@ func typeToOsMode(typ string) (os.FileMode, error) { } func (c *chunkedDiffer) ApplyDiff(dest string, options *archive.TarOptions, differOpts *graphdriver.DifferOptions) (graphdriver.DriverWithDifferOutput, error) { + if c.used { + return graphdriver.DriverWithDifferOutput{}, fmt.Errorf("internal error: chunked differ already used") + } + c.used = true + defer c.layersCache.release() defer func() { if c.zstdReader != nil { @@ -1419,7 +1448,9 @@ func (c *chunkedDiffer) ApplyDiff(dest string, options *archive.TarOptions, diff if err != nil { return graphdriver.DriverWithDifferOutput{}, err } + c.uncompressedTarSize = tarSize + // fileSource is a O_TMPFILE file descriptor, so we // need to keep it open until the entire file is processed. defer fileSource.Close() @@ -1435,7 +1466,7 @@ func (c *chunkedDiffer) ApplyDiff(dest string, options *archive.TarOptions, diff if tocDigest == nil { return graphdriver.DriverWithDifferOutput{}, fmt.Errorf("internal error: just-created zstd:chunked missing TOC digest") } - manifest, toc, tarSplit, tocOffset, err := readZstdChunkedManifest(fileSource, *tocDigest, annotations) + manifest, toc, tarSplit, tocOffset, err := readZstdChunkedManifest(dest, fileSource, *tocDigest, annotations, false) if err != nil { return graphdriver.DriverWithDifferOutput{}, fmt.Errorf("read zstd:chunked manifest: %w", err) } @@ -1444,7 +1475,7 @@ func (c *chunkedDiffer) ApplyDiff(dest string, options *archive.TarOptions, diff stream = fileSource // fill the chunkedDiffer with the data we just read. - c.fileType = fileTypeZstdChunked + c.fileType = fileTypeNoCompression c.manifest = manifest c.toc = toc c.tarSplit = tarSplit @@ -1842,7 +1873,10 @@ func (c *chunkedDiffer) ApplyDiff(dest string, options *archive.TarOptions, diff case c.pullOptions.insecureAllowUnpredictableImageContents: // Oh well. Skip the costly digest computation. case output.TarSplit != nil: - metadata := tsStorage.NewJSONUnpacker(bytes.NewReader(output.TarSplit)) + if _, err := output.TarSplit.Seek(0, io.SeekStart); err != nil { + return output, err + } + metadata := tsStorage.NewJSONUnpacker(output.TarSplit) fg := newStagedFileGetter(dirFile, flatPathNameMap) digester := digest.Canonical.Digester() if err := asm.WriteOutputTarStream(fg, metadata, digester.Hash()); err != nil { @@ -1850,7 +1884,7 @@ func (c *chunkedDiffer) ApplyDiff(dest string, options *archive.TarOptions, diff } output.UncompressedDigest = digester.Digest() default: - // We are checking for this earlier in GetDiffer, so this should not be reachable. + // We are checking for this earlier in NewDiffer, so this should not be reachable. return output, fmt.Errorf(`internal error: layer's UncompressedDigest is unknown and "insecure_allow_unpredictable_image_contents" is not set`) } } @@ -1861,6 +1895,9 @@ func (c *chunkedDiffer) ApplyDiff(dest string, options *archive.TarOptions, diff output.Artifacts[fsVerityDigestsKey] = c.fsVerityDigests + // on success steal the reference to the tarSplit file + c.tarSplit = nil + return output, nil } @@ -1962,7 +1999,7 @@ func validateChunkChecksum(chunk *minimal.FileMetadata, root, path string, offse } defer fd.Close() - if _, err := unix.Seek(int(fd.Fd()), offset, 0); err != nil { + if _, err := fd.Seek(offset, io.SeekStart); err != nil { return false } diff --git a/vendor/github.com/containers/storage/pkg/chunked/storage_unsupported.go b/vendor/github.com/containers/storage/pkg/chunked/storage_unsupported.go index fe3d36c76..7e73a145b 100644 --- a/vendor/github.com/containers/storage/pkg/chunked/storage_unsupported.go +++ b/vendor/github.com/containers/storage/pkg/chunked/storage_unsupported.go @@ -11,7 +11,8 @@ import ( digest "github.com/opencontainers/go-digest" ) -// GetDiffer returns a differ than can be used with ApplyDiffWithDiffer. -func GetDiffer(ctx context.Context, store storage.Store, blobDigest digest.Digest, blobSize int64, annotations map[string]string, iss ImageSourceSeekable) (graphdriver.Differ, error) { +// NewDiffer returns a differ than can be used with [Store.PrepareStagedLayer]. +// The caller must call Close() on the returned Differ. +func NewDiffer(ctx context.Context, store storage.Store, blobDigest digest.Digest, blobSize int64, annotations map[string]string, iss ImageSourceSeekable) (graphdriver.Differ, error) { return nil, newErrFallbackToOrdinaryLayerDownload(errors.New("format not supported on this system")) } diff --git a/vendor/github.com/containers/storage/pkg/lockfile/lockfile.go b/vendor/github.com/containers/storage/pkg/lockfile/lockfile.go index 52f6c0a62..dfe81c245 100644 --- a/vendor/github.com/containers/storage/pkg/lockfile/lockfile.go +++ b/vendor/github.com/containers/storage/pkg/lockfile/lockfile.go @@ -6,6 +6,8 @@ import ( "path/filepath" "sync" "time" + + "github.com/containers/storage/internal/rawfilelock" ) // A Locker represents a file lock where the file is used to cache an @@ -55,13 +57,6 @@ type Locker interface { AssertLockedForWriting() } -type lockType byte - -const ( - readLock lockType = iota - writeLock -) - // LockFile represents a file lock where the file is used to cache an // identifier of the last party that made changes to whatever's being protected // by the lock. @@ -79,12 +74,12 @@ type LockFile struct { stateMutex *sync.Mutex counter int64 lw LastWrite // A global value valid as of the last .Touch() or .Modified() - lockType lockType + lockType rawfilelock.LockType locked bool // The following fields are only modified on transitions between counter == 0 / counter != 0. // Thus, they can be safely accessed by users _that currently hold the LockFile_ without locking. // In other cases, they need to be protected using stateMutex. - fd fileHandle + fd rawfilelock.FileHandle } var ( @@ -129,12 +124,12 @@ func (l *LockFile) Lock() { if l.ro { panic("can't take write lock on read-only lock file") } - l.lock(writeLock) + l.lock(rawfilelock.WriteLock) } // RLock locks the lockfile as a reader. func (l *LockFile) RLock() { - l.lock(readLock) + l.lock(rawfilelock.ReadLock) } // TryLock attempts to lock the lockfile as a writer. Panic if the lock is a read-only one. @@ -142,12 +137,12 @@ func (l *LockFile) TryLock() error { if l.ro { panic("can't take write lock on read-only lock file") } - return l.tryLock(writeLock) + return l.tryLock(rawfilelock.WriteLock) } // TryRLock attempts to lock the lockfile as a reader. func (l *LockFile) TryRLock() error { - return l.tryLock(readLock) + return l.tryLock(rawfilelock.ReadLock) } // Unlock unlocks the lockfile. @@ -172,9 +167,9 @@ func (l *LockFile) Unlock() { l.locked = false // Close the file descriptor on the last unlock, releasing the // file lock. - unlockAndCloseHandle(l.fd) + rawfilelock.UnlockAndCloseHandle(l.fd) } - if l.lockType == readLock { + if l.lockType == rawfilelock.ReadLock { l.rwMutex.RUnlock() } else { l.rwMutex.Unlock() @@ -206,7 +201,7 @@ func (l *LockFile) AssertLockedForWriting() { l.AssertLocked() // Like AssertLocked, don’t even bother with l.stateMutex. - if l.lockType == readLock { + if l.lockType == rawfilelock.ReadLock { panic("internal error: lock is not held for writing") } } @@ -273,7 +268,7 @@ func (l *LockFile) Touch() error { return err } l.stateMutex.Lock() - if !l.locked || (l.lockType == readLock) { + if !l.locked || (l.lockType == rawfilelock.ReadLock) { panic("attempted to update last-writer in lockfile without the write lock") } defer l.stateMutex.Unlock() @@ -324,6 +319,24 @@ func getLockfile(path string, ro bool) (*LockFile, error) { return lockFile, nil } +// openLock opens a lock file at the specified path, creating the parent directory if it does not exist. +func openLock(path string, readOnly bool) (rawfilelock.FileHandle, error) { + fd, err := rawfilelock.OpenLock(path, readOnly) + if err == nil { + return fd, nil + } + + // the directory of the lockfile seems to be removed, try to create it + if os.IsNotExist(err) { + if err := os.MkdirAll(filepath.Dir(path), 0o700); err != nil { + return fd, fmt.Errorf("creating lock file directory: %w", err) + } + + return openLock(path, readOnly) + } + return fd, &os.PathError{Op: "open", Path: path, Err: err} +} + // createLockFileForPath returns new *LockFile object, possibly (depending on the platform) // working inter-process and associated with the specified path. // @@ -343,11 +356,11 @@ func createLockFileForPath(path string, ro bool) (*LockFile, error) { if err != nil { return nil, err } - unlockAndCloseHandle(fd) + rawfilelock.UnlockAndCloseHandle(fd) - lType := writeLock + lType := rawfilelock.WriteLock if ro { - lType = readLock + lType = rawfilelock.ReadLock } return &LockFile{ @@ -362,40 +375,10 @@ func createLockFileForPath(path string, ro bool) (*LockFile, error) { }, nil } -// openLock opens the file at path and returns the corresponding file -// descriptor. The path is opened either read-only or read-write, -// depending on the value of ro argument. -// -// openLock will create the file and its parent directories, -// if necessary. -func openLock(path string, ro bool) (fd fileHandle, err error) { - flags := os.O_CREATE - if ro { - flags |= os.O_RDONLY - } else { - flags |= os.O_RDWR - } - fd, err = openHandle(path, flags) - if err == nil { - return fd, nil - } - - // the directory of the lockfile seems to be removed, try to create it - if os.IsNotExist(err) { - if err := os.MkdirAll(filepath.Dir(path), 0o700); err != nil { - return fd, fmt.Errorf("creating lock file directory: %w", err) - } - - return openLock(path, ro) - } - - return fd, &os.PathError{Op: "open", Path: path, Err: err} -} - // lock locks the lockfile via syscall based on the specified type and // command. -func (l *LockFile) lock(lType lockType) { - if lType == readLock { +func (l *LockFile) lock(lType rawfilelock.LockType) { + if lType == rawfilelock.ReadLock { l.rwMutex.RLock() } else { l.rwMutex.Lock() @@ -413,7 +396,7 @@ func (l *LockFile) lock(lType lockType) { // Optimization: only use the (expensive) syscall when // the counter is 0. In this case, we're either the first // reader lock or a writer lock. - if err := lockHandle(l.fd, lType, false); err != nil { + if err := rawfilelock.LockFile(l.fd, lType); err != nil { panic(err) } } @@ -424,10 +407,10 @@ func (l *LockFile) lock(lType lockType) { // lock locks the lockfile via syscall based on the specified type and // command. -func (l *LockFile) tryLock(lType lockType) error { +func (l *LockFile) tryLock(lType rawfilelock.LockType) error { var success bool var rwMutexUnlocker func() - if lType == readLock { + if lType == rawfilelock.ReadLock { success = l.rwMutex.TryRLock() rwMutexUnlocker = l.rwMutex.RUnlock } else { @@ -451,8 +434,8 @@ func (l *LockFile) tryLock(lType lockType) error { // Optimization: only use the (expensive) syscall when // the counter is 0. In this case, we're either the first // reader lock or a writer lock. - if err = lockHandle(l.fd, lType, true); err != nil { - closeHandle(fd) + if err = rawfilelock.TryLockFile(l.fd, lType); err != nil { + rawfilelock.CloseHandle(fd) rwMutexUnlocker() return err } diff --git a/vendor/github.com/containers/storage/pkg/lockfile/lockfile_unix.go b/vendor/github.com/containers/storage/pkg/lockfile/lockfile_unix.go index 885f2f88a..14c27c51f 100644 --- a/vendor/github.com/containers/storage/pkg/lockfile/lockfile_unix.go +++ b/vendor/github.com/containers/storage/pkg/lockfile/lockfile_unix.go @@ -9,8 +9,6 @@ import ( "golang.org/x/sys/unix" ) -type fileHandle uintptr - // GetLastWrite returns a LastWrite value corresponding to current state of the lock. // This is typically called before (_not after_) loading the state when initializing a consumer // of the data protected by the lock. @@ -66,41 +64,3 @@ func (l *LockFile) TouchedSince(when time.Time) bool { touched := time.Unix(mtim.Unix()) return when.Before(touched) } - -func openHandle(path string, mode int) (fileHandle, error) { - mode |= unix.O_CLOEXEC - fd, err := unix.Open(path, mode, 0o644) - return fileHandle(fd), err -} - -func lockHandle(fd fileHandle, lType lockType, nonblocking bool) error { - fType := unix.F_RDLCK - if lType != readLock { - fType = unix.F_WRLCK - } - lk := unix.Flock_t{ - Type: int16(fType), - Whence: int16(unix.SEEK_SET), - Start: 0, - Len: 0, - } - cmd := unix.F_SETLKW - if nonblocking { - cmd = unix.F_SETLK - } - for { - err := unix.FcntlFlock(uintptr(fd), cmd, &lk) - if err == nil || nonblocking { - return err - } - time.Sleep(10 * time.Millisecond) - } -} - -func unlockAndCloseHandle(fd fileHandle) { - unix.Close(int(fd)) -} - -func closeHandle(fd fileHandle) { - unix.Close(int(fd)) -} diff --git a/vendor/github.com/containers/storage/pkg/lockfile/lockfile_windows.go b/vendor/github.com/containers/storage/pkg/lockfile/lockfile_windows.go index 0cc1c50cc..e66f7bfbb 100644 --- a/vendor/github.com/containers/storage/pkg/lockfile/lockfile_windows.go +++ b/vendor/github.com/containers/storage/pkg/lockfile/lockfile_windows.go @@ -14,8 +14,6 @@ const ( allBytes = ^uint32(0) ) -type fileHandle windows.Handle - // GetLastWrite returns a LastWrite value corresponding to current state of the lock. // This is typically called before (_not after_) loading the state when initializing a consumer // of the data protected by the lock. @@ -73,37 +71,3 @@ func (l *LockFile) TouchedSince(when time.Time) bool { } return when.Before(stat.ModTime()) } - -func openHandle(path string, mode int) (fileHandle, error) { - mode |= windows.O_CLOEXEC - fd, err := windows.Open(path, mode, windows.S_IWRITE) - return fileHandle(fd), err -} - -func lockHandle(fd fileHandle, lType lockType, nonblocking bool) error { - flags := 0 - if lType != readLock { - flags = windows.LOCKFILE_EXCLUSIVE_LOCK - } - if nonblocking { - flags |= windows.LOCKFILE_FAIL_IMMEDIATELY - } - ol := new(windows.Overlapped) - if err := windows.LockFileEx(windows.Handle(fd), uint32(flags), reserved, allBytes, allBytes, ol); err != nil { - if nonblocking { - return err - } - panic(err) - } - return nil -} - -func unlockAndCloseHandle(fd fileHandle) { - ol := new(windows.Overlapped) - windows.UnlockFileEx(windows.Handle(fd), reserved, allBytes, allBytes, ol) - closeHandle(fd) -} - -func closeHandle(fd fileHandle) { - windows.Close(windows.Handle(fd)) -} diff --git a/vendor/github.com/containers/storage/store.go b/vendor/github.com/containers/storage/store.go index 869b0c516..10f4d56a8 100644 --- a/vendor/github.com/containers/storage/store.go +++ b/vendor/github.com/containers/storage/store.go @@ -22,6 +22,7 @@ import ( drivers "github.com/containers/storage/drivers" "github.com/containers/storage/internal/dedup" + "github.com/containers/storage/internal/tempdir" "github.com/containers/storage/pkg/archive" "github.com/containers/storage/pkg/directory" "github.com/containers/storage/pkg/idtools" @@ -362,15 +363,11 @@ type Store interface { // } ApplyDiff(to string, diff io.Reader) (int64, error) - // ApplyDiffWithDiffer applies a diff to a layer. - // It is the caller responsibility to clean the staging directory if it is not - // successfully applied with ApplyStagedLayer. - // Deprecated: Use PrepareStagedLayer instead. ApplyDiffWithDiffer is going to be removed in a future release - ApplyDiffWithDiffer(to string, options *drivers.ApplyDiffWithDifferOpts, differ drivers.Differ) (*drivers.DriverWithDifferOutput, error) - // PrepareStagedLayer applies a diff to a layer. // It is the caller responsibility to clean the staging directory if it is not // successfully applied with ApplyStagedLayer. + // The caller must ensure [Store.ApplyStagedLayer] or [Store.CleanupStagedLayer] is called eventually + // with the returned [drivers.DriverWithDifferOutput] object. PrepareStagedLayer(options *drivers.ApplyDiffWithDifferOpts, differ drivers.Differ) (*drivers.DriverWithDifferOutput, error) // ApplyStagedLayer combines the functions of creating a layer and using the staging @@ -1449,16 +1446,7 @@ func (s *store) writeToAllStores(fn func(rlstore rwLayerStore) error) error { // On entry: // - rlstore must be locked for writing func (s *store) canUseShifting(uidmap, gidmap []idtools.IDMap) bool { - if !s.graphDriver.SupportsShifting() { - return false - } - if uidmap != nil && !idtools.IsContiguous(uidmap) { - return false - } - if gidmap != nil && !idtools.IsContiguous(gidmap) { - return false - } - return true + return s.graphDriver.SupportsShifting(uidmap, gidmap) } // On entry: @@ -1771,7 +1759,7 @@ func (s *store) imageTopLayerForMapping(image *Image, ristore roImageStore, rlst } // By construction, createMappedLayer can only be true if ristore == s.imageStore. if err = s.imageStore.addMappedTopLayer(image.ID, mappedLayer.ID); err != nil { - if err2 := rlstore.Delete(mappedLayer.ID); err2 != nil { + if err2 := rlstore.deleteWhileHoldingLock(mappedLayer.ID); err2 != nil { err = fmt.Errorf("deleting layer %q: %v: %w", mappedLayer.ID, err2, err) } return nil, fmt.Errorf("registering ID-mapped layer with image %q: %w", image.ID, err) @@ -1956,7 +1944,7 @@ func (s *store) CreateContainer(id string, names []string, image, layer, metadat } container, err := s.containerStore.create(id, names, imageID, layer, &options) if err != nil || container == nil { - if err2 := rlstore.Delete(layer); err2 != nil { + if err2 := rlstore.deleteWhileHoldingLock(layer); err2 != nil { if err == nil { err = fmt.Errorf("deleting layer %#v: %w", layer, err2) } else { @@ -2553,7 +2541,13 @@ func (s *store) Lookup(name string) (string, error) { return "", ErrLayerUnknown } -func (s *store) DeleteLayer(id string) error { +func (s *store) DeleteLayer(id string) (retErr error) { + cleanupFunctions := []tempdir.CleanupTempDirFunc{} + defer func() { + if cleanupErr := tempdir.CleanupTemporaryDirectories(cleanupFunctions...); cleanupErr != nil { + retErr = errors.Join(cleanupErr, retErr) + } + }() return s.writeToAllStores(func(rlstore rwLayerStore) error { if rlstore.Exists(id) { if l, err := rlstore.Get(id); err != nil { @@ -2587,7 +2581,9 @@ func (s *store) DeleteLayer(id string) error { return fmt.Errorf("layer %v used by container %v: %w", id, container.ID, ErrLayerUsedByContainer) } } - if err := rlstore.Delete(id); err != nil { + cf, err := rlstore.deferredDelete(id) + cleanupFunctions = append(cleanupFunctions, cf...) + if err != nil { return fmt.Errorf("delete layer %v: %w", id, err) } @@ -2604,8 +2600,14 @@ func (s *store) DeleteLayer(id string) error { }) } -func (s *store) DeleteImage(id string, commit bool) (layers []string, err error) { +func (s *store) DeleteImage(id string, commit bool) (layers []string, retErr error) { layersToRemove := []string{} + cleanupFunctions := []tempdir.CleanupTempDirFunc{} + defer func() { + if cleanupErr := tempdir.CleanupTemporaryDirectories(cleanupFunctions...); cleanupErr != nil { + retErr = errors.Join(cleanupErr, retErr) + } + }() if err := s.writeToAllStores(func(rlstore rwLayerStore) error { // Delete image from all available imagestores configured to be used. imageFound := false @@ -2711,7 +2713,9 @@ func (s *store) DeleteImage(id string, commit bool) (layers []string, err error) } if commit { for _, layer := range layersToRemove { - if err = rlstore.Delete(layer); err != nil { + cf, err := rlstore.deferredDelete(layer) + cleanupFunctions = append(cleanupFunctions, cf...) + if err != nil { return err } } @@ -2723,7 +2727,13 @@ func (s *store) DeleteImage(id string, commit bool) (layers []string, err error) return layersToRemove, nil } -func (s *store) DeleteContainer(id string) error { +func (s *store) DeleteContainer(id string) (retErr error) { + cleanupFunctions := []tempdir.CleanupTempDirFunc{} + defer func() { + if cleanupErr := tempdir.CleanupTemporaryDirectories(cleanupFunctions...); cleanupErr != nil { + retErr = errors.Join(cleanupErr, retErr) + } + }() return s.writeToAllStores(func(rlstore rwLayerStore) error { if !s.containerStore.Exists(id) { return ErrNotAContainer @@ -2739,7 +2749,9 @@ func (s *store) DeleteContainer(id string) error { // the container record that refers to it, effectively losing // track of it if rlstore.Exists(container.LayerID) { - if err := rlstore.Delete(container.LayerID); err != nil { + cf, err := rlstore.deferredDelete(container.LayerID) + cleanupFunctions = append(cleanupFunctions, cf...) + if err != nil { return err } } @@ -2765,12 +2777,20 @@ func (s *store) DeleteContainer(id string) error { }) } -func (s *store) Delete(id string) error { +func (s *store) Delete(id string) (retErr error) { + cleanupFunctions := []tempdir.CleanupTempDirFunc{} + defer func() { + if cleanupErr := tempdir.CleanupTemporaryDirectories(cleanupFunctions...); cleanupErr != nil { + retErr = errors.Join(cleanupErr, retErr) + } + }() return s.writeToAllStores(func(rlstore rwLayerStore) error { if s.containerStore.Exists(id) { if container, err := s.containerStore.Get(id); err == nil { if rlstore.Exists(container.LayerID) { - if err = rlstore.Delete(container.LayerID); err != nil { + cf, err := rlstore.deferredDelete(container.LayerID) + cleanupFunctions = append(cleanupFunctions, cf...) + if err != nil { return err } if err = s.containerStore.Delete(id); err != nil { @@ -2794,7 +2814,9 @@ func (s *store) Delete(id string) error { return s.imageStore.Delete(id) } if rlstore.Exists(id) { - return rlstore.Delete(id) + cf, err := rlstore.deferredDelete(id) + cleanupFunctions = append(cleanupFunctions, cf...) + return err } return ErrLayerUnknown }) @@ -3132,6 +3154,12 @@ func (s *store) Diff(from, to string, options *DiffOptions) (io.ReadCloser, erro } func (s *store) ApplyStagedLayer(args ApplyStagedLayerOptions) (*Layer, error) { + defer func() { + if args.DiffOutput.TarSplit != nil { + args.DiffOutput.TarSplit.Close() + args.DiffOutput.TarSplit = nil + } + }() rlstore, rlstores, err := s.bothLayerStoreKinds() if err != nil { return nil, err @@ -3163,6 +3191,10 @@ func (s *store) ApplyStagedLayer(args ApplyStagedLayerOptions) (*Layer, error) { } func (s *store) CleanupStagedLayer(diffOutput *drivers.DriverWithDifferOutput) error { + if diffOutput.TarSplit != nil { + diffOutput.TarSplit.Close() + diffOutput.TarSplit = nil + } _, err := writeToLayerStore(s, func(rlstore rwLayerStore) (struct{}, error) { return struct{}{}, rlstore.CleanupStagingDirectory(diffOutput.Target) }) @@ -3177,13 +3209,6 @@ func (s *store) PrepareStagedLayer(options *drivers.ApplyDiffWithDifferOpts, dif return rlstore.applyDiffWithDifferNoLock(options, differ) } -func (s *store) ApplyDiffWithDiffer(to string, options *drivers.ApplyDiffWithDifferOpts, differ drivers.Differ) (*drivers.DriverWithDifferOutput, error) { - if to != "" { - return nil, fmt.Errorf("ApplyDiffWithDiffer does not support non-empty 'layer' parameter") - } - return s.PrepareStagedLayer(options, differ) -} - func (s *store) DifferTarget(id string) (string, error) { return writeToLayerStore(s, func(rlstore rwLayerStore) (string, error) { if rlstore.Exists(id) { diff --git a/vendor/github.com/containers/storage/types/options.go b/vendor/github.com/containers/storage/types/options.go index 1255a0290..451a3f6de 100644 --- a/vendor/github.com/containers/storage/types/options.go +++ b/vendor/github.com/containers/storage/types/options.go @@ -160,19 +160,17 @@ func loadStoreOptionsFromConfFile(storageConf string) (StoreOptions, error) { defaultRootlessGraphRoot = storageOpts.GraphRoot storageOpts = StoreOptions{} reloadConfigurationFileIfNeeded(storageConf, &storageOpts) - if usePerUserStorage() { - // If the file did not specify a graphroot or runroot, - // set sane defaults so we don't try and use root-owned - // directories - if storageOpts.RunRoot == "" { - storageOpts.RunRoot = defaultRootlessRunRoot - } - if storageOpts.GraphRoot == "" { - if storageOpts.RootlessStoragePath != "" { - storageOpts.GraphRoot = storageOpts.RootlessStoragePath - } else { - storageOpts.GraphRoot = defaultRootlessGraphRoot - } + // If the file did not specify a graphroot or runroot, + // set sane defaults so we don't try and use root-owned + // directories + if storageOpts.RunRoot == "" { + storageOpts.RunRoot = defaultRootlessRunRoot + } + if storageOpts.GraphRoot == "" { + if storageOpts.RootlessStoragePath != "" { + storageOpts.GraphRoot = storageOpts.RootlessStoragePath + } else { + storageOpts.GraphRoot = defaultRootlessGraphRoot } } } diff --git a/vendor/github.com/containers/storage/userns.go b/vendor/github.com/containers/storage/userns.go index 9cfd6ea34..117a732ce 100644 --- a/vendor/github.com/containers/storage/userns.go +++ b/vendor/github.com/containers/storage/userns.go @@ -202,7 +202,7 @@ outer: return 0, err } defer func() { - if err2 := rlstore.Delete(clayer.ID); err2 != nil { + if err2 := rlstore.deleteWhileHoldingLock(clayer.ID); err2 != nil { if retErr == nil { retErr = fmt.Errorf("deleting temporary layer %#v: %w", clayer.ID, err2) } else { diff --git a/vendor/github.com/tchap/go-patricia/v2/patricia/patricia.go b/vendor/github.com/tchap/go-patricia/v2/patricia/patricia.go index 7b9975e38..9bf8f4fec 100644 --- a/vendor/github.com/tchap/go-patricia/v2/patricia/patricia.go +++ b/vendor/github.com/tchap/go-patricia/v2/patricia/patricia.go @@ -465,7 +465,7 @@ func (trie *Trie) compact() *Trie { // If any item is set, we cannot compact since we want to retain // the ability to do searching by key. This makes compaction less usable, // but that simply cannot be avoided. - if trie.item != nil || child.item != nil { + if child == nil || trie.item != nil || child.item != nil { return trie } diff --git a/vendor/golang.org/x/sync/errgroup/errgroup.go b/vendor/golang.org/x/sync/errgroup/errgroup.go index f8c3c0926..1d8cffae8 100644 --- a/vendor/golang.org/x/sync/errgroup/errgroup.go +++ b/vendor/golang.org/x/sync/errgroup/errgroup.go @@ -61,12 +61,14 @@ func (g *Group) Wait() error { } // Go calls the given function in a new goroutine. +// // The first call to Go must happen before a Wait. // It blocks until the new goroutine can be added without the number of -// active goroutines in the group exceeding the configured limit. +// goroutines in the group exceeding the configured limit. // -// The first call to return a non-nil error cancels the group's context, if the -// group was created by calling WithContext. The error will be returned by Wait. +// The first goroutine in the group that returns a non-nil error will +// cancel the associated Context, if any. The error will be returned +// by Wait. func (g *Group) Go(f func() error) { if g.sem != nil { g.sem <- token{} @@ -76,6 +78,18 @@ func (g *Group) Go(f func() error) { go func() { defer g.done() + // It is tempting to propagate panics from f() + // up to the goroutine that calls Wait, but + // it creates more problems than it solves: + // - it delays panics arbitrarily, + // making bugs harder to detect; + // - it turns f's panic stack into a mere value, + // hiding it from crash-monitoring tools; + // - it risks deadlocks that hide the panic entirely, + // if f's panic leaves the program in a state + // that prevents the Wait call from being reached. + // See #53757, #74275, #74304, #74306. + if err := f(); err != nil { g.errOnce.Do(func() { g.err = err diff --git a/vendor/golang.org/x/sys/unix/zerrors_linux.go b/vendor/golang.org/x/sys/unix/zerrors_linux.go index 4f432bfe8..9e7a6c5a4 100644 --- a/vendor/golang.org/x/sys/unix/zerrors_linux.go +++ b/vendor/golang.org/x/sys/unix/zerrors_linux.go @@ -319,6 +319,7 @@ const ( AUDIT_INTEGRITY_POLICY_RULE = 0x70f AUDIT_INTEGRITY_RULE = 0x70d AUDIT_INTEGRITY_STATUS = 0x70a + AUDIT_INTEGRITY_USERSPACE = 0x710 AUDIT_IPC = 0x517 AUDIT_IPC_SET_PERM = 0x51f AUDIT_IPE_ACCESS = 0x58c @@ -843,9 +844,9 @@ const ( DM_UUID_FLAG = 0x4000 DM_UUID_LEN = 0x81 DM_VERSION = 0xc138fd00 - DM_VERSION_EXTRA = "-ioctl (2023-03-01)" + DM_VERSION_EXTRA = "-ioctl (2025-01-17)" DM_VERSION_MAJOR = 0x4 - DM_VERSION_MINOR = 0x30 + DM_VERSION_MINOR = 0x31 DM_VERSION_PATCHLEVEL = 0x0 DT_BLK = 0x6 DT_CHR = 0x2 @@ -941,6 +942,8 @@ const ( ETHER_FLOW = 0x12 ETHTOOL_BUSINFO_LEN = 0x20 ETHTOOL_EROMVERS_LEN = 0x20 + ETHTOOL_FAMILY_NAME = "ethtool" + ETHTOOL_FAMILY_VERSION = 0x1 ETHTOOL_FEC_AUTO = 0x2 ETHTOOL_FEC_BASER = 0x10 ETHTOOL_FEC_LLRS = 0x20 @@ -1203,6 +1206,9 @@ const ( FAN_DENY = 0x2 FAN_ENABLE_AUDIT = 0x40 FAN_EPIDFD = -0x2 + FAN_ERRNO_BITS = 0x8 + FAN_ERRNO_MASK = 0xff + FAN_ERRNO_SHIFT = 0x18 FAN_EVENT_INFO_TYPE_DFID = 0x3 FAN_EVENT_INFO_TYPE_DFID_NAME = 0x2 FAN_EVENT_INFO_TYPE_ERROR = 0x5 @@ -1210,6 +1216,7 @@ const ( FAN_EVENT_INFO_TYPE_NEW_DFID_NAME = 0xc FAN_EVENT_INFO_TYPE_OLD_DFID_NAME = 0xa FAN_EVENT_INFO_TYPE_PIDFD = 0x4 + FAN_EVENT_INFO_TYPE_RANGE = 0x6 FAN_EVENT_METADATA_LEN = 0x18 FAN_EVENT_ON_CHILD = 0x8000000 FAN_FS_ERROR = 0x8000 @@ -1240,6 +1247,7 @@ const ( FAN_OPEN_EXEC = 0x1000 FAN_OPEN_EXEC_PERM = 0x40000 FAN_OPEN_PERM = 0x10000 + FAN_PRE_ACCESS = 0x100000 FAN_Q_OVERFLOW = 0x4000 FAN_RENAME = 0x10000000 FAN_REPORT_DFID_NAME = 0xc00 @@ -2787,7 +2795,7 @@ const ( RTAX_UNSPEC = 0x0 RTAX_WINDOW = 0x3 RTA_ALIGNTO = 0x4 - RTA_MAX = 0x1e + RTA_MAX = 0x1f RTCF_DIRECTSRC = 0x4000000 RTCF_DOREDIRECT = 0x1000000 RTCF_LOG = 0x2000000 @@ -2864,10 +2872,12 @@ const ( RTM_DELACTION = 0x31 RTM_DELADDR = 0x15 RTM_DELADDRLABEL = 0x49 + RTM_DELANYCAST = 0x3d RTM_DELCHAIN = 0x65 RTM_DELLINK = 0x11 RTM_DELLINKPROP = 0x6d RTM_DELMDB = 0x55 + RTM_DELMULTICAST = 0x39 RTM_DELNEIGH = 0x1d RTM_DELNETCONF = 0x51 RTM_DELNEXTHOP = 0x69 @@ -2917,11 +2927,13 @@ const ( RTM_NEWACTION = 0x30 RTM_NEWADDR = 0x14 RTM_NEWADDRLABEL = 0x48 + RTM_NEWANYCAST = 0x3c RTM_NEWCACHEREPORT = 0x60 RTM_NEWCHAIN = 0x64 RTM_NEWLINK = 0x10 RTM_NEWLINKPROP = 0x6c RTM_NEWMDB = 0x54 + RTM_NEWMULTICAST = 0x38 RTM_NEWNDUSEROPT = 0x44 RTM_NEWNEIGH = 0x1c RTM_NEWNEIGHTBL = 0x40 @@ -2987,11 +2999,12 @@ const ( RUSAGE_THREAD = 0x1 RWF_APPEND = 0x10 RWF_ATOMIC = 0x40 + RWF_DONTCACHE = 0x80 RWF_DSYNC = 0x2 RWF_HIPRI = 0x1 RWF_NOAPPEND = 0x20 RWF_NOWAIT = 0x8 - RWF_SUPPORTED = 0x7f + RWF_SUPPORTED = 0xff RWF_SYNC = 0x4 RWF_WRITE_LIFE_NOT_SET = 0x0 SCHED_BATCH = 0x3 @@ -3271,6 +3284,7 @@ const ( STATX_BTIME = 0x800 STATX_CTIME = 0x80 STATX_DIOALIGN = 0x2000 + STATX_DIO_READ_ALIGN = 0x20000 STATX_GID = 0x10 STATX_INO = 0x100 STATX_MNT_ID = 0x1000 @@ -3322,7 +3336,7 @@ const ( TASKSTATS_GENL_NAME = "TASKSTATS" TASKSTATS_GENL_VERSION = 0x1 TASKSTATS_TYPE_MAX = 0x6 - TASKSTATS_VERSION = 0xe + TASKSTATS_VERSION = 0xf TCIFLUSH = 0x0 TCIOFF = 0x2 TCIOFLUSH = 0x2 @@ -3503,6 +3517,7 @@ const ( TP_STATUS_WRONG_FORMAT = 0x4 TRACEFS_MAGIC = 0x74726163 TS_COMM_LEN = 0x20 + UBI_IOCECNFO = 0xc01c6f06 UDF_SUPER_MAGIC = 0x15013346 UDP_CORK = 0x1 UDP_ENCAP = 0x64 diff --git a/vendor/golang.org/x/sys/unix/zerrors_linux_386.go b/vendor/golang.org/x/sys/unix/zerrors_linux_386.go index 75207613c..a8c421e29 100644 --- a/vendor/golang.org/x/sys/unix/zerrors_linux_386.go +++ b/vendor/golang.org/x/sys/unix/zerrors_linux_386.go @@ -372,6 +372,7 @@ const ( SO_RCVBUFFORCE = 0x21 SO_RCVLOWAT = 0x12 SO_RCVMARK = 0x4b + SO_RCVPRIORITY = 0x52 SO_RCVTIMEO = 0x14 SO_RCVTIMEO_NEW = 0x42 SO_RCVTIMEO_OLD = 0x14 diff --git a/vendor/golang.org/x/sys/unix/zerrors_linux_amd64.go b/vendor/golang.org/x/sys/unix/zerrors_linux_amd64.go index c68acda53..9a88d1813 100644 --- a/vendor/golang.org/x/sys/unix/zerrors_linux_amd64.go +++ b/vendor/golang.org/x/sys/unix/zerrors_linux_amd64.go @@ -373,6 +373,7 @@ const ( SO_RCVBUFFORCE = 0x21 SO_RCVLOWAT = 0x12 SO_RCVMARK = 0x4b + SO_RCVPRIORITY = 0x52 SO_RCVTIMEO = 0x14 SO_RCVTIMEO_NEW = 0x42 SO_RCVTIMEO_OLD = 0x14 diff --git a/vendor/golang.org/x/sys/unix/zerrors_linux_arm.go b/vendor/golang.org/x/sys/unix/zerrors_linux_arm.go index a8c607ab8..7cb6a867e 100644 --- a/vendor/golang.org/x/sys/unix/zerrors_linux_arm.go +++ b/vendor/golang.org/x/sys/unix/zerrors_linux_arm.go @@ -378,6 +378,7 @@ const ( SO_RCVBUFFORCE = 0x21 SO_RCVLOWAT = 0x12 SO_RCVMARK = 0x4b + SO_RCVPRIORITY = 0x52 SO_RCVTIMEO = 0x14 SO_RCVTIMEO_NEW = 0x42 SO_RCVTIMEO_OLD = 0x14 diff --git a/vendor/golang.org/x/sys/unix/zerrors_linux_arm64.go b/vendor/golang.org/x/sys/unix/zerrors_linux_arm64.go index 18563dd8d..d0ecd2c58 100644 --- a/vendor/golang.org/x/sys/unix/zerrors_linux_arm64.go +++ b/vendor/golang.org/x/sys/unix/zerrors_linux_arm64.go @@ -371,6 +371,7 @@ const ( SO_RCVBUFFORCE = 0x21 SO_RCVLOWAT = 0x12 SO_RCVMARK = 0x4b + SO_RCVPRIORITY = 0x52 SO_RCVTIMEO = 0x14 SO_RCVTIMEO_NEW = 0x42 SO_RCVTIMEO_OLD = 0x14 diff --git a/vendor/golang.org/x/sys/unix/zerrors_linux_loong64.go b/vendor/golang.org/x/sys/unix/zerrors_linux_loong64.go index 22912cdaa..7a2940ae0 100644 --- a/vendor/golang.org/x/sys/unix/zerrors_linux_loong64.go +++ b/vendor/golang.org/x/sys/unix/zerrors_linux_loong64.go @@ -365,6 +365,7 @@ const ( SO_RCVBUFFORCE = 0x21 SO_RCVLOWAT = 0x12 SO_RCVMARK = 0x4b + SO_RCVPRIORITY = 0x52 SO_RCVTIMEO = 0x14 SO_RCVTIMEO_NEW = 0x42 SO_RCVTIMEO_OLD = 0x14 diff --git a/vendor/golang.org/x/sys/unix/zerrors_linux_mips.go b/vendor/golang.org/x/sys/unix/zerrors_linux_mips.go index 29344eb37..d14ca8f2e 100644 --- a/vendor/golang.org/x/sys/unix/zerrors_linux_mips.go +++ b/vendor/golang.org/x/sys/unix/zerrors_linux_mips.go @@ -371,6 +371,7 @@ const ( SO_RCVBUFFORCE = 0x21 SO_RCVLOWAT = 0x1004 SO_RCVMARK = 0x4b + SO_RCVPRIORITY = 0x52 SO_RCVTIMEO = 0x1006 SO_RCVTIMEO_NEW = 0x42 SO_RCVTIMEO_OLD = 0x1006 diff --git a/vendor/golang.org/x/sys/unix/zerrors_linux_mips64.go b/vendor/golang.org/x/sys/unix/zerrors_linux_mips64.go index 20d51fb96..2da1bac1e 100644 --- a/vendor/golang.org/x/sys/unix/zerrors_linux_mips64.go +++ b/vendor/golang.org/x/sys/unix/zerrors_linux_mips64.go @@ -371,6 +371,7 @@ const ( SO_RCVBUFFORCE = 0x21 SO_RCVLOWAT = 0x1004 SO_RCVMARK = 0x4b + SO_RCVPRIORITY = 0x52 SO_RCVTIMEO = 0x1006 SO_RCVTIMEO_NEW = 0x42 SO_RCVTIMEO_OLD = 0x1006 diff --git a/vendor/golang.org/x/sys/unix/zerrors_linux_mips64le.go b/vendor/golang.org/x/sys/unix/zerrors_linux_mips64le.go index 321b60902..28727514b 100644 --- a/vendor/golang.org/x/sys/unix/zerrors_linux_mips64le.go +++ b/vendor/golang.org/x/sys/unix/zerrors_linux_mips64le.go @@ -371,6 +371,7 @@ const ( SO_RCVBUFFORCE = 0x21 SO_RCVLOWAT = 0x1004 SO_RCVMARK = 0x4b + SO_RCVPRIORITY = 0x52 SO_RCVTIMEO = 0x1006 SO_RCVTIMEO_NEW = 0x42 SO_RCVTIMEO_OLD = 0x1006 diff --git a/vendor/golang.org/x/sys/unix/zerrors_linux_mipsle.go b/vendor/golang.org/x/sys/unix/zerrors_linux_mipsle.go index 9bacdf1e2..7f287b54b 100644 --- a/vendor/golang.org/x/sys/unix/zerrors_linux_mipsle.go +++ b/vendor/golang.org/x/sys/unix/zerrors_linux_mipsle.go @@ -371,6 +371,7 @@ const ( SO_RCVBUFFORCE = 0x21 SO_RCVLOWAT = 0x1004 SO_RCVMARK = 0x4b + SO_RCVPRIORITY = 0x52 SO_RCVTIMEO = 0x1006 SO_RCVTIMEO_NEW = 0x42 SO_RCVTIMEO_OLD = 0x1006 diff --git a/vendor/golang.org/x/sys/unix/zerrors_linux_ppc.go b/vendor/golang.org/x/sys/unix/zerrors_linux_ppc.go index c22427261..7e5f9e6aa 100644 --- a/vendor/golang.org/x/sys/unix/zerrors_linux_ppc.go +++ b/vendor/golang.org/x/sys/unix/zerrors_linux_ppc.go @@ -426,6 +426,7 @@ const ( SO_RCVBUFFORCE = 0x21 SO_RCVLOWAT = 0x10 SO_RCVMARK = 0x4b + SO_RCVPRIORITY = 0x52 SO_RCVTIMEO = 0x12 SO_RCVTIMEO_NEW = 0x42 SO_RCVTIMEO_OLD = 0x12 diff --git a/vendor/golang.org/x/sys/unix/zerrors_linux_ppc64.go b/vendor/golang.org/x/sys/unix/zerrors_linux_ppc64.go index 6270c8ee1..37c87952f 100644 --- a/vendor/golang.org/x/sys/unix/zerrors_linux_ppc64.go +++ b/vendor/golang.org/x/sys/unix/zerrors_linux_ppc64.go @@ -430,6 +430,7 @@ const ( SO_RCVBUFFORCE = 0x21 SO_RCVLOWAT = 0x10 SO_RCVMARK = 0x4b + SO_RCVPRIORITY = 0x52 SO_RCVTIMEO = 0x12 SO_RCVTIMEO_NEW = 0x42 SO_RCVTIMEO_OLD = 0x12 diff --git a/vendor/golang.org/x/sys/unix/zerrors_linux_ppc64le.go b/vendor/golang.org/x/sys/unix/zerrors_linux_ppc64le.go index 9966c1941..522013361 100644 --- a/vendor/golang.org/x/sys/unix/zerrors_linux_ppc64le.go +++ b/vendor/golang.org/x/sys/unix/zerrors_linux_ppc64le.go @@ -430,6 +430,7 @@ const ( SO_RCVBUFFORCE = 0x21 SO_RCVLOWAT = 0x10 SO_RCVMARK = 0x4b + SO_RCVPRIORITY = 0x52 SO_RCVTIMEO = 0x12 SO_RCVTIMEO_NEW = 0x42 SO_RCVTIMEO_OLD = 0x12 diff --git a/vendor/golang.org/x/sys/unix/zerrors_linux_riscv64.go b/vendor/golang.org/x/sys/unix/zerrors_linux_riscv64.go index 848e5fcc4..4bfe2b5b6 100644 --- a/vendor/golang.org/x/sys/unix/zerrors_linux_riscv64.go +++ b/vendor/golang.org/x/sys/unix/zerrors_linux_riscv64.go @@ -362,6 +362,7 @@ const ( SO_RCVBUFFORCE = 0x21 SO_RCVLOWAT = 0x12 SO_RCVMARK = 0x4b + SO_RCVPRIORITY = 0x52 SO_RCVTIMEO = 0x14 SO_RCVTIMEO_NEW = 0x42 SO_RCVTIMEO_OLD = 0x14 diff --git a/vendor/golang.org/x/sys/unix/zerrors_linux_s390x.go b/vendor/golang.org/x/sys/unix/zerrors_linux_s390x.go index 669b2adb8..e3cffb869 100644 --- a/vendor/golang.org/x/sys/unix/zerrors_linux_s390x.go +++ b/vendor/golang.org/x/sys/unix/zerrors_linux_s390x.go @@ -434,6 +434,7 @@ const ( SO_RCVBUFFORCE = 0x21 SO_RCVLOWAT = 0x12 SO_RCVMARK = 0x4b + SO_RCVPRIORITY = 0x52 SO_RCVTIMEO = 0x14 SO_RCVTIMEO_NEW = 0x42 SO_RCVTIMEO_OLD = 0x14 diff --git a/vendor/golang.org/x/sys/unix/zerrors_linux_sparc64.go b/vendor/golang.org/x/sys/unix/zerrors_linux_sparc64.go index 4834e5751..c219c8db3 100644 --- a/vendor/golang.org/x/sys/unix/zerrors_linux_sparc64.go +++ b/vendor/golang.org/x/sys/unix/zerrors_linux_sparc64.go @@ -473,6 +473,7 @@ const ( SO_RCVBUFFORCE = 0x100b SO_RCVLOWAT = 0x800 SO_RCVMARK = 0x54 + SO_RCVPRIORITY = 0x5b SO_RCVTIMEO = 0x2000 SO_RCVTIMEO_NEW = 0x44 SO_RCVTIMEO_OLD = 0x2000 diff --git a/vendor/golang.org/x/sys/unix/ztypes_linux.go b/vendor/golang.org/x/sys/unix/ztypes_linux.go index a46abe647..8bcac2835 100644 --- a/vendor/golang.org/x/sys/unix/ztypes_linux.go +++ b/vendor/golang.org/x/sys/unix/ztypes_linux.go @@ -114,7 +114,7 @@ type Statx_t struct { Atomic_write_unit_min uint32 Atomic_write_unit_max uint32 Atomic_write_segments_max uint32 - _ [1]uint32 + Dio_read_offset_align uint32 _ [9]uint64 } @@ -2226,8 +2226,11 @@ const ( NFT_PAYLOAD_LL_HEADER = 0x0 NFT_PAYLOAD_NETWORK_HEADER = 0x1 NFT_PAYLOAD_TRANSPORT_HEADER = 0x2 + NFT_PAYLOAD_INNER_HEADER = 0x3 + NFT_PAYLOAD_TUN_HEADER = 0x4 NFT_PAYLOAD_CSUM_NONE = 0x0 NFT_PAYLOAD_CSUM_INET = 0x1 + NFT_PAYLOAD_CSUM_SCTP = 0x2 NFT_PAYLOAD_L4CSUM_PSEUDOHDR = 0x1 NFTA_PAYLOAD_UNSPEC = 0x0 NFTA_PAYLOAD_DREG = 0x1 @@ -3802,7 +3805,16 @@ const ( ETHTOOL_MSG_PSE_GET = 0x24 ETHTOOL_MSG_PSE_SET = 0x25 ETHTOOL_MSG_RSS_GET = 0x26 - ETHTOOL_MSG_USER_MAX = 0x2d + ETHTOOL_MSG_PLCA_GET_CFG = 0x27 + ETHTOOL_MSG_PLCA_SET_CFG = 0x28 + ETHTOOL_MSG_PLCA_GET_STATUS = 0x29 + ETHTOOL_MSG_MM_GET = 0x2a + ETHTOOL_MSG_MM_SET = 0x2b + ETHTOOL_MSG_MODULE_FW_FLASH_ACT = 0x2c + ETHTOOL_MSG_PHY_GET = 0x2d + ETHTOOL_MSG_TSCONFIG_GET = 0x2e + ETHTOOL_MSG_TSCONFIG_SET = 0x2f + ETHTOOL_MSG_USER_MAX = 0x2f ETHTOOL_MSG_KERNEL_NONE = 0x0 ETHTOOL_MSG_STRSET_GET_REPLY = 0x1 ETHTOOL_MSG_LINKINFO_GET_REPLY = 0x2 @@ -3842,7 +3854,17 @@ const ( ETHTOOL_MSG_MODULE_NTF = 0x24 ETHTOOL_MSG_PSE_GET_REPLY = 0x25 ETHTOOL_MSG_RSS_GET_REPLY = 0x26 - ETHTOOL_MSG_KERNEL_MAX = 0x2e + ETHTOOL_MSG_PLCA_GET_CFG_REPLY = 0x27 + ETHTOOL_MSG_PLCA_GET_STATUS_REPLY = 0x28 + ETHTOOL_MSG_PLCA_NTF = 0x29 + ETHTOOL_MSG_MM_GET_REPLY = 0x2a + ETHTOOL_MSG_MM_NTF = 0x2b + ETHTOOL_MSG_MODULE_FW_FLASH_NTF = 0x2c + ETHTOOL_MSG_PHY_GET_REPLY = 0x2d + ETHTOOL_MSG_PHY_NTF = 0x2e + ETHTOOL_MSG_TSCONFIG_GET_REPLY = 0x2f + ETHTOOL_MSG_TSCONFIG_SET_REPLY = 0x30 + ETHTOOL_MSG_KERNEL_MAX = 0x30 ETHTOOL_FLAG_COMPACT_BITSETS = 0x1 ETHTOOL_FLAG_OMIT_REPLY = 0x2 ETHTOOL_FLAG_STATS = 0x4 @@ -3949,7 +3971,12 @@ const ( ETHTOOL_A_RINGS_TCP_DATA_SPLIT = 0xb ETHTOOL_A_RINGS_CQE_SIZE = 0xc ETHTOOL_A_RINGS_TX_PUSH = 0xd - ETHTOOL_A_RINGS_MAX = 0x10 + ETHTOOL_A_RINGS_RX_PUSH = 0xe + ETHTOOL_A_RINGS_TX_PUSH_BUF_LEN = 0xf + ETHTOOL_A_RINGS_TX_PUSH_BUF_LEN_MAX = 0x10 + ETHTOOL_A_RINGS_HDS_THRESH = 0x11 + ETHTOOL_A_RINGS_HDS_THRESH_MAX = 0x12 + ETHTOOL_A_RINGS_MAX = 0x12 ETHTOOL_A_CHANNELS_UNSPEC = 0x0 ETHTOOL_A_CHANNELS_HEADER = 0x1 ETHTOOL_A_CHANNELS_RX_MAX = 0x2 @@ -4015,7 +4042,9 @@ const ( ETHTOOL_A_TSINFO_TX_TYPES = 0x3 ETHTOOL_A_TSINFO_RX_FILTERS = 0x4 ETHTOOL_A_TSINFO_PHC_INDEX = 0x5 - ETHTOOL_A_TSINFO_MAX = 0x6 + ETHTOOL_A_TSINFO_STATS = 0x6 + ETHTOOL_A_TSINFO_HWTSTAMP_PROVIDER = 0x7 + ETHTOOL_A_TSINFO_MAX = 0x7 ETHTOOL_A_CABLE_TEST_UNSPEC = 0x0 ETHTOOL_A_CABLE_TEST_HEADER = 0x1 ETHTOOL_A_CABLE_TEST_MAX = 0x1 @@ -4613,6 +4642,7 @@ const ( NL80211_ATTR_AKM_SUITES = 0x4c NL80211_ATTR_AP_ISOLATE = 0x60 NL80211_ATTR_AP_SETTINGS_FLAGS = 0x135 + NL80211_ATTR_ASSOC_SPP_AMSDU = 0x14a NL80211_ATTR_AUTH_DATA = 0x9c NL80211_ATTR_AUTH_TYPE = 0x35 NL80211_ATTR_BANDS = 0xef @@ -4623,6 +4653,7 @@ const ( NL80211_ATTR_BSS_BASIC_RATES = 0x24 NL80211_ATTR_BSS = 0x2f NL80211_ATTR_BSS_CTS_PROT = 0x1c + NL80211_ATTR_BSS_DUMP_INCLUDE_USE_DATA = 0x147 NL80211_ATTR_BSS_HT_OPMODE = 0x6d NL80211_ATTR_BSSID = 0xf5 NL80211_ATTR_BSS_SELECT = 0xe3 @@ -4682,6 +4713,7 @@ const ( NL80211_ATTR_DTIM_PERIOD = 0xd NL80211_ATTR_DURATION = 0x57 NL80211_ATTR_EHT_CAPABILITY = 0x136 + NL80211_ATTR_EMA_RNR_ELEMS = 0x145 NL80211_ATTR_EML_CAPABILITY = 0x13d NL80211_ATTR_EXT_CAPA = 0xa9 NL80211_ATTR_EXT_CAPA_MASK = 0xaa @@ -4717,6 +4749,7 @@ const ( NL80211_ATTR_HIDDEN_SSID = 0x7e NL80211_ATTR_HT_CAPABILITY = 0x1f NL80211_ATTR_HT_CAPABILITY_MASK = 0x94 + NL80211_ATTR_HW_TIMESTAMP_ENABLED = 0x144 NL80211_ATTR_IE_ASSOC_RESP = 0x80 NL80211_ATTR_IE = 0x2a NL80211_ATTR_IE_PROBE_RESP = 0x7f @@ -4747,9 +4780,10 @@ const ( NL80211_ATTR_MAC_HINT = 0xc8 NL80211_ATTR_MAC_MASK = 0xd7 NL80211_ATTR_MAX_AP_ASSOC_STA = 0xca - NL80211_ATTR_MAX = 0x14d + NL80211_ATTR_MAX = 0x150 NL80211_ATTR_MAX_CRIT_PROT_DURATION = 0xb4 NL80211_ATTR_MAX_CSA_COUNTERS = 0xce + NL80211_ATTR_MAX_HW_TIMESTAMP_PEERS = 0x143 NL80211_ATTR_MAX_MATCH_SETS = 0x85 NL80211_ATTR_MAX_NUM_AKM_SUITES = 0x13c NL80211_ATTR_MAX_NUM_PMKIDS = 0x56 @@ -4774,9 +4808,12 @@ const ( NL80211_ATTR_MGMT_SUBTYPE = 0x29 NL80211_ATTR_MLD_ADDR = 0x13a NL80211_ATTR_MLD_CAPA_AND_OPS = 0x13e + NL80211_ATTR_MLO_LINK_DISABLED = 0x146 NL80211_ATTR_MLO_LINK_ID = 0x139 NL80211_ATTR_MLO_LINKS = 0x138 NL80211_ATTR_MLO_SUPPORT = 0x13b + NL80211_ATTR_MLO_TTLM_DLINK = 0x148 + NL80211_ATTR_MLO_TTLM_ULINK = 0x149 NL80211_ATTR_MNTR_FLAGS = 0x17 NL80211_ATTR_MPATH_INFO = 0x1b NL80211_ATTR_MPATH_NEXT_HOP = 0x1a @@ -4809,12 +4846,14 @@ const ( NL80211_ATTR_PORT_AUTHORIZED = 0x103 NL80211_ATTR_POWER_RULE_MAX_ANT_GAIN = 0x5 NL80211_ATTR_POWER_RULE_MAX_EIRP = 0x6 + NL80211_ATTR_POWER_RULE_PSD = 0x8 NL80211_ATTR_PREV_BSSID = 0x4f NL80211_ATTR_PRIVACY = 0x46 NL80211_ATTR_PROBE_RESP = 0x91 NL80211_ATTR_PROBE_RESP_OFFLOAD = 0x90 NL80211_ATTR_PROTOCOL_FEATURES = 0xad NL80211_ATTR_PS_STATE = 0x5d + NL80211_ATTR_PUNCT_BITMAP = 0x142 NL80211_ATTR_QOS_MAP = 0xc7 NL80211_ATTR_RADAR_BACKGROUND = 0x134 NL80211_ATTR_RADAR_EVENT = 0xa8 @@ -4943,7 +4982,9 @@ const ( NL80211_ATTR_WIPHY_FREQ = 0x26 NL80211_ATTR_WIPHY_FREQ_HINT = 0xc9 NL80211_ATTR_WIPHY_FREQ_OFFSET = 0x122 + NL80211_ATTR_WIPHY_INTERFACE_COMBINATIONS = 0x14c NL80211_ATTR_WIPHY_NAME = 0x2 + NL80211_ATTR_WIPHY_RADIOS = 0x14b NL80211_ATTR_WIPHY_RETRY_LONG = 0x3e NL80211_ATTR_WIPHY_RETRY_SHORT = 0x3d NL80211_ATTR_WIPHY_RTS_THRESHOLD = 0x40 @@ -4978,6 +5019,8 @@ const ( NL80211_BAND_ATTR_IFTYPE_DATA = 0x9 NL80211_BAND_ATTR_MAX = 0xd NL80211_BAND_ATTR_RATES = 0x2 + NL80211_BAND_ATTR_S1G_CAPA = 0xd + NL80211_BAND_ATTR_S1G_MCS_NSS_SET = 0xc NL80211_BAND_ATTR_VHT_CAPA = 0x8 NL80211_BAND_ATTR_VHT_MCS_SET = 0x7 NL80211_BAND_IFTYPE_ATTR_EHT_CAP_MAC = 0x8 @@ -5001,6 +5044,10 @@ const ( NL80211_BSS_BEACON_INTERVAL = 0x4 NL80211_BSS_BEACON_TSF = 0xd NL80211_BSS_BSSID = 0x1 + NL80211_BSS_CANNOT_USE_6GHZ_PWR_MISMATCH = 0x2 + NL80211_BSS_CANNOT_USE_NSTR_NONPRIMARY = 0x1 + NL80211_BSS_CANNOT_USE_REASONS = 0x18 + NL80211_BSS_CANNOT_USE_UHB_PWR_MISMATCH = 0x2 NL80211_BSS_CAPABILITY = 0x5 NL80211_BSS_CHAIN_SIGNAL = 0x13 NL80211_BSS_CHAN_WIDTH_10 = 0x1 @@ -5032,6 +5079,9 @@ const ( NL80211_BSS_STATUS = 0x9 NL80211_BSS_STATUS_IBSS_JOINED = 0x2 NL80211_BSS_TSF = 0x3 + NL80211_BSS_USE_FOR = 0x17 + NL80211_BSS_USE_FOR_MLD_LINK = 0x2 + NL80211_BSS_USE_FOR_NORMAL = 0x1 NL80211_CHAN_HT20 = 0x1 NL80211_CHAN_HT40MINUS = 0x2 NL80211_CHAN_HT40PLUS = 0x3 @@ -5117,7 +5167,8 @@ const ( NL80211_CMD_LEAVE_IBSS = 0x2c NL80211_CMD_LEAVE_MESH = 0x45 NL80211_CMD_LEAVE_OCB = 0x6d - NL80211_CMD_MAX = 0x9b + NL80211_CMD_LINKS_REMOVED = 0x9a + NL80211_CMD_MAX = 0x9d NL80211_CMD_MICHAEL_MIC_FAILURE = 0x29 NL80211_CMD_MODIFY_LINK_STA = 0x97 NL80211_CMD_NAN_MATCH = 0x78 @@ -5161,6 +5212,7 @@ const ( NL80211_CMD_SET_COALESCE = 0x65 NL80211_CMD_SET_CQM = 0x3f NL80211_CMD_SET_FILS_AAD = 0x92 + NL80211_CMD_SET_HW_TIMESTAMP = 0x99 NL80211_CMD_SET_INTERFACE = 0x6 NL80211_CMD_SET_KEY = 0xa NL80211_CMD_SET_MAC_ACL = 0x5d @@ -5180,6 +5232,7 @@ const ( NL80211_CMD_SET_SAR_SPECS = 0x8c NL80211_CMD_SET_STATION = 0x12 NL80211_CMD_SET_TID_CONFIG = 0x89 + NL80211_CMD_SET_TID_TO_LINK_MAPPING = 0x9b NL80211_CMD_SET_TX_BITRATE_MASK = 0x39 NL80211_CMD_SET_WDS_PEER = 0x42 NL80211_CMD_SET_WIPHY = 0x2 @@ -5247,6 +5300,7 @@ const ( NL80211_EXT_FEATURE_AIRTIME_FAIRNESS = 0x21 NL80211_EXT_FEATURE_AP_PMKSA_CACHING = 0x22 NL80211_EXT_FEATURE_AQL = 0x28 + NL80211_EXT_FEATURE_AUTH_AND_DEAUTH_RANDOM_TA = 0x40 NL80211_EXT_FEATURE_BEACON_PROTECTION_CLIENT = 0x2e NL80211_EXT_FEATURE_BEACON_PROTECTION = 0x29 NL80211_EXT_FEATURE_BEACON_RATE_HE = 0x36 @@ -5262,6 +5316,7 @@ const ( NL80211_EXT_FEATURE_CQM_RSSI_LIST = 0xd NL80211_EXT_FEATURE_DATA_ACK_SIGNAL_SUPPORT = 0x1b NL80211_EXT_FEATURE_DEL_IBSS_STA = 0x2c + NL80211_EXT_FEATURE_DFS_CONCURRENT = 0x43 NL80211_EXT_FEATURE_DFS_OFFLOAD = 0x19 NL80211_EXT_FEATURE_ENABLE_FTM_RESPONDER = 0x20 NL80211_EXT_FEATURE_EXT_KEY_ID = 0x24 @@ -5281,9 +5336,12 @@ const ( NL80211_EXT_FEATURE_OCE_PROBE_REQ_DEFERRAL_SUPPRESSION = 0x14 NL80211_EXT_FEATURE_OCE_PROBE_REQ_HIGH_TX_RATE = 0x13 NL80211_EXT_FEATURE_OPERATING_CHANNEL_VALIDATION = 0x31 + NL80211_EXT_FEATURE_OWE_OFFLOAD_AP = 0x42 + NL80211_EXT_FEATURE_OWE_OFFLOAD = 0x41 NL80211_EXT_FEATURE_POWERED_ADDR_CHANGE = 0x3d NL80211_EXT_FEATURE_PROTECTED_TWT = 0x2b NL80211_EXT_FEATURE_PROT_RANGE_NEGO_AND_MEASURE = 0x39 + NL80211_EXT_FEATURE_PUNCT = 0x3e NL80211_EXT_FEATURE_RADAR_BACKGROUND = 0x3c NL80211_EXT_FEATURE_RRM = 0x1 NL80211_EXT_FEATURE_SAE_OFFLOAD_AP = 0x33 @@ -5295,8 +5353,10 @@ const ( NL80211_EXT_FEATURE_SCHED_SCAN_BAND_SPECIFIC_RSSI_THOLD = 0x23 NL80211_EXT_FEATURE_SCHED_SCAN_RELATIVE_RSSI = 0xc NL80211_EXT_FEATURE_SECURE_LTF = 0x37 + NL80211_EXT_FEATURE_SECURE_NAN = 0x3f NL80211_EXT_FEATURE_SECURE_RTT = 0x38 NL80211_EXT_FEATURE_SET_SCAN_DWELL = 0x5 + NL80211_EXT_FEATURE_SPP_AMSDU_SUPPORT = 0x44 NL80211_EXT_FEATURE_STA_TX_PWR = 0x25 NL80211_EXT_FEATURE_TXQS = 0x1c NL80211_EXT_FEATURE_UNSOL_BCAST_PROBE_RESP = 0x35 @@ -5343,7 +5403,10 @@ const ( NL80211_FREQUENCY_ATTR_2MHZ = 0x16 NL80211_FREQUENCY_ATTR_4MHZ = 0x17 NL80211_FREQUENCY_ATTR_8MHZ = 0x18 + NL80211_FREQUENCY_ATTR_ALLOW_6GHZ_VLP_AP = 0x21 + NL80211_FREQUENCY_ATTR_CAN_MONITOR = 0x20 NL80211_FREQUENCY_ATTR_DFS_CAC_TIME = 0xd + NL80211_FREQUENCY_ATTR_DFS_CONCURRENT = 0x1d NL80211_FREQUENCY_ATTR_DFS_STATE = 0x7 NL80211_FREQUENCY_ATTR_DFS_TIME = 0x8 NL80211_FREQUENCY_ATTR_DISABLED = 0x2 @@ -5357,6 +5420,8 @@ const ( NL80211_FREQUENCY_ATTR_NO_160MHZ = 0xc NL80211_FREQUENCY_ATTR_NO_20MHZ = 0x10 NL80211_FREQUENCY_ATTR_NO_320MHZ = 0x1a + NL80211_FREQUENCY_ATTR_NO_6GHZ_AFC_CLIENT = 0x1f + NL80211_FREQUENCY_ATTR_NO_6GHZ_VLP_CLIENT = 0x1e NL80211_FREQUENCY_ATTR_NO_80MHZ = 0xb NL80211_FREQUENCY_ATTR_NO_EHT = 0x1b NL80211_FREQUENCY_ATTR_NO_HE = 0x13 @@ -5364,8 +5429,11 @@ const ( NL80211_FREQUENCY_ATTR_NO_HT40_PLUS = 0xa NL80211_FREQUENCY_ATTR_NO_IBSS = 0x3 NL80211_FREQUENCY_ATTR_NO_IR = 0x3 + NL80211_FREQUENCY_ATTR_NO_UHB_AFC_CLIENT = 0x1f + NL80211_FREQUENCY_ATTR_NO_UHB_VLP_CLIENT = 0x1e NL80211_FREQUENCY_ATTR_OFFSET = 0x14 NL80211_FREQUENCY_ATTR_PASSIVE_SCAN = 0x3 + NL80211_FREQUENCY_ATTR_PSD = 0x1c NL80211_FREQUENCY_ATTR_RADAR = 0x5 NL80211_FREQUENCY_ATTR_WMM = 0x12 NL80211_FTM_RESP_ATTR_CIVICLOC = 0x3 @@ -5430,6 +5498,7 @@ const ( NL80211_IFTYPE_STATION = 0x2 NL80211_IFTYPE_UNSPECIFIED = 0x0 NL80211_IFTYPE_WDS = 0x5 + NL80211_KCK_EXT_LEN_32 = 0x20 NL80211_KCK_EXT_LEN = 0x18 NL80211_KCK_LEN = 0x10 NL80211_KEK_EXT_LEN = 0x20 @@ -5458,6 +5527,7 @@ const ( NL80211_MAX_SUPP_HT_RATES = 0x4d NL80211_MAX_SUPP_RATES = 0x20 NL80211_MAX_SUPP_REG_RULES = 0x80 + NL80211_MAX_SUPP_SELECTORS = 0x80 NL80211_MBSSID_CONFIG_ATTR_EMA = 0x5 NL80211_MBSSID_CONFIG_ATTR_INDEX = 0x3 NL80211_MBSSID_CONFIG_ATTR_MAX = 0x5 @@ -5703,11 +5773,16 @@ const ( NL80211_RADAR_PRE_CAC_EXPIRED = 0x4 NL80211_RATE_INFO_10_MHZ_WIDTH = 0xb NL80211_RATE_INFO_160_MHZ_WIDTH = 0xa + NL80211_RATE_INFO_16_MHZ_WIDTH = 0x1d + NL80211_RATE_INFO_1_MHZ_WIDTH = 0x19 + NL80211_RATE_INFO_2_MHZ_WIDTH = 0x1a NL80211_RATE_INFO_320_MHZ_WIDTH = 0x12 NL80211_RATE_INFO_40_MHZ_WIDTH = 0x3 + NL80211_RATE_INFO_4_MHZ_WIDTH = 0x1b NL80211_RATE_INFO_5_MHZ_WIDTH = 0xc NL80211_RATE_INFO_80_MHZ_WIDTH = 0x8 NL80211_RATE_INFO_80P80_MHZ_WIDTH = 0x9 + NL80211_RATE_INFO_8_MHZ_WIDTH = 0x1c NL80211_RATE_INFO_BITRATE32 = 0x5 NL80211_RATE_INFO_BITRATE = 0x1 NL80211_RATE_INFO_EHT_GI_0_8 = 0x0 @@ -5753,6 +5828,8 @@ const ( NL80211_RATE_INFO_HE_RU_ALLOC = 0x11 NL80211_RATE_INFO_MAX = 0x1d NL80211_RATE_INFO_MCS = 0x2 + NL80211_RATE_INFO_S1G_MCS = 0x17 + NL80211_RATE_INFO_S1G_NSS = 0x18 NL80211_RATE_INFO_SHORT_GI = 0x4 NL80211_RATE_INFO_VHT_MCS = 0x6 NL80211_RATE_INFO_VHT_NSS = 0x7 @@ -5770,14 +5847,19 @@ const ( NL80211_REKEY_DATA_KEK = 0x1 NL80211_REKEY_DATA_REPLAY_CTR = 0x3 NL80211_REPLAY_CTR_LEN = 0x8 + NL80211_RRF_ALLOW_6GHZ_VLP_AP = 0x1000000 NL80211_RRF_AUTO_BW = 0x800 NL80211_RRF_DFS = 0x10 + NL80211_RRF_DFS_CONCURRENT = 0x200000 NL80211_RRF_GO_CONCURRENT = 0x1000 NL80211_RRF_IR_CONCURRENT = 0x1000 NL80211_RRF_NO_160MHZ = 0x10000 NL80211_RRF_NO_320MHZ = 0x40000 + NL80211_RRF_NO_6GHZ_AFC_CLIENT = 0x800000 + NL80211_RRF_NO_6GHZ_VLP_CLIENT = 0x400000 NL80211_RRF_NO_80MHZ = 0x8000 NL80211_RRF_NO_CCK = 0x2 + NL80211_RRF_NO_EHT = 0x80000 NL80211_RRF_NO_HE = 0x20000 NL80211_RRF_NO_HT40 = 0x6000 NL80211_RRF_NO_HT40MINUS = 0x2000 @@ -5788,7 +5870,10 @@ const ( NL80211_RRF_NO_IR = 0x80 NL80211_RRF_NO_OFDM = 0x1 NL80211_RRF_NO_OUTDOOR = 0x8 + NL80211_RRF_NO_UHB_AFC_CLIENT = 0x800000 + NL80211_RRF_NO_UHB_VLP_CLIENT = 0x400000 NL80211_RRF_PASSIVE_SCAN = 0x80 + NL80211_RRF_PSD = 0x100000 NL80211_RRF_PTMP_ONLY = 0x40 NL80211_RRF_PTP_ONLY = 0x20 NL80211_RXMGMT_FLAG_ANSWERED = 0x1 @@ -5849,6 +5934,7 @@ const ( NL80211_STA_FLAG_MAX_OLD_API = 0x6 NL80211_STA_FLAG_MFP = 0x4 NL80211_STA_FLAG_SHORT_PREAMBLE = 0x2 + NL80211_STA_FLAG_SPP_AMSDU = 0x8 NL80211_STA_FLAG_TDLS_PEER = 0x6 NL80211_STA_FLAG_WME = 0x3 NL80211_STA_INFO_ACK_SIGNAL_AVG = 0x23 @@ -6007,6 +6093,13 @@ const ( NL80211_VHT_CAPABILITY_LEN = 0xc NL80211_VHT_NSS_MAX = 0x8 NL80211_WIPHY_NAME_MAXLEN = 0x40 + NL80211_WIPHY_RADIO_ATTR_FREQ_RANGE = 0x2 + NL80211_WIPHY_RADIO_ATTR_INDEX = 0x1 + NL80211_WIPHY_RADIO_ATTR_INTERFACE_COMBINATION = 0x3 + NL80211_WIPHY_RADIO_ATTR_MAX = 0x4 + NL80211_WIPHY_RADIO_FREQ_ATTR_END = 0x2 + NL80211_WIPHY_RADIO_FREQ_ATTR_MAX = 0x2 + NL80211_WIPHY_RADIO_FREQ_ATTR_START = 0x1 NL80211_WMMR_AIFSN = 0x3 NL80211_WMMR_CW_MAX = 0x2 NL80211_WMMR_CW_MIN = 0x1 @@ -6038,6 +6131,7 @@ const ( NL80211_WOWLAN_TRIG_PKT_PATTERN = 0x4 NL80211_WOWLAN_TRIG_RFKILL_RELEASE = 0x9 NL80211_WOWLAN_TRIG_TCP_CONNECTION = 0xe + NL80211_WOWLAN_TRIG_UNPROTECTED_DEAUTH_DISASSOC = 0x14 NL80211_WOWLAN_TRIG_WAKEUP_PKT_80211 = 0xa NL80211_WOWLAN_TRIG_WAKEUP_PKT_80211_LEN = 0xb NL80211_WOWLAN_TRIG_WAKEUP_PKT_8023 = 0xc diff --git a/vendor/golang.org/x/sys/unix/ztypes_linux_386.go b/vendor/golang.org/x/sys/unix/ztypes_linux_386.go index fd402da43..62db85f6c 100644 --- a/vendor/golang.org/x/sys/unix/ztypes_linux_386.go +++ b/vendor/golang.org/x/sys/unix/ztypes_linux_386.go @@ -285,10 +285,16 @@ type Taskstats struct { _ [4]byte Cpu_count uint64 Cpu_delay_total uint64 + Cpu_delay_max uint64 + Cpu_delay_min uint64 Blkio_count uint64 Blkio_delay_total uint64 + Blkio_delay_max uint64 + Blkio_delay_min uint64 Swapin_count uint64 Swapin_delay_total uint64 + Swapin_delay_max uint64 + Swapin_delay_min uint64 Cpu_run_real_total uint64 Cpu_run_virtual_total uint64 Ac_comm [32]int8 @@ -324,11 +330,17 @@ type Taskstats struct { Cpu_scaled_run_real_total uint64 Freepages_count uint64 Freepages_delay_total uint64 + Freepages_delay_max uint64 + Freepages_delay_min uint64 Thrashing_count uint64 Thrashing_delay_total uint64 + Thrashing_delay_max uint64 + Thrashing_delay_min uint64 Ac_btime64 uint64 Compact_count uint64 Compact_delay_total uint64 + Compact_delay_max uint64 + Compact_delay_min uint64 Ac_tgid uint32 _ [4]byte Ac_tgetime uint64 @@ -336,8 +348,12 @@ type Taskstats struct { Ac_exe_inode uint64 Wpcopy_count uint64 Wpcopy_delay_total uint64 + Wpcopy_delay_max uint64 + Wpcopy_delay_min uint64 Irq_count uint64 Irq_delay_total uint64 + Irq_delay_max uint64 + Irq_delay_min uint64 } type cpuMask uint32 diff --git a/vendor/golang.org/x/sys/unix/ztypes_linux_amd64.go b/vendor/golang.org/x/sys/unix/ztypes_linux_amd64.go index eb7a5e186..7d89d648d 100644 --- a/vendor/golang.org/x/sys/unix/ztypes_linux_amd64.go +++ b/vendor/golang.org/x/sys/unix/ztypes_linux_amd64.go @@ -300,10 +300,16 @@ type Taskstats struct { Ac_nice uint8 Cpu_count uint64 Cpu_delay_total uint64 + Cpu_delay_max uint64 + Cpu_delay_min uint64 Blkio_count uint64 Blkio_delay_total uint64 + Blkio_delay_max uint64 + Blkio_delay_min uint64 Swapin_count uint64 Swapin_delay_total uint64 + Swapin_delay_max uint64 + Swapin_delay_min uint64 Cpu_run_real_total uint64 Cpu_run_virtual_total uint64 Ac_comm [32]int8 @@ -338,19 +344,29 @@ type Taskstats struct { Cpu_scaled_run_real_total uint64 Freepages_count uint64 Freepages_delay_total uint64 + Freepages_delay_max uint64 + Freepages_delay_min uint64 Thrashing_count uint64 Thrashing_delay_total uint64 + Thrashing_delay_max uint64 + Thrashing_delay_min uint64 Ac_btime64 uint64 Compact_count uint64 Compact_delay_total uint64 + Compact_delay_max uint64 + Compact_delay_min uint64 Ac_tgid uint32 Ac_tgetime uint64 Ac_exe_dev uint64 Ac_exe_inode uint64 Wpcopy_count uint64 Wpcopy_delay_total uint64 + Wpcopy_delay_max uint64 + Wpcopy_delay_min uint64 Irq_count uint64 Irq_delay_total uint64 + Irq_delay_max uint64 + Irq_delay_min uint64 } type cpuMask uint64 diff --git a/vendor/golang.org/x/sys/unix/ztypes_linux_arm.go b/vendor/golang.org/x/sys/unix/ztypes_linux_arm.go index d78ac108b..9c0b39eec 100644 --- a/vendor/golang.org/x/sys/unix/ztypes_linux_arm.go +++ b/vendor/golang.org/x/sys/unix/ztypes_linux_arm.go @@ -276,10 +276,16 @@ type Taskstats struct { _ [4]byte Cpu_count uint64 Cpu_delay_total uint64 + Cpu_delay_max uint64 + Cpu_delay_min uint64 Blkio_count uint64 Blkio_delay_total uint64 + Blkio_delay_max uint64 + Blkio_delay_min uint64 Swapin_count uint64 Swapin_delay_total uint64 + Swapin_delay_max uint64 + Swapin_delay_min uint64 Cpu_run_real_total uint64 Cpu_run_virtual_total uint64 Ac_comm [32]uint8 @@ -315,11 +321,17 @@ type Taskstats struct { Cpu_scaled_run_real_total uint64 Freepages_count uint64 Freepages_delay_total uint64 + Freepages_delay_max uint64 + Freepages_delay_min uint64 Thrashing_count uint64 Thrashing_delay_total uint64 + Thrashing_delay_max uint64 + Thrashing_delay_min uint64 Ac_btime64 uint64 Compact_count uint64 Compact_delay_total uint64 + Compact_delay_max uint64 + Compact_delay_min uint64 Ac_tgid uint32 _ [4]byte Ac_tgetime uint64 @@ -327,8 +339,12 @@ type Taskstats struct { Ac_exe_inode uint64 Wpcopy_count uint64 Wpcopy_delay_total uint64 + Wpcopy_delay_max uint64 + Wpcopy_delay_min uint64 Irq_count uint64 Irq_delay_total uint64 + Irq_delay_max uint64 + Irq_delay_min uint64 } type cpuMask uint32 diff --git a/vendor/golang.org/x/sys/unix/ztypes_linux_arm64.go b/vendor/golang.org/x/sys/unix/ztypes_linux_arm64.go index cd06d47f1..de9c7ff36 100644 --- a/vendor/golang.org/x/sys/unix/ztypes_linux_arm64.go +++ b/vendor/golang.org/x/sys/unix/ztypes_linux_arm64.go @@ -279,10 +279,16 @@ type Taskstats struct { Ac_nice uint8 Cpu_count uint64 Cpu_delay_total uint64 + Cpu_delay_max uint64 + Cpu_delay_min uint64 Blkio_count uint64 Blkio_delay_total uint64 + Blkio_delay_max uint64 + Blkio_delay_min uint64 Swapin_count uint64 Swapin_delay_total uint64 + Swapin_delay_max uint64 + Swapin_delay_min uint64 Cpu_run_real_total uint64 Cpu_run_virtual_total uint64 Ac_comm [32]int8 @@ -317,19 +323,29 @@ type Taskstats struct { Cpu_scaled_run_real_total uint64 Freepages_count uint64 Freepages_delay_total uint64 + Freepages_delay_max uint64 + Freepages_delay_min uint64 Thrashing_count uint64 Thrashing_delay_total uint64 + Thrashing_delay_max uint64 + Thrashing_delay_min uint64 Ac_btime64 uint64 Compact_count uint64 Compact_delay_total uint64 + Compact_delay_max uint64 + Compact_delay_min uint64 Ac_tgid uint32 Ac_tgetime uint64 Ac_exe_dev uint64 Ac_exe_inode uint64 Wpcopy_count uint64 Wpcopy_delay_total uint64 + Wpcopy_delay_max uint64 + Wpcopy_delay_min uint64 Irq_count uint64 Irq_delay_total uint64 + Irq_delay_max uint64 + Irq_delay_min uint64 } type cpuMask uint64 diff --git a/vendor/golang.org/x/sys/unix/ztypes_linux_loong64.go b/vendor/golang.org/x/sys/unix/ztypes_linux_loong64.go index 2f28fe26c..2336bd2bf 100644 --- a/vendor/golang.org/x/sys/unix/ztypes_linux_loong64.go +++ b/vendor/golang.org/x/sys/unix/ztypes_linux_loong64.go @@ -280,10 +280,16 @@ type Taskstats struct { Ac_nice uint8 Cpu_count uint64 Cpu_delay_total uint64 + Cpu_delay_max uint64 + Cpu_delay_min uint64 Blkio_count uint64 Blkio_delay_total uint64 + Blkio_delay_max uint64 + Blkio_delay_min uint64 Swapin_count uint64 Swapin_delay_total uint64 + Swapin_delay_max uint64 + Swapin_delay_min uint64 Cpu_run_real_total uint64 Cpu_run_virtual_total uint64 Ac_comm [32]int8 @@ -318,19 +324,29 @@ type Taskstats struct { Cpu_scaled_run_real_total uint64 Freepages_count uint64 Freepages_delay_total uint64 + Freepages_delay_max uint64 + Freepages_delay_min uint64 Thrashing_count uint64 Thrashing_delay_total uint64 + Thrashing_delay_max uint64 + Thrashing_delay_min uint64 Ac_btime64 uint64 Compact_count uint64 Compact_delay_total uint64 + Compact_delay_max uint64 + Compact_delay_min uint64 Ac_tgid uint32 Ac_tgetime uint64 Ac_exe_dev uint64 Ac_exe_inode uint64 Wpcopy_count uint64 Wpcopy_delay_total uint64 + Wpcopy_delay_max uint64 + Wpcopy_delay_min uint64 Irq_count uint64 Irq_delay_total uint64 + Irq_delay_max uint64 + Irq_delay_min uint64 } type cpuMask uint64 diff --git a/vendor/golang.org/x/sys/unix/ztypes_linux_mips.go b/vendor/golang.org/x/sys/unix/ztypes_linux_mips.go index 71d6cac2f..4711f0be1 100644 --- a/vendor/golang.org/x/sys/unix/ztypes_linux_mips.go +++ b/vendor/golang.org/x/sys/unix/ztypes_linux_mips.go @@ -281,10 +281,16 @@ type Taskstats struct { _ [4]byte Cpu_count uint64 Cpu_delay_total uint64 + Cpu_delay_max uint64 + Cpu_delay_min uint64 Blkio_count uint64 Blkio_delay_total uint64 + Blkio_delay_max uint64 + Blkio_delay_min uint64 Swapin_count uint64 Swapin_delay_total uint64 + Swapin_delay_max uint64 + Swapin_delay_min uint64 Cpu_run_real_total uint64 Cpu_run_virtual_total uint64 Ac_comm [32]int8 @@ -320,11 +326,17 @@ type Taskstats struct { Cpu_scaled_run_real_total uint64 Freepages_count uint64 Freepages_delay_total uint64 + Freepages_delay_max uint64 + Freepages_delay_min uint64 Thrashing_count uint64 Thrashing_delay_total uint64 + Thrashing_delay_max uint64 + Thrashing_delay_min uint64 Ac_btime64 uint64 Compact_count uint64 Compact_delay_total uint64 + Compact_delay_max uint64 + Compact_delay_min uint64 Ac_tgid uint32 _ [4]byte Ac_tgetime uint64 @@ -332,8 +344,12 @@ type Taskstats struct { Ac_exe_inode uint64 Wpcopy_count uint64 Wpcopy_delay_total uint64 + Wpcopy_delay_max uint64 + Wpcopy_delay_min uint64 Irq_count uint64 Irq_delay_total uint64 + Irq_delay_max uint64 + Irq_delay_min uint64 } type cpuMask uint32 diff --git a/vendor/golang.org/x/sys/unix/ztypes_linux_mips64.go b/vendor/golang.org/x/sys/unix/ztypes_linux_mips64.go index 8596d4535..ab99a34b9 100644 --- a/vendor/golang.org/x/sys/unix/ztypes_linux_mips64.go +++ b/vendor/golang.org/x/sys/unix/ztypes_linux_mips64.go @@ -282,10 +282,16 @@ type Taskstats struct { Ac_nice uint8 Cpu_count uint64 Cpu_delay_total uint64 + Cpu_delay_max uint64 + Cpu_delay_min uint64 Blkio_count uint64 Blkio_delay_total uint64 + Blkio_delay_max uint64 + Blkio_delay_min uint64 Swapin_count uint64 Swapin_delay_total uint64 + Swapin_delay_max uint64 + Swapin_delay_min uint64 Cpu_run_real_total uint64 Cpu_run_virtual_total uint64 Ac_comm [32]int8 @@ -320,19 +326,29 @@ type Taskstats struct { Cpu_scaled_run_real_total uint64 Freepages_count uint64 Freepages_delay_total uint64 + Freepages_delay_max uint64 + Freepages_delay_min uint64 Thrashing_count uint64 Thrashing_delay_total uint64 + Thrashing_delay_max uint64 + Thrashing_delay_min uint64 Ac_btime64 uint64 Compact_count uint64 Compact_delay_total uint64 + Compact_delay_max uint64 + Compact_delay_min uint64 Ac_tgid uint32 Ac_tgetime uint64 Ac_exe_dev uint64 Ac_exe_inode uint64 Wpcopy_count uint64 Wpcopy_delay_total uint64 + Wpcopy_delay_max uint64 + Wpcopy_delay_min uint64 Irq_count uint64 Irq_delay_total uint64 + Irq_delay_max uint64 + Irq_delay_min uint64 } type cpuMask uint64 diff --git a/vendor/golang.org/x/sys/unix/ztypes_linux_mips64le.go b/vendor/golang.org/x/sys/unix/ztypes_linux_mips64le.go index cd60ea186..04c9866e3 100644 --- a/vendor/golang.org/x/sys/unix/ztypes_linux_mips64le.go +++ b/vendor/golang.org/x/sys/unix/ztypes_linux_mips64le.go @@ -282,10 +282,16 @@ type Taskstats struct { Ac_nice uint8 Cpu_count uint64 Cpu_delay_total uint64 + Cpu_delay_max uint64 + Cpu_delay_min uint64 Blkio_count uint64 Blkio_delay_total uint64 + Blkio_delay_max uint64 + Blkio_delay_min uint64 Swapin_count uint64 Swapin_delay_total uint64 + Swapin_delay_max uint64 + Swapin_delay_min uint64 Cpu_run_real_total uint64 Cpu_run_virtual_total uint64 Ac_comm [32]int8 @@ -320,19 +326,29 @@ type Taskstats struct { Cpu_scaled_run_real_total uint64 Freepages_count uint64 Freepages_delay_total uint64 + Freepages_delay_max uint64 + Freepages_delay_min uint64 Thrashing_count uint64 Thrashing_delay_total uint64 + Thrashing_delay_max uint64 + Thrashing_delay_min uint64 Ac_btime64 uint64 Compact_count uint64 Compact_delay_total uint64 + Compact_delay_max uint64 + Compact_delay_min uint64 Ac_tgid uint32 Ac_tgetime uint64 Ac_exe_dev uint64 Ac_exe_inode uint64 Wpcopy_count uint64 Wpcopy_delay_total uint64 + Wpcopy_delay_max uint64 + Wpcopy_delay_min uint64 Irq_count uint64 Irq_delay_total uint64 + Irq_delay_max uint64 + Irq_delay_min uint64 } type cpuMask uint64 diff --git a/vendor/golang.org/x/sys/unix/ztypes_linux_mipsle.go b/vendor/golang.org/x/sys/unix/ztypes_linux_mipsle.go index b0ae420c4..60aa69f61 100644 --- a/vendor/golang.org/x/sys/unix/ztypes_linux_mipsle.go +++ b/vendor/golang.org/x/sys/unix/ztypes_linux_mipsle.go @@ -281,10 +281,16 @@ type Taskstats struct { _ [4]byte Cpu_count uint64 Cpu_delay_total uint64 + Cpu_delay_max uint64 + Cpu_delay_min uint64 Blkio_count uint64 Blkio_delay_total uint64 + Blkio_delay_max uint64 + Blkio_delay_min uint64 Swapin_count uint64 Swapin_delay_total uint64 + Swapin_delay_max uint64 + Swapin_delay_min uint64 Cpu_run_real_total uint64 Cpu_run_virtual_total uint64 Ac_comm [32]int8 @@ -320,11 +326,17 @@ type Taskstats struct { Cpu_scaled_run_real_total uint64 Freepages_count uint64 Freepages_delay_total uint64 + Freepages_delay_max uint64 + Freepages_delay_min uint64 Thrashing_count uint64 Thrashing_delay_total uint64 + Thrashing_delay_max uint64 + Thrashing_delay_min uint64 Ac_btime64 uint64 Compact_count uint64 Compact_delay_total uint64 + Compact_delay_max uint64 + Compact_delay_min uint64 Ac_tgid uint32 _ [4]byte Ac_tgetime uint64 @@ -332,8 +344,12 @@ type Taskstats struct { Ac_exe_inode uint64 Wpcopy_count uint64 Wpcopy_delay_total uint64 + Wpcopy_delay_max uint64 + Wpcopy_delay_min uint64 Irq_count uint64 Irq_delay_total uint64 + Irq_delay_max uint64 + Irq_delay_min uint64 } type cpuMask uint32 diff --git a/vendor/golang.org/x/sys/unix/ztypes_linux_ppc.go b/vendor/golang.org/x/sys/unix/ztypes_linux_ppc.go index 835972875..cb4fad785 100644 --- a/vendor/golang.org/x/sys/unix/ztypes_linux_ppc.go +++ b/vendor/golang.org/x/sys/unix/ztypes_linux_ppc.go @@ -288,10 +288,16 @@ type Taskstats struct { _ [4]byte Cpu_count uint64 Cpu_delay_total uint64 + Cpu_delay_max uint64 + Cpu_delay_min uint64 Blkio_count uint64 Blkio_delay_total uint64 + Blkio_delay_max uint64 + Blkio_delay_min uint64 Swapin_count uint64 Swapin_delay_total uint64 + Swapin_delay_max uint64 + Swapin_delay_min uint64 Cpu_run_real_total uint64 Cpu_run_virtual_total uint64 Ac_comm [32]uint8 @@ -327,11 +333,17 @@ type Taskstats struct { Cpu_scaled_run_real_total uint64 Freepages_count uint64 Freepages_delay_total uint64 + Freepages_delay_max uint64 + Freepages_delay_min uint64 Thrashing_count uint64 Thrashing_delay_total uint64 + Thrashing_delay_max uint64 + Thrashing_delay_min uint64 Ac_btime64 uint64 Compact_count uint64 Compact_delay_total uint64 + Compact_delay_max uint64 + Compact_delay_min uint64 Ac_tgid uint32 _ [4]byte Ac_tgetime uint64 @@ -339,8 +351,12 @@ type Taskstats struct { Ac_exe_inode uint64 Wpcopy_count uint64 Wpcopy_delay_total uint64 + Wpcopy_delay_max uint64 + Wpcopy_delay_min uint64 Irq_count uint64 Irq_delay_total uint64 + Irq_delay_max uint64 + Irq_delay_min uint64 } type cpuMask uint32 diff --git a/vendor/golang.org/x/sys/unix/ztypes_linux_ppc64.go b/vendor/golang.org/x/sys/unix/ztypes_linux_ppc64.go index 69eb6a5c6..60272cfce 100644 --- a/vendor/golang.org/x/sys/unix/ztypes_linux_ppc64.go +++ b/vendor/golang.org/x/sys/unix/ztypes_linux_ppc64.go @@ -289,10 +289,16 @@ type Taskstats struct { Ac_nice uint8 Cpu_count uint64 Cpu_delay_total uint64 + Cpu_delay_max uint64 + Cpu_delay_min uint64 Blkio_count uint64 Blkio_delay_total uint64 + Blkio_delay_max uint64 + Blkio_delay_min uint64 Swapin_count uint64 Swapin_delay_total uint64 + Swapin_delay_max uint64 + Swapin_delay_min uint64 Cpu_run_real_total uint64 Cpu_run_virtual_total uint64 Ac_comm [32]uint8 @@ -327,19 +333,29 @@ type Taskstats struct { Cpu_scaled_run_real_total uint64 Freepages_count uint64 Freepages_delay_total uint64 + Freepages_delay_max uint64 + Freepages_delay_min uint64 Thrashing_count uint64 Thrashing_delay_total uint64 + Thrashing_delay_max uint64 + Thrashing_delay_min uint64 Ac_btime64 uint64 Compact_count uint64 Compact_delay_total uint64 + Compact_delay_max uint64 + Compact_delay_min uint64 Ac_tgid uint32 Ac_tgetime uint64 Ac_exe_dev uint64 Ac_exe_inode uint64 Wpcopy_count uint64 Wpcopy_delay_total uint64 + Wpcopy_delay_max uint64 + Wpcopy_delay_min uint64 Irq_count uint64 Irq_delay_total uint64 + Irq_delay_max uint64 + Irq_delay_min uint64 } type cpuMask uint64 diff --git a/vendor/golang.org/x/sys/unix/ztypes_linux_ppc64le.go b/vendor/golang.org/x/sys/unix/ztypes_linux_ppc64le.go index 5f583cb62..3f5b91bc0 100644 --- a/vendor/golang.org/x/sys/unix/ztypes_linux_ppc64le.go +++ b/vendor/golang.org/x/sys/unix/ztypes_linux_ppc64le.go @@ -289,10 +289,16 @@ type Taskstats struct { Ac_nice uint8 Cpu_count uint64 Cpu_delay_total uint64 + Cpu_delay_max uint64 + Cpu_delay_min uint64 Blkio_count uint64 Blkio_delay_total uint64 + Blkio_delay_max uint64 + Blkio_delay_min uint64 Swapin_count uint64 Swapin_delay_total uint64 + Swapin_delay_max uint64 + Swapin_delay_min uint64 Cpu_run_real_total uint64 Cpu_run_virtual_total uint64 Ac_comm [32]uint8 @@ -327,19 +333,29 @@ type Taskstats struct { Cpu_scaled_run_real_total uint64 Freepages_count uint64 Freepages_delay_total uint64 + Freepages_delay_max uint64 + Freepages_delay_min uint64 Thrashing_count uint64 Thrashing_delay_total uint64 + Thrashing_delay_max uint64 + Thrashing_delay_min uint64 Ac_btime64 uint64 Compact_count uint64 Compact_delay_total uint64 + Compact_delay_max uint64 + Compact_delay_min uint64 Ac_tgid uint32 Ac_tgetime uint64 Ac_exe_dev uint64 Ac_exe_inode uint64 Wpcopy_count uint64 Wpcopy_delay_total uint64 + Wpcopy_delay_max uint64 + Wpcopy_delay_min uint64 Irq_count uint64 Irq_delay_total uint64 + Irq_delay_max uint64 + Irq_delay_min uint64 } type cpuMask uint64 diff --git a/vendor/golang.org/x/sys/unix/ztypes_linux_riscv64.go b/vendor/golang.org/x/sys/unix/ztypes_linux_riscv64.go index ad05b51a6..51550f15a 100644 --- a/vendor/golang.org/x/sys/unix/ztypes_linux_riscv64.go +++ b/vendor/golang.org/x/sys/unix/ztypes_linux_riscv64.go @@ -307,10 +307,16 @@ type Taskstats struct { Ac_nice uint8 Cpu_count uint64 Cpu_delay_total uint64 + Cpu_delay_max uint64 + Cpu_delay_min uint64 Blkio_count uint64 Blkio_delay_total uint64 + Blkio_delay_max uint64 + Blkio_delay_min uint64 Swapin_count uint64 Swapin_delay_total uint64 + Swapin_delay_max uint64 + Swapin_delay_min uint64 Cpu_run_real_total uint64 Cpu_run_virtual_total uint64 Ac_comm [32]uint8 @@ -345,19 +351,29 @@ type Taskstats struct { Cpu_scaled_run_real_total uint64 Freepages_count uint64 Freepages_delay_total uint64 + Freepages_delay_max uint64 + Freepages_delay_min uint64 Thrashing_count uint64 Thrashing_delay_total uint64 + Thrashing_delay_max uint64 + Thrashing_delay_min uint64 Ac_btime64 uint64 Compact_count uint64 Compact_delay_total uint64 + Compact_delay_max uint64 + Compact_delay_min uint64 Ac_tgid uint32 Ac_tgetime uint64 Ac_exe_dev uint64 Ac_exe_inode uint64 Wpcopy_count uint64 Wpcopy_delay_total uint64 + Wpcopy_delay_max uint64 + Wpcopy_delay_min uint64 Irq_count uint64 Irq_delay_total uint64 + Irq_delay_max uint64 + Irq_delay_min uint64 } type cpuMask uint64 diff --git a/vendor/golang.org/x/sys/unix/ztypes_linux_s390x.go b/vendor/golang.org/x/sys/unix/ztypes_linux_s390x.go index cf3ce9003..3239e50e0 100644 --- a/vendor/golang.org/x/sys/unix/ztypes_linux_s390x.go +++ b/vendor/golang.org/x/sys/unix/ztypes_linux_s390x.go @@ -302,10 +302,16 @@ type Taskstats struct { Ac_nice uint8 Cpu_count uint64 Cpu_delay_total uint64 + Cpu_delay_max uint64 + Cpu_delay_min uint64 Blkio_count uint64 Blkio_delay_total uint64 + Blkio_delay_max uint64 + Blkio_delay_min uint64 Swapin_count uint64 Swapin_delay_total uint64 + Swapin_delay_max uint64 + Swapin_delay_min uint64 Cpu_run_real_total uint64 Cpu_run_virtual_total uint64 Ac_comm [32]int8 @@ -340,19 +346,29 @@ type Taskstats struct { Cpu_scaled_run_real_total uint64 Freepages_count uint64 Freepages_delay_total uint64 + Freepages_delay_max uint64 + Freepages_delay_min uint64 Thrashing_count uint64 Thrashing_delay_total uint64 + Thrashing_delay_max uint64 + Thrashing_delay_min uint64 Ac_btime64 uint64 Compact_count uint64 Compact_delay_total uint64 + Compact_delay_max uint64 + Compact_delay_min uint64 Ac_tgid uint32 Ac_tgetime uint64 Ac_exe_dev uint64 Ac_exe_inode uint64 Wpcopy_count uint64 Wpcopy_delay_total uint64 + Wpcopy_delay_max uint64 + Wpcopy_delay_min uint64 Irq_count uint64 Irq_delay_total uint64 + Irq_delay_max uint64 + Irq_delay_min uint64 } type cpuMask uint64 diff --git a/vendor/golang.org/x/sys/unix/ztypes_linux_sparc64.go b/vendor/golang.org/x/sys/unix/ztypes_linux_sparc64.go index 590b56739..faf200278 100644 --- a/vendor/golang.org/x/sys/unix/ztypes_linux_sparc64.go +++ b/vendor/golang.org/x/sys/unix/ztypes_linux_sparc64.go @@ -284,10 +284,16 @@ type Taskstats struct { Ac_nice uint8 Cpu_count uint64 Cpu_delay_total uint64 + Cpu_delay_max uint64 + Cpu_delay_min uint64 Blkio_count uint64 Blkio_delay_total uint64 + Blkio_delay_max uint64 + Blkio_delay_min uint64 Swapin_count uint64 Swapin_delay_total uint64 + Swapin_delay_max uint64 + Swapin_delay_min uint64 Cpu_run_real_total uint64 Cpu_run_virtual_total uint64 Ac_comm [32]int8 @@ -322,19 +328,29 @@ type Taskstats struct { Cpu_scaled_run_real_total uint64 Freepages_count uint64 Freepages_delay_total uint64 + Freepages_delay_max uint64 + Freepages_delay_min uint64 Thrashing_count uint64 Thrashing_delay_total uint64 + Thrashing_delay_max uint64 + Thrashing_delay_min uint64 Ac_btime64 uint64 Compact_count uint64 Compact_delay_total uint64 + Compact_delay_max uint64 + Compact_delay_min uint64 Ac_tgid uint32 Ac_tgetime uint64 Ac_exe_dev uint64 Ac_exe_inode uint64 Wpcopy_count uint64 Wpcopy_delay_total uint64 + Wpcopy_delay_max uint64 + Wpcopy_delay_min uint64 Irq_count uint64 Irq_delay_total uint64 + Irq_delay_max uint64 + Irq_delay_min uint64 } type cpuMask uint64 diff --git a/vendor/modules.txt b/vendor/modules.txt index 90746caf9..5e4393444 100644 --- a/vendor/modules.txt +++ b/vendor/modules.txt @@ -18,8 +18,8 @@ github.com/Microsoft/go-winio/internal/socket github.com/Microsoft/go-winio/internal/stringbuffer github.com/Microsoft/go-winio/pkg/guid github.com/Microsoft/go-winio/vhd -# github.com/Microsoft/hcsshim v0.12.9 -## explicit; go 1.22 +# github.com/Microsoft/hcsshim v0.13.0 +## explicit; go 1.23.0 github.com/Microsoft/hcsshim github.com/Microsoft/hcsshim/computestorage github.com/Microsoft/hcsshim/internal/cow @@ -121,7 +121,7 @@ github.com/containers/libtrust # github.com/containers/ocicrypt v1.2.1 ## explicit; go 1.22 github.com/containers/ocicrypt/spec -# github.com/containers/storage v1.58.0 +# github.com/containers/storage v1.59.1 ## explicit; go 1.23.0 github.com/containers/storage github.com/containers/storage/drivers @@ -136,6 +136,9 @@ github.com/containers/storage/drivers/vfs github.com/containers/storage/drivers/windows github.com/containers/storage/drivers/zfs github.com/containers/storage/internal/dedup +github.com/containers/storage/internal/rawfilelock +github.com/containers/storage/internal/staging_lockfile +github.com/containers/storage/internal/tempdir github.com/containers/storage/pkg/archive github.com/containers/storage/pkg/chrootarchive github.com/containers/storage/pkg/chunked @@ -352,7 +355,7 @@ github.com/spf13/pflag # github.com/sylabs/sif/v2 v2.21.1 ## explicit; go 1.23.0 github.com/sylabs/sif/v2/pkg/sif -# github.com/tchap/go-patricia/v2 v2.3.2 +# github.com/tchap/go-patricia/v2 v2.3.3 ## explicit; go 1.16 github.com/tchap/go-patricia/v2/patricia # github.com/ulikunitz/xz v0.5.12 @@ -416,10 +419,10 @@ golang.org/x/mod/semver # golang.org/x/net v0.40.0 ## explicit; go 1.23.0 golang.org/x/net/context -# golang.org/x/sync v0.13.0 +# golang.org/x/sync v0.16.0 ## explicit; go 1.23.0 golang.org/x/sync/errgroup -# golang.org/x/sys v0.33.0 +# golang.org/x/sys v0.34.0 ## explicit; go 1.23.0 golang.org/x/sys/unix golang.org/x/sys/windows