lib/fs: properly call windows APIs (#6998)

Previously we manually imported system windows DDLs
and made direct syscall.

 But golang exposes syscall wrappers with sys/windows package.
It seems, that direct syscall was broken at 1.23 golang release. It was
`GetDiskFreeSpace` syscall in our case.

This commit replaces all manual syscalls with wrappers

Related issue:
https://github.com/VictoriaMetrics/VictoriaMetrics/issues/6973

Related golang issue:
https://github.com/golang/go/issues/69029

Signed-off-by: f41gh7 <nik@victoriametrics.com>
This commit is contained in:
Nikolay 2024-09-13 12:22:25 +02:00 committed by GitHub
parent 8207879fa3
commit 264c2ec6bd
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
2 changed files with 11 additions and 29 deletions

View file

@ -31,7 +31,8 @@ See also [LTS releases](https://docs.victoriametrics.com/lts-releases/).
* BUGFIX: [vmagent](https://docs.victoriametrics.com/vmagent/) fix service discovery of Azure Virtual Machines for response contains `nextLink` in `Host:Port` format. See [this issue](https://github.com/VictoriaMetrics/VictoriaMetrics/issues/6912). * BUGFIX: [vmagent](https://docs.victoriametrics.com/vmagent/) fix service discovery of Azure Virtual Machines for response contains `nextLink` in `Host:Port` format. See [this issue](https://github.com/VictoriaMetrics/VictoriaMetrics/issues/6912).
* BUGFIX: [vmagent dashboard](https://github.com/VictoriaMetrics/VictoriaMetrics/blob/master/dashboards/vmagent.json): fix legend captions for stream aggregation related panels. Before they were displaying wrong label names. * BUGFIX: [vmagent dashboard](https://github.com/VictoriaMetrics/VictoriaMetrics/blob/master/dashboards/vmagent.json): fix legend captions for stream aggregation related panels. Before they were displaying wrong label names.
* BUGFIX: [vmgateway](https://docs.victoriametrics.com/vmgateway/): add missing `datadog`, `newrelic`, `opentelemetry` and `pushgateway` routes to the `JWT` authorization routes. Allows prefixed (`prometheus/graphite`) routes for query requests. * BUGFIX: [vmgateway](https://docs.victoriametrics.com/vmgateway/): add missing `datadog`, `newrelic`, `opentelemetry` and `pushgateway` routes to the `JWT` authorization routes. Allows prefixed (`promtheus/graphite`) routes for query requests.
* BUGFIX: [Single-node VictoriaMetrics](https://docs.victoriametrics.com/) and `vmstorage` in [VictoriaMetrics cluster](https://docs.victoriametrics.com/cluster-victoriametrics/): Fixes start-up crash on Windows OS. See this [issue](https://github.com/VictoriaMetrics/VictoriaMetrics/issues/6973) for details.
* BUGFIX: [Single-node VictoriaMetrics](https://docs.victoriametrics.com/) and `vmstorage` in [VictoriaMetrics cluster](https://docs.victoriametrics.com/cluster-victoriametrics/): fix metric `vm_object_references{type="indexdb"}`. Previously, it was overcounted. * BUGFIX: [Single-node VictoriaMetrics](https://docs.victoriametrics.com/) and `vmstorage` in [VictoriaMetrics cluster](https://docs.victoriametrics.com/cluster-victoriametrics/): fix metric `vm_object_references{type="indexdb"}`. Previously, it was overcounted.
* BUGFIX: [Single-node VictoriaMetrics](https://docs.victoriametrics.com/) and `vmstorage` in [VictoriaMetrics cluster](https://docs.victoriametrics.com/cluster-victoriametrics/): properly ingest stale NaN samples. Previously it could be dropped if series didn't exist at storage node. See this issue [https://github.com/VictoriaMetrics/VictoriaMetrics/issues/5069] for details. * BUGFIX: [Single-node VictoriaMetrics](https://docs.victoriametrics.com/) and `vmstorage` in [VictoriaMetrics cluster](https://docs.victoriametrics.com/cluster-victoriametrics/): properly ingest stale NaN samples. Previously it could be dropped if series didn't exist at storage node. See this issue [https://github.com/VictoriaMetrics/VictoriaMetrics/issues/5069] for details.

View file

@ -10,13 +10,6 @@ import (
"golang.org/x/sys/windows" "golang.org/x/sys/windows"
) )
var (
kernelDLL = windows.MustLoadDLL("kernel32.dll")
procLock = kernelDLL.MustFindProc("LockFileEx")
procEvent = kernelDLL.MustFindProc("CreateEventW")
procDisk = kernelDLL.MustFindProc("GetDiskFreeSpaceExW")
)
// at windows only files could be synced // at windows only files could be synced
// Sync for directories is not supported. // Sync for directories is not supported.
func mustSyncPath(path string) { func mustSyncPath(path string) {
@ -61,8 +54,8 @@ func createFlockFile(flockFile string) (*os.File, error) {
return nil, fmt.Errorf("cannot create Overlapped handler: %w", err) return nil, fmt.Errorf("cannot create Overlapped handler: %w", err)
} }
// https://docs.microsoft.com/en-us/windows/win32/api/fileapi/nf-fileapi-lockfileex // https://docs.microsoft.com/en-us/windows/win32/api/fileapi/nf-fileapi-lockfileex
r1, _, err := procLock.Call(uintptr(handle), uintptr(lockfileExclusiveLock), uintptr(0), uintptr(1), uintptr(0), uintptr(unsafe.Pointer(ol))) err = windows.LockFileEx(handle, lockfileExclusiveLock, 0, 0, 0, ol)
if r1 == 0 { if err != nil {
return nil, err return nil, err
} }
return os.NewFile(uintptr(handle), flockFile), nil return os.NewFile(uintptr(handle), flockFile), nil
@ -118,13 +111,13 @@ func mUnmap(data []byte) error {
} }
func mustGetFreeSpace(path string) uint64 { func mustGetFreeSpace(path string) uint64 {
var freeBytes int64 var freeBytes uint64
r, _, err := procDisk.Call(uintptr(unsafe.Pointer(windows.StringToUTF16Ptr(path))), // https://learn.microsoft.com/en-us/windows/win32/api/fileapi/nf-fileapi-getdiskfreespaceexw
uintptr(unsafe.Pointer(&freeBytes))) err := windows.GetDiskFreeSpaceEx(windows.StringToUTF16Ptr(path), &freeBytes, nil, nil)
if r == 0 { if err != nil {
logger.Panicf("FATAL: cannot get free space for %q : %s", path, err) logger.Panicf("FATAL: cannot get free space for %q : %s", path, err)
} }
return uint64(freeBytes) return freeBytes
} }
// stub // stub
@ -132,23 +125,11 @@ func fadviseSequentialRead(f *os.File, prefetch bool) error {
return nil return nil
} }
// copied from https://github.com/juju/fslock/blob/master/fslock_windows.go
// https://docs.microsoft.com/en-us/windows/win32/api/minwinbase/ns-minwinbase-overlapped // https://docs.microsoft.com/en-us/windows/win32/api/minwinbase/ns-minwinbase-overlapped
func newOverlapped() (*windows.Overlapped, error) { func newOverlapped() (*windows.Overlapped, error) {
event, err := createEvent(nil, nil) event, err := windows.CreateEvent(nil, 1, 1, nil)
if err != nil { if err != nil {
return nil, err return nil, fmt.Errorf("cannot create event: %w", err)
} }
return &windows.Overlapped{HEvent: event}, nil return &windows.Overlapped{HEvent: event}, nil
} }
// copied from https://github.com/juju/fslock/blob/master/fslock_windows.go
// https://docs.microsoft.com/en-us/windows/win32/api/synchapi/nf-synchapi-createeventa
func createEvent(sa *windows.SecurityAttributes, name *uint16) (windows.Handle, error) {
r0, _, err := procEvent.Call(uintptr(unsafe.Pointer(sa)), uintptr(1), uintptr(1), uintptr(unsafe.Pointer(name)))
handle := windows.Handle(r0)
if handle == windows.InvalidHandle {
return 0, err
}
return handle, nil
}