From 28b7a83e12247d5504f66ece0b29187c5459bf25 Mon Sep 17 00:00:00 2001 From: Zhongcheng Lao Date: Fri, 20 Jun 2025 12:56:48 +0800 Subject: [PATCH 1/3] Move WMI functions to cim package --- pkg/cim/disk.go | 103 ++++++++++++++++++++++++++ pkg/cim/smb.go | 53 +++++++++++++- pkg/cim/volume.go | 151 +++++++++++++++++++++++++++++++++++++++ pkg/cim/wmi.go | 13 ++-- pkg/os/disk/api.go | 82 +++++++++------------ pkg/os/filesystem/api.go | 11 ++- pkg/os/smb/api.go | 68 ++---------------- pkg/os/volume/api.go | 131 +++++++++------------------------ pkg/utils/utils.go | 75 ++++++++++++++++--- 9 files changed, 461 insertions(+), 226 deletions(-) diff --git a/pkg/cim/disk.go b/pkg/cim/disk.go index 0298b793..58c8f376 100644 --- a/pkg/cim/disk.go +++ b/pkg/cim/disk.go @@ -23,6 +23,17 @@ const ( // GPTPartitionTypeMicrosoftReserved is the GUID for Microsoft Reserved Partition (MSR) // Reserved by Windows for system use GPTPartitionTypeMicrosoftReserved = "{e3c9e316-0b5c-4db8-817d-f92df00215ae}" + + // ErrorCodeCreatePartitionAccessPathAlreadyInUse is the error code (42002) returned when the driver letter failed to assign after partition created + ErrorCodeCreatePartitionAccessPathAlreadyInUse = 42002 +) + +var ( + DiskSelectorListForDiskNumberAndLocation = []string{"Number", "Location"} + DiskSelectorListForPartitionStyle = []string{"PartitionStyle"} + DiskSelectorListForPathAndSerialNumber = []string{"Path", "SerialNumber"} + DiskSelectorListForIsOffline = []string{"IsOffline"} + DiskSelectorListForSize = []string{"Size"} ) // QueryDiskByNumber retrieves disk information for a specific disk identified by its number. @@ -77,6 +88,60 @@ func ListDisks(selectorList []string) ([]*storage.MSFT_Disk, error) { return disks, nil } +// InitializeDisk initializes a RAW disk with a particular partition style. +// +// Refer to https://learn.microsoft.com/en-us/windows-hardware/drivers/storage/initialize-msft-disk +// for the WMI method definition. +func InitializeDisk(disk *storage.MSFT_Disk, partitionStyle int) (int, error) { + result, err := disk.InvokeMethodWithReturn("Initialize", int32(partitionStyle)) + return int(result), err +} + +// RefreshDisk Refreshes the cached disk layout information. +// +// Refer to https://learn.microsoft.com/en-us/windows-hardware/drivers/storage/msft-disk-refresh +// for the WMI method definition. +func RefreshDisk(disk *storage.MSFT_Disk) (int, string, error) { + var status string + result, err := disk.InvokeMethodWithReturn("Refresh", &status) + return int(result), status, err +} + +// CreatePartition creates a partition on a disk. +// +// Refer to https://learn.microsoft.com/en-us/windows-hardware/drivers/storage/createpartition-msft-disk +// for the WMI method definition. +func CreatePartition(disk *storage.MSFT_Disk, params ...interface{}) (int, error) { + result, err := disk.InvokeMethodWithReturn("CreatePartition", params...) + return int(result), err +} + +// SetDiskState takes a disk online or offline. +// +// Refer to https://learn.microsoft.com/en-us/windows-hardware/drivers/storage/msft-disk-online and +// https://learn.microsoft.com/en-us/windows-hardware/drivers/storage/msft-disk-offline +// for the WMI method definition. +func SetDiskState(disk *storage.MSFT_Disk, online bool) (int, string, error) { + method := "Offline" + if online { + method = "Online" + } + + var status string + result, err := disk.InvokeMethodWithReturn(method, &status) + return int(result), status, err +} + +// RescanDisks rescans all changes by updating the internal cache of software objects (that is, Disks, Partitions, Volumes) +// for the storage setting. +// +// Refer to https://learn.microsoft.com/en-us/windows-hardware/drivers/storage/msft-storagesetting-updatehoststoragecache +// for the WMI method definition. +func RescanDisks() (int, error) { + result, _, err := InvokeCimMethod(WMINamespaceStorage, "MSFT_StorageSetting", "UpdateHostStorageCache", nil) + return result, err +} + // GetDiskNumber returns the number of a disk. func GetDiskNumber(disk *storage.MSFT_Disk) (uint32, error) { number, err := disk.GetProperty("Number") @@ -85,3 +150,41 @@ func GetDiskNumber(disk *storage.MSFT_Disk) (uint32, error) { } return uint32(number.(int32)), err } + +// GetDiskLocation returns the location of a disk. +func GetDiskLocation(disk *storage.MSFT_Disk) (string, error) { + return disk.GetPropertyLocation() +} + +// GetDiskPartitionStyle returns the partition style of a disk. +func GetDiskPartitionStyle(disk *storage.MSFT_Disk) (int32, error) { + retValue, err := disk.GetProperty("PartitionStyle") + if err != nil { + return 0, err + } + return retValue.(int32), err +} + +// IsDiskOffline returns whether a disk is offline. +func IsDiskOffline(disk *storage.MSFT_Disk) (bool, error) { + return disk.GetPropertyIsOffline() +} + +// GetDiskSize returns the size of a disk. +func GetDiskSize(disk *storage.MSFT_Disk) (int64, error) { + sz, err := disk.GetProperty("Size") + if err != nil { + return -1, err + } + return strconv.ParseInt(sz.(string), 10, 64) +} + +// GetDiskPath returns the path of a disk. +func GetDiskPath(disk *storage.MSFT_Disk) (string, error) { + return disk.GetPropertyPath() +} + +// GetDiskSerialNumber returns the serial number of a disk. +func GetDiskSerialNumber(disk *storage.MSFT_Disk) (string, error) { + return disk.GetPropertySerialNumber() +} diff --git a/pkg/cim/smb.go b/pkg/cim/smb.go index 5868d456..2850ab78 100644 --- a/pkg/cim/smb.go +++ b/pkg/cim/smb.go @@ -4,6 +4,8 @@ package cim import ( + "strings" + "github.com/microsoft/wmi/pkg/base/query" cim "github.com/microsoft/wmi/pkg/wmiinstance" ) @@ -17,8 +19,24 @@ const ( SmbMappingStatusConnecting SmbMappingStatusReconnecting SmbMappingStatusUnavailable + + credentialDelimiter = ":" ) +// escapeQueryParameter escapes a parameter for WMI Queries +func escapeQueryParameter(s string) string { + s = strings.ReplaceAll(s, "'", "''") + s = strings.ReplaceAll(s, "\\", "\\\\") + return s +} + +func escapeUserName(userName string) string { + // refer to https://github.com/PowerShell/PowerShell/blob/9303de597da55963a6e26a8fe164d0b256ca3d4d/src/Microsoft.PowerShell.Commands.Management/cimSupport/cmdletization/cim/cimConverter.cs#L169-L170 + userName = strings.ReplaceAll(userName, "\\", "\\\\") + userName = strings.ReplaceAll(userName, credentialDelimiter, "\\"+credentialDelimiter) + return userName +} + // QuerySmbGlobalMappingByRemotePath retrieves the SMB global mapping from its remote path. // // The equivalent WMI query is: @@ -28,7 +46,7 @@ const ( // Refer to https://pkg.go.dev/github.com/microsoft/wmi/server2019/root/microsoft/windows/smb#MSFT_SmbGlobalMapping // for the WMI class definition. func QuerySmbGlobalMappingByRemotePath(remotePath string) (*cim.WmiInstance, error) { - smbQuery := query.NewWmiQuery("MSFT_SmbGlobalMapping", "RemotePath", remotePath) + smbQuery := query.NewWmiQuery("MSFT_SmbGlobalMapping", "RemotePath", escapeQueryParameter(remotePath)) instances, err := QueryInstances(WMINamespaceSmb, smbQuery) if err != nil { return nil, err @@ -37,12 +55,22 @@ func QuerySmbGlobalMappingByRemotePath(remotePath string) (*cim.WmiInstance, err return instances[0], err } -// RemoveSmbGlobalMappingByRemotePath removes a SMB global mapping matching to the remote path. +// GetSmbGlobalMappingStatus returns the status of an SMB global mapping. +func GetSmbGlobalMappingStatus(inst *cim.WmiInstance) (int32, error) { + statusProp, err := inst.GetProperty("Status") + if err != nil { + return SmbMappingStatusUnavailable, err + } + + return statusProp.(int32), nil +} + +// RemoveSmbGlobalMappingByRemotePath removes an SMB global mapping matching to the remote path. // // Refer to https://pkg.go.dev/github.com/microsoft/wmi/server2019/root/microsoft/windows/smb#MSFT_SmbGlobalMapping // for the WMI class definition. func RemoveSmbGlobalMappingByRemotePath(remotePath string) error { - smbQuery := query.NewWmiQuery("MSFT_SmbGlobalMapping", "RemotePath", remotePath) + smbQuery := query.NewWmiQuery("MSFT_SmbGlobalMapping", "RemotePath", escapeQueryParameter(remotePath)) instances, err := QueryInstances(WMINamespaceSmb, smbQuery) if err != nil { return err @@ -51,3 +79,22 @@ func RemoveSmbGlobalMappingByRemotePath(remotePath string) error { _, err = instances[0].InvokeMethod("Remove", true) return err } + +// NewSmbGlobalMapping creates a new SMB global mapping to the remote path. +// +// Refer to https://pkg.go.dev/github.com/microsoft/wmi/server2019/root/microsoft/windows/smb#MSFT_SmbGlobalMapping +// for the WMI class definition. +func NewSmbGlobalMapping(remotePath, username, password string, requirePrivacy bool) (int, error) { + params := map[string]interface{}{ + "RemotePath": remotePath, + "RequirePrivacy": requirePrivacy, + } + if username != "" { + // refer to https://github.com/PowerShell/PowerShell/blob/9303de597da55963a6e26a8fe164d0b256ca3d4d/src/Microsoft.PowerShell.Commands.Management/cimSupport/cmdletization/cim/cimConverter.cs#L166-L178 + // on how SMB credential is handled in PowerShell + params["Credential"] = escapeUserName(username) + credentialDelimiter + password + } + + result, _, err := InvokeCimMethod(WMINamespaceSmb, "MSFT_SmbGlobalMapping", "Create", params) + return result, err +} diff --git a/pkg/cim/volume.go b/pkg/cim/volume.go index b77fd6d6..0c880fe1 100644 --- a/pkg/cim/volume.go +++ b/pkg/cim/volume.go @@ -7,9 +7,23 @@ import ( "fmt" "strconv" + "github.com/go-ole/go-ole" "github.com/microsoft/wmi/pkg/base/query" "github.com/microsoft/wmi/pkg/errors" "github.com/microsoft/wmi/server2019/root/microsoft/windows/storage" + "k8s.io/klog/v2" +) + +const ( + FileSystemUnknown = 0 +) + +var ( + VolumeSelectorListForFileSystemType = []string{"FileSystemType"} + VolumeSelectorListForStats = []string{"UniqueId", "SizeRemaining", "Size"} + VolumeSelectorListUniqueID = []string{"UniqueId"} + + PartitionSelectorListObjectID = []string{"ObjectId"} ) // QueryVolumeByUniqueID retrieves a specific volume by its unique identifier, @@ -78,6 +92,68 @@ func ListVolumes(selectorList []string) ([]*storage.MSFT_Volume, error) { return volumes, nil } +// FormatVolume formats the specified volume. +// +// Refer to https://learn.microsoft.com/en-us/windows-hardware/drivers/storage/format-msft-volume +// for the WMI method definition. +func FormatVolume(volume *storage.MSFT_Volume, params ...interface{}) (int, error) { + result, err := volume.InvokeMethodWithReturn("Format", params...) + return int(result), err +} + +// FlushVolume flushes the cached data in the volume's file system to disk. +// +// Refer to https://learn.microsoft.com/en-us/windows-hardware/drivers/storage/msft-volume-flush +// for the WMI method definition. +func FlushVolume(volume *storage.MSFT_Volume) (int, error) { + result, err := volume.Flush() + return int(result), err +} + +// GetVolumeUniqueID returns the unique ID (object ID) of a volume. +func GetVolumeUniqueID(volume *storage.MSFT_Volume) (string, error) { + return volume.GetPropertyUniqueId() +} + +// GetVolumeFileSystemType returns the file system type of a volume. +func GetVolumeFileSystemType(volume *storage.MSFT_Volume) (int32, error) { + fsType, err := volume.GetProperty("FileSystemType") + if err != nil { + return 0, err + } + return fsType.(int32), nil +} + +// GetVolumeSize returns the size of a volume. +func GetVolumeSize(volume *storage.MSFT_Volume) (int64, error) { + volumeSizeVal, err := volume.GetProperty("Size") + if err != nil { + return -1, err + } + + volumeSize, err := strconv.ParseInt(volumeSizeVal.(string), 10, 64) + if err != nil { + return -1, err + } + + return volumeSize, err +} + +// GetVolumeSizeRemaining returns the remaining size of a volume. +func GetVolumeSizeRemaining(volume *storage.MSFT_Volume) (int64, error) { + volumeSizeRemainingVal, err := volume.GetProperty("SizeRemaining") + if err != nil { + return -1, err + } + + volumeSizeRemaining, err := strconv.ParseInt(volumeSizeRemainingVal.(string), 10, 64) + if err != nil { + return -1, err + } + + return volumeSizeRemaining, err +} + // ListPartitionsOnDisk retrieves all partitions or a partition with the specified number on a disk. // // The equivalent WMI query is: @@ -245,3 +321,78 @@ func GetPartitionDiskNumber(part *storage.MSFT_Partition) (uint32, error) { return uint32(diskNumber.(int32)), nil } + +// SetPartitionState takes a partition online or offline. +// +// Refer to https://learn.microsoft.com/en-us/windows-hardware/drivers/storage/msft-partition-online and +// https://learn.microsoft.com/en-us/windows-hardware/drivers/storage/msft-partition-offline +// for the WMI method definition. +func SetPartitionState(part *storage.MSFT_Partition, online bool) (int, string, error) { + method := "Offline" + if online { + method = "Online" + } + + var status string + result, err := part.InvokeMethodWithReturn(method, &status) + return int(result), status, err +} + +// GetPartitionSupportedSize retrieves the minimum and maximum sizes that the partition can be resized to using the ResizePartition method. +// +// Refer to https://learn.microsoft.com/en-us/windows-hardware/drivers/storage/msft-partition-getsupportedsizes +// for the WMI method definition. +func GetPartitionSupportedSize(part *storage.MSFT_Partition) (result int, sizeMin, sizeMax int64, status string, err error) { + sizeMin = -1 + sizeMax = -1 + + var sizeMinVar, sizeMaxVar ole.VARIANT + invokeResult, err := part.InvokeMethodWithReturn("GetSupportedSize", &sizeMinVar, &sizeMaxVar, &status) + if invokeResult != 0 || err != nil { + result = int(invokeResult) + } + klog.V(5).Infof("got sizeMin (%v) sizeMax (%v) from partition (%v), status: %s", sizeMinVar, sizeMaxVar, part, status) + + sizeMin, err = strconv.ParseInt(sizeMinVar.ToString(), 10, 64) + if err != nil { + return + } + + sizeMax, err = strconv.ParseInt(sizeMaxVar.ToString(), 10, 64) + return +} + +// ResizePartition resizes a partition. +// +// Refer to https://learn.microsoft.com/en-us/windows-hardware/drivers/storage/msft-partition-resize +// for the WMI method definition. +func ResizePartition(part *storage.MSFT_Partition, size int64) (int, string, error) { + var status string + result, err := part.InvokeMethodWithReturn("Resize", strconv.Itoa(int(size)), &status) + return int(result), status, err +} + +// GetPartitionSize returns the size of a partition. +func GetPartitionSize(part *storage.MSFT_Partition) (int64, error) { + sizeProp, err := part.GetProperty("Size") + if err != nil { + return -1, err + } + + size, err := strconv.ParseInt(sizeProp.(string), 10, 64) + if err != nil { + return -1, err + } + + return size, err +} + +// FilterForPartitionOnDisk creates a WMI query filter to query a disk by its number. +func FilterForPartitionOnDisk(diskNumber uint32) *query.WmiQueryFilter { + return query.NewWmiQueryFilter("DiskNumber", strconv.Itoa(int(diskNumber)), query.Equals) +} + +// FilterForPartitionsOfTypeNormal creates a WMI query filter for all non-reserved partitions. +func FilterForPartitionsOfTypeNormal() *query.WmiQueryFilter { + return query.NewWmiQueryFilter("GptType", GPTPartitionTypeMicrosoftReserved, query.NotEquals) +} diff --git a/pkg/cim/wmi.go b/pkg/cim/wmi.go index 1dacce8a..ba75f747 100644 --- a/pkg/cim/wmi.go +++ b/pkg/cim/wmi.go @@ -9,7 +9,7 @@ import ( "github.com/go-ole/go-ole" "github.com/go-ole/go-ole/oleutil" "github.com/microsoft/wmi/pkg/base/query" - "github.com/microsoft/wmi/pkg/errors" + wmierrors "github.com/microsoft/wmi/pkg/errors" cim "github.com/microsoft/wmi/pkg/wmiinstance" "k8s.io/klog/v2" ) @@ -61,7 +61,7 @@ func QueryFromWMI(namespace string, query *query.WmiQuery, handler InstanceHandl } if len(instances) == 0 { - return errors.NotFound + return wmierrors.NotFound } var cont bool @@ -95,7 +95,7 @@ func executeClassMethodParam(classInst *cim.WmiInstance, method *cim.WmiMethod, iDispatchInstance := classInst.GetIDispatch() if iDispatchInstance == nil { - return nil, errors.Wrapf(errors.InvalidInput, "InvalidInstance") + return nil, wmierrors.Wrapf(wmierrors.InvalidInput, "InvalidInstance") } rawResult, err := iDispatchInstance.GetProperty("Methods_") if err != nil { @@ -235,10 +235,15 @@ func InvokeCimMethod(namespace, class, methodName string, inputParameters map[st return int(result.ReturnValue), outputParameters, nil } +// IsNotFound returns true if it's a "not found" error. +func IsNotFound(err error) bool { + return wmierrors.IsNotFound(err) +} + // IgnoreNotFound returns nil if the error is nil or a "not found" error, // otherwise returns the original error. func IgnoreNotFound(err error) error { - if err == nil || errors.IsNotFound(err) { + if err == nil || IsNotFound(err) { return nil } return err diff --git a/pkg/os/disk/api.go b/pkg/os/disk/api.go index dc8637fd..b366b977 100644 --- a/pkg/os/disk/api.go +++ b/pkg/os/disk/api.go @@ -3,14 +3,12 @@ package disk import ( "encoding/hex" "fmt" - "strconv" "strings" "syscall" "unsafe" "github.com/kubernetes-csi/csi-proxy/pkg/cim" shared "github.com/kubernetes-csi/csi-proxy/pkg/shared/disk" - "github.com/microsoft/wmi/pkg/base/query" "k8s.io/klog/v2" ) @@ -67,19 +65,19 @@ func New() DiskAPI { // as the value. The DiskLocation struct has various fields like the Adapter, Bus, Target and LUNID. func (imp DiskAPI) ListDiskLocations() (map[uint32]shared.DiskLocation, error) { // "location": "PCI Slot 3 : Adapter 0 : Port 0 : Target 1 : LUN 0" - disks, err := cim.ListDisks([]string{"Number", "Location"}) + disks, err := cim.ListDisks(cim.DiskSelectorListForDiskNumberAndLocation) if err != nil { return nil, fmt.Errorf("could not query disk locations") } m := make(map[uint32]shared.DiskLocation) for _, disk := range disks { - num, err := disk.GetProperty("Number") + num, err := cim.GetDiskNumber(disk) if err != nil { return m, fmt.Errorf("failed to query disk number: %v, %w", disk, err) } - location, err := disk.GetPropertyLocation() + location, err := cim.GetDiskLocation(disk) if err != nil { return m, fmt.Errorf("failed to query disk location: %v, %w", disk, err) } @@ -107,7 +105,7 @@ func (imp DiskAPI) ListDiskLocations() (map[uint32]shared.DiskLocation, error) { } if found { - m[uint32(num.(int32))] = d + m[num] = d } } } @@ -116,7 +114,7 @@ func (imp DiskAPI) ListDiskLocations() (map[uint32]shared.DiskLocation, error) { } func (imp DiskAPI) Rescan() error { - result, _, err := cim.InvokeCimMethod(cim.WMINamespaceStorage, "MSFT_StorageSetting", "UpdateHostStorageCache", nil) + result, err := cim.RescanDisks() if err != nil { return fmt.Errorf("error updating host storage cache output. result: %d, err: %v", result, err) } @@ -124,18 +122,16 @@ func (imp DiskAPI) Rescan() error { } func (imp DiskAPI) IsDiskInitialized(diskNumber uint32) (bool, error) { - var partitionStyle int32 - disk, err := cim.QueryDiskByNumber(diskNumber, []string{"PartitionStyle"}) + disk, err := cim.QueryDiskByNumber(diskNumber, cim.DiskSelectorListForPartitionStyle) if err != nil { - return false, fmt.Errorf("error checking initialized status of disk %d. %v", diskNumber, err) + return false, fmt.Errorf("error checking initialized status of disk %d: %v", diskNumber, err) } - retValue, err := disk.GetProperty("PartitionStyle") + partitionStyle, err := cim.GetDiskPartitionStyle(disk) if err != nil { - return false, fmt.Errorf("failed to query partition style of disk %d: %w", diskNumber, err) + return false, fmt.Errorf("failed to query partition style of disk %d: %v", diskNumber, err) } - partitionStyle = retValue.(int32) return partitionStyle != cim.PartitionStyleUnknown, nil } @@ -145,7 +141,7 @@ func (imp DiskAPI) InitializeDisk(diskNumber uint32) error { return fmt.Errorf("failed to initializing disk %d. error: %w", diskNumber, err) } - result, err := disk.InvokeMethodWithReturn("Initialize", int32(cim.PartitionStyleGPT)) + result, err := cim.InitializeDisk(disk, cim.PartitionStyleGPT) if result != 0 || err != nil { return fmt.Errorf("failed to initializing disk %d: result %d, error: %w", diskNumber, result, err) } @@ -154,9 +150,7 @@ func (imp DiskAPI) InitializeDisk(diskNumber uint32) error { } func (imp DiskAPI) BasicPartitionsExist(diskNumber uint32) (bool, error) { - partitions, err := cim.ListPartitionsWithFilters(nil, - query.NewWmiQueryFilter("DiskNumber", strconv.Itoa(int(diskNumber)), query.Equals), - query.NewWmiQueryFilter("GptType", cim.GPTPartitionTypeMicrosoftReserved, query.NotEquals)) + partitions, err := cim.ListPartitionsWithFilters(nil, cim.FilterForPartitionOnDisk(diskNumber), cim.FilterForPartitionsOfTypeNormal()) if cim.IgnoreNotFound(err) != nil { return false, fmt.Errorf("error checking presence of partitions on disk %d:, %v", diskNumber, err) } @@ -170,8 +164,8 @@ func (imp DiskAPI) CreateBasicPartition(diskNumber uint32) error { return err } - result, err := disk.InvokeMethodWithReturn( - "CreatePartition", + result, err := cim.CreatePartition( + disk, nil, // Size true, // UseMaximumSize nil, // Offset @@ -183,20 +177,16 @@ func (imp DiskAPI) CreateBasicPartition(diskNumber uint32) error { false, // IsHidden false, // IsActive, ) - // 42002 is returned by driver letter failed to assign after partition - if (result != 0 && result != 42002) || err != nil { + if (result != 0 && result != cim.ErrorCodeCreatePartitionAccessPathAlreadyInUse) || err != nil { return fmt.Errorf("error creating partition on disk %d. result: %d, err: %v", diskNumber, result, err) } - var status string - result, err = disk.InvokeMethodWithReturn("Refresh", &status) + result, _, err = cim.RefreshDisk(disk) if result != 0 || err != nil { return fmt.Errorf("error rescan disk (%d). result %d, error: %v", diskNumber, result, err) } - partitions, err := cim.ListPartitionsWithFilters(nil, - query.NewWmiQueryFilter("DiskNumber", strconv.Itoa(int(diskNumber)), query.Equals), - query.NewWmiQueryFilter("GptType", cim.GPTPartitionTypeMicrosoftReserved, query.NotEquals)) + partitions, err := cim.ListPartitionsWithFilters(nil, cim.FilterForPartitionOnDisk(diskNumber), cim.FilterForPartitionsOfTypeNormal()) if err != nil { return fmt.Errorf("error query basic partition on disk %d:, %v", diskNumber, err) } @@ -206,13 +196,12 @@ func (imp DiskAPI) CreateBasicPartition(diskNumber uint32) error { } partition := partitions[0] - result, err = partition.InvokeMethodWithReturn("Online", status) + result, status, err := cim.SetPartitionState(partition, true) if result != 0 || err != nil { return fmt.Errorf("error bring partition %v on disk %d online. result: %d, status %s, err: %v", partition, diskNumber, result, status, err) } - err = partition.Refresh() - return err + return nil } func (imp DiskAPI) GetDiskNumberByName(page83ID string) (uint32, error) { @@ -272,13 +261,13 @@ func (imp DiskAPI) GetDiskPage83ID(disk syscall.Handle) (string, error) { } func (imp DiskAPI) GetDiskNumberWithID(page83ID string) (uint32, error) { - disks, err := cim.ListDisks([]string{"Path", "SerialNumber"}) + disks, err := cim.ListDisks(cim.DiskSelectorListForPathAndSerialNumber) if err != nil { return 0, err } for _, disk := range disks { - path, err := disk.GetPropertyPath() + path, err := cim.GetDiskPath(disk) if err != nil { return 0, fmt.Errorf("failed to query disk path: %v, %w", disk, err) } @@ -319,19 +308,19 @@ func (imp DiskAPI) GetDiskNumberAndPage83ID(path string) (uint32, string, error) // ListDiskIDs - constructs a map with the disk number as the key and the DiskID structure // as the value. The DiskID struct has a field for the page83 ID. func (imp DiskAPI) ListDiskIDs() (map[uint32]shared.DiskIDs, error) { - disks, err := cim.ListDisks([]string{"Path", "SerialNumber"}) + disks, err := cim.ListDisks(cim.DiskSelectorListForPathAndSerialNumber) if err != nil { return nil, err } m := make(map[uint32]shared.DiskIDs) for _, disk := range disks { - path, err := disk.GetPropertyPath() + path, err := cim.GetDiskPath(disk) if err != nil { return m, fmt.Errorf("failed to query disk path: %v, %w", disk, err) } - sn, err := disk.GetPropertySerialNumber() + sn, err := cim.GetDiskSerialNumber(disk) if err != nil { return m, fmt.Errorf("failed to query disk serial number: %v, %w", disk, err) } @@ -351,56 +340,49 @@ func (imp DiskAPI) ListDiskIDs() (map[uint32]shared.DiskIDs, error) { func (imp DiskAPI) GetDiskStats(diskNumber uint32) (int64, error) { // TODO: change to uint64 as it does not make sense to use int64 for size - var size int64 - disk, err := cim.QueryDiskByNumber(diskNumber, []string{"Size"}) + disk, err := cim.QueryDiskByNumber(diskNumber, cim.DiskSelectorListForSize) if err != nil { return -1, err } - sz, err := disk.GetProperty("Size") + size, err := cim.GetDiskSize(disk) if err != nil { return -1, fmt.Errorf("failed to query size of disk %d. %v", diskNumber, err) } - size, err = strconv.ParseInt(sz.(string), 10, 64) return size, err } func (imp DiskAPI) SetDiskState(diskNumber uint32, isOnline bool) error { - disk, err := cim.QueryDiskByNumber(diskNumber, []string{"IsOffline"}) + disk, err := cim.QueryDiskByNumber(diskNumber, cim.DiskSelectorListForIsOffline) if err != nil { return err } - offline, err := disk.GetPropertyIsOffline() + isOffline, err := cim.IsDiskOffline(disk) if err != nil { return fmt.Errorf("error setting disk %d attach state. error: %v", diskNumber, err) } - if isOnline == !offline { + if isOnline == !isOffline { return nil } - method := "Offline" - if isOnline { - method = "Online" - } - - result, err := disk.InvokeMethodWithReturn(method) + result, _, err := cim.SetDiskState(disk, isOnline) if result != 0 || err != nil { - return fmt.Errorf("setting disk %d attach state %s: result %d, error: %w", diskNumber, method, result, err) + return fmt.Errorf("setting disk %d attach state (isOnline: %v): result %d, error: %w", diskNumber, isOnline, result, err) } return nil } func (imp DiskAPI) GetDiskState(diskNumber uint32) (bool, error) { - disk, err := cim.QueryDiskByNumber(diskNumber, []string{"IsOffline"}) + disk, err := cim.QueryDiskByNumber(diskNumber, cim.DiskSelectorListForIsOffline) if err != nil { return false, err } - isOffline, err := disk.GetPropertyIsOffline() + isOffline, err := cim.IsDiskOffline(disk) if err != nil { return false, fmt.Errorf("error parsing disk %d state. error: %v", diskNumber, err) } diff --git a/pkg/os/filesystem/api.go b/pkg/os/filesystem/api.go index a2fc4d26..458fd89f 100644 --- a/pkg/os/filesystem/api.go +++ b/pkg/os/filesystem/api.go @@ -112,13 +112,18 @@ func (filesystemAPI) IsSymlink(tgt string) (bool, error) { // This code is similar to k8s.io/kubernetes/pkg/util/mount except the pathExists usage. // Also in a remote call environment the os error cannot be passed directly back, hence the callers // are expected to perform the isExists check before calling this call in CSI proxy. - stat, err := os.Lstat(tgt) + isSymlink, err := utils.IsPathSymlink(tgt) if err != nil { return false, err } - // If its a link and it points to an existing file then its a mount point. - if stat.Mode()&os.ModeSymlink != 0 { + // mounted folder created by SetVolumeMountPoint may still report ModeSymlink == 0 + mountedFolder, err := utils.IsMountedFolder(tgt) + if err != nil { + return false, err + } + + if isSymlink || mountedFolder { target, err := os.Readlink(tgt) if err != nil { return false, fmt.Errorf("readlink error: %v", err) diff --git a/pkg/os/smb/api.go b/pkg/os/smb/api.go index 20b9544e..f0d28da4 100644 --- a/pkg/os/smb/api.go +++ b/pkg/os/smb/api.go @@ -3,15 +3,9 @@ package smb import ( "fmt" "strings" - "syscall" "github.com/kubernetes-csi/csi-proxy/pkg/cim" "github.com/kubernetes-csi/csi-proxy/pkg/utils" - "golang.org/x/sys/windows" -) - -const ( - credentialDelimiter = ":" ) type API interface { @@ -33,61 +27,23 @@ func New(requirePrivacy bool) *SmbAPI { } } -func remotePathForQuery(remotePath string) string { - return strings.ReplaceAll(remotePath, "\\", "\\\\") -} - -func escapeUserName(userName string) string { - // refer to https://github.com/PowerShell/PowerShell/blob/9303de597da55963a6e26a8fe164d0b256ca3d4d/src/Microsoft.PowerShell.Commands.Management/cimSupport/cmdletization/cim/cimConverter.cs#L169-L170 - escaped := strings.ReplaceAll(userName, "\\", "\\\\") - escaped = strings.ReplaceAll(escaped, credentialDelimiter, "\\"+credentialDelimiter) - return escaped -} - -func createSymlink(link, target string, isDir bool) error { - linkPtr, err := syscall.UTF16PtrFromString(link) - if err != nil { - return err - } - targetPtr, err := syscall.UTF16PtrFromString(target) - if err != nil { - return err - } - - var flags uint32 - if isDir { - flags = windows.SYMBOLIC_LINK_FLAG_DIRECTORY - } - - err = windows.CreateSymbolicLink( - linkPtr, - targetPtr, - flags, - ) - return err -} - func (*SmbAPI) IsSmbMapped(remotePath string) (bool, error) { - inst, err := cim.QuerySmbGlobalMappingByRemotePath(remotePathForQuery(remotePath)) + inst, err := cim.QuerySmbGlobalMappingByRemotePath(remotePath) if err != nil { return false, cim.IgnoreNotFound(err) } - status, err := inst.GetProperty("Status") + status, err := cim.GetSmbGlobalMappingStatus(inst) if err != nil { return false, err } - return status.(int32) == cim.SmbMappingStatusOK, nil + return status == cim.SmbMappingStatusOK, nil } // NewSmbLink - creates a directory symbolic link to the remote share. // The os.Symlink was having issue for cases where the destination was an SMB share - the container -// runtime would complain stating "Access Denied". Because of this, we had to perform -// this operation with powershell commandlet creating an directory softlink. -// Since os.Symlink is currently being used in working code paths, no attempt is made in -// alpha to merge the paths. -// TODO (for beta release): Merge the link paths - os.Symlink and Powershell link path. +// runtime would complain stating "Access Denied". func (*SmbAPI) NewSmbLink(remotePath, localPath string) error { if !strings.HasSuffix(remotePath, "\\") { // Golang has issues resolving paths mapped to file shares if they do not end in a trailing \ @@ -97,7 +53,7 @@ func (*SmbAPI) NewSmbLink(remotePath, localPath string) error { longRemotePath := utils.EnsureLongPath(remotePath) longLocalPath := utils.EnsureLongPath(localPath) - err := createSymlink(longLocalPath, longRemotePath, true) + err := utils.CreateSymlink(longLocalPath, longRemotePath, true) if err != nil { return fmt.Errorf("error linking %s to %s. err: %v", remotePath, localPath, err) } @@ -106,17 +62,7 @@ func (*SmbAPI) NewSmbLink(remotePath, localPath string) error { } func (api *SmbAPI) NewSmbGlobalMapping(remotePath, username, password string) error { - params := map[string]interface{}{ - "RemotePath": remotePath, - "RequirePrivacy": api.RequirePrivacy, - } - if username != "" { - // refer to https://github.com/PowerShell/PowerShell/blob/9303de597da55963a6e26a8fe164d0b256ca3d4d/src/Microsoft.PowerShell.Commands.Management/cimSupport/cmdletization/cim/cimConverter.cs#L166-L178 - // on how SMB credential is handled in PowerShell - params["Credential"] = escapeUserName(username) + credentialDelimiter + password - } - - result, _, err := cim.InvokeCimMethod(cim.WMINamespaceSmb, "MSFT_SmbGlobalMapping", "Create", params) + result, err := cim.NewSmbGlobalMapping(remotePath, username, password, api.RequirePrivacy) if err != nil { return fmt.Errorf("NewSmbGlobalMapping failed. result: %d, err: %v", result, err) } @@ -125,7 +71,7 @@ func (api *SmbAPI) NewSmbGlobalMapping(remotePath, username, password string) er } func (*SmbAPI) RemoveSmbGlobalMapping(remotePath string) error { - err := cim.RemoveSmbGlobalMappingByRemotePath(remotePathForQuery(remotePath)) + err := cim.RemoveSmbGlobalMappingByRemotePath(remotePath) if err != nil { return fmt.Errorf("error remove smb mapping '%s'. err: %v", remotePath, err) } diff --git a/pkg/os/volume/api.go b/pkg/os/volume/api.go index fcd2e6f8..ea667798 100644 --- a/pkg/os/volume/api.go +++ b/pkg/os/volume/api.go @@ -2,21 +2,21 @@ package volume import ( "fmt" - "os" "path/filepath" "regexp" - "strconv" "strings" - "github.com/go-ole/go-ole" "github.com/kubernetes-csi/csi-proxy/pkg/cim" "github.com/kubernetes-csi/csi-proxy/pkg/utils" - wmierrors "github.com/microsoft/wmi/pkg/errors" "github.com/pkg/errors" "golang.org/x/sys/windows" "k8s.io/klog/v2" ) +const ( + minimumResizeSize = 100 * 1024 * 1024 +) + // API exposes the internal volume operations available in the server type API interface { // ListVolumesOnDisk lists volumes on a disk identified by a `diskNumber` and optionally a partition identified by `partitionNumber`. @@ -69,7 +69,7 @@ func New() VolumeAPI { // ListVolumesOnDisk - returns back list of volumes(volumeIDs) in a disk and a partition. func (VolumeAPI) ListVolumesOnDisk(diskNumber uint32, partitionNumber uint32) (volumeIDs []string, err error) { - partitions, err := cim.ListPartitionsOnDisk(diskNumber, partitionNumber, []string{"ObjectId"}) + partitions, err := cim.ListPartitionsOnDisk(diskNumber, partitionNumber, cim.PartitionSelectorListObjectID) if err != nil { return nil, errors.Wrapf(err, "failed to list partition on disk %d", diskNumber) } @@ -80,9 +80,9 @@ func (VolumeAPI) ListVolumesOnDisk(diskNumber uint32, partitionNumber uint32) (v } for _, volume := range volumes { - uniqueID, err := volume.GetPropertyUniqueId() + uniqueID, err := cim.GetVolumeUniqueID(volume) if err != nil { - return nil, errors.Wrapf(err, "failed to list volumes") + return nil, errors.Wrapf(err, "failed to get unique ID for volume %v", volume) } volumeIDs = append(volumeIDs, uniqueID) } @@ -97,8 +97,7 @@ func (VolumeAPI) FormatVolume(volumeID string) (err error) { return fmt.Errorf("error formatting volume (%s). error: %v", volumeID, err) } - result, err := volume.InvokeMethodWithReturn( - "Format", + result, err := cim.FormatVolume(volume, "NTFS", // Format, "", // FileSystemLabel, nil, // AllocationUnitSize, @@ -113,7 +112,6 @@ func (VolumeAPI) FormatVolume(volumeID string) (err error) { if result != 0 || err != nil { return fmt.Errorf("error formatting volume (%s). result: %d, error: %v", volumeID, result, err) } - // TODO: Do we need to handle anything for len(out) == 0 return nil } @@ -124,18 +122,17 @@ func (VolumeAPI) WriteVolumeCache(volumeID string) (err error) { // IsVolumeFormatted - Check if the volume is formatted with the pre specified filesystem(typically ntfs). func (VolumeAPI) IsVolumeFormatted(volumeID string) (bool, error) { - volume, err := cim.QueryVolumeByUniqueID(volumeID, []string{"FileSystemType"}) + volume, err := cim.QueryVolumeByUniqueID(volumeID, cim.VolumeSelectorListForFileSystemType) if err != nil { return false, fmt.Errorf("error checking if volume (%s) is formatted. error: %v", volumeID, err) } - fsType, err := volume.GetProperty("FileSystemType") + fsType, err := cim.GetVolumeFileSystemType(volume) if err != nil { return false, fmt.Errorf("failed to query volume file system type (%s): %w", volumeID, err) } - const FileSystemUnknown = 0 - return fsType.(int32) != FileSystemUnknown, nil + return fsType != cim.FileSystemUnknown, nil } // MountVolume - mounts a volume to a path. This is done using Win32 API SetVolumeMountPoint for presenting the volume via a path. @@ -194,36 +191,25 @@ func (VolumeAPI) ResizeVolume(volumeID string, size int64) error { // If size is 0 then we will resize to the maximum size possible, otherwise just resize to size if size == 0 { - var sizeMin, sizeMax ole.VARIANT + var result int var status string - result, err := part.InvokeMethodWithReturn("GetSupportedSize", &sizeMin, &sizeMax, &status) + result, _, finalSize, status, err = cim.GetPartitionSupportedSize(part) if result != 0 || err != nil { - return fmt.Errorf("error getting sizeMin, sizeMax from volume(%s). result: %d, status: %s, error: %v", volumeID, result, status, err) + return fmt.Errorf("error getting sizeMin, sizeMax from volume (%s). result: %d, status: %s, error: %v", volumeID, result, status, err) } - klog.V(5).Infof("got sizeMin(%v) sizeMax(%v) from volume(%s), status: %s", sizeMin, sizeMax, volumeID, status) - finalSizeStr := sizeMax.ToString() - finalSize, err = strconv.ParseInt(finalSizeStr, 10, 64) - if err != nil { - return fmt.Errorf("error parsing the sizeMax of volume (%s) with error (%v)", volumeID, err) - } } else { finalSize = size } - currentSizeVal, err := part.GetProperty("Size") + currentSize, err := cim.GetPartitionSize(part) if err != nil { return fmt.Errorf("error getting the current size of volume (%s) with error (%v)", volumeID, err) } - currentSize, err := strconv.ParseInt(currentSizeVal.(string), 10, 64) - if err != nil { - return fmt.Errorf("error parsing the current size of volume (%s) with error (%v)", volumeID, err) - } - // only resize if finalSize - currentSize is greater than 100MB - if finalSize-currentSize < 100*1024*1024 { - klog.V(2).Infof("minimum resize difference(1GB) not met, skipping resize. volumeID=%s currentSize=%d finalSize=%d", volumeID, currentSize, finalSize) + if finalSize-currentSize < minimumResizeSize { + klog.V(2).Infof("minimum resize difference (100MB) not met, skipping resize. volumeID=%s currentSize=%d finalSize=%d", volumeID, currentSize, finalSize) return nil } @@ -233,9 +219,7 @@ func (VolumeAPI) ResizeVolume(volumeID string, size int64) error { return nil } - var status string - result, err := part.InvokeMethodWithReturn("Resize", strconv.Itoa(int(finalSize)), &status) - + result, _, err := cim.ResizePartition(part, finalSize) if result != 0 || err != nil { return fmt.Errorf("error resizing volume (%s). size:%v, finalSize %v, error: %v", volumeID, size, finalSize, err) } @@ -247,10 +231,10 @@ func (VolumeAPI) ResizeVolume(volumeID string, size int64) error { disk, err := cim.QueryDiskByNumber(diskNumber, nil) if err != nil { - return fmt.Errorf("error parsing disk number of volume (%s). error: %v", volumeID, err) + return fmt.Errorf("error query disk of volume (%s). error: %v", volumeID, err) } - result, err = disk.InvokeMethodWithReturn("Refresh", &status) + result, _, err = cim.RefreshDisk(disk) if result != 0 || err != nil { return fmt.Errorf("error rescan disk (%d). result %d, error: %v", diskNumber, result, err) } @@ -260,31 +244,21 @@ func (VolumeAPI) ResizeVolume(volumeID string, size int64) error { // GetVolumeStats - retrieves the volume stats for a given volume func (VolumeAPI) GetVolumeStats(volumeID string) (int64, int64, error) { - volume, err := cim.QueryVolumeByUniqueID(volumeID, []string{"UniqueId", "SizeRemaining", "Size"}) + volume, err := cim.QueryVolumeByUniqueID(volumeID, cim.VolumeSelectorListForStats) if err != nil { return -1, -1, fmt.Errorf("error getting capacity and used size of volume (%s). error: %v", volumeID, err) } - volumeSizeVal, err := volume.GetProperty("Size") + volumeSize, err := cim.GetVolumeSize(volume) if err != nil { return -1, -1, fmt.Errorf("failed to query volume size (%s): %w", volumeID, err) } - volumeSize, err := strconv.ParseInt(volumeSizeVal.(string), 10, 64) - if err != nil { - return -1, -1, fmt.Errorf("failed to parse volume size (%s): %w", volumeID, err) - } - - volumeSizeRemainingVal, err := volume.GetProperty("SizeRemaining") + volumeSizeRemaining, err := cim.GetVolumeSizeRemaining(volume) if err != nil { return -1, -1, fmt.Errorf("failed to query volume remaining size (%s): %w", volumeID, err) } - volumeSizeRemaining, err := strconv.ParseInt(volumeSizeRemainingVal.(string), 10, 64) - if err != nil { - return -1, -1, fmt.Errorf("failed to parse volume remaining size (%s): %w", volumeID, err) - } - volumeUsedSize := volumeSize - volumeSizeRemaining return volumeSize, volumeUsedSize, nil } @@ -297,12 +271,12 @@ func (VolumeAPI) GetDiskNumberFromVolumeID(volumeID string) (uint32, error) { return 0, err } - diskNumber, err := part.GetProperty("DiskNumber") + diskNumber, err := cim.GetPartitionDiskNumber(part) if err != nil { return 0, fmt.Errorf("error query disk number of volume (%s). error: %v", volumeID, err) } - return uint32(diskNumber.(int32)), nil + return diskNumber, nil } // GetVolumeIDFromTargetPath - gets the volume ID given a mount point, the function is recursive until it find a volume or errors out @@ -316,7 +290,7 @@ func (VolumeAPI) GetVolumeIDFromTargetPath(mount string) (string, error) { } func getTarget(mount string) (string, error) { - mountedFolder, err := isMountedFolder(mount) + mountedFolder, err := utils.IsMountedFolder(mount) if err != nil { return "", err } @@ -356,7 +330,7 @@ func (VolumeAPI) GetClosestVolumeIDFromTargetPath(targetPath string) (string, er } // findClosestVolume finds the closest volume id for a given target path -// by following symlinks and moving up in the filesystem, if after moving up in the filesystem +// by following symlinks and moving up in the filesystem. if after moving up in the filesystem // we get to a DriveLetter then the volume corresponding to this drive letter is returned instead. func findClosestVolume(path string) (string, error) { candidatePath := path @@ -365,22 +339,20 @@ func findClosestVolume(path string) (string, error) { // while trying to follow symlinks // // The maximum path length in Windows is 260, it could be possible to end - // up in a sceneario where we do more than 256 iterations (e.g. by following symlinks from + // up in a scenario where we do more than 256 iterations (e.g. by following symlinks from // a place high in the hierarchy to a nested sibling location many times) // https://docs.microsoft.com/en-us/windows/win32/fileio/naming-a-file#:~:text=In%20editions%20of%20Windows%20before,required%20to%20remove%20the%20limit. // // The number of iterations is 256, which is similar to the number of iterations in filepath-securejoin // https://github.com/cyphar/filepath-securejoin/blob/64536a8a66ae59588c981e2199f1dcf410508e07/join.go#L51 for i := 0; i < 256; i += 1 { - fi, err := os.Lstat(candidatePath) + isSymlink, err := utils.IsPathSymlink(candidatePath) if err != nil { return "", err } - // for windows NTFS, check if the path is symlink instead of directory. - isSymlink := fi.Mode()&os.ModeSymlink != 0 || fi.Mode()&os.ModeIrregular != 0 // mounted folder created by SetVolumeMountPoint may still report ModeSymlink == 0 - mountedFolder, err := isMountedFolder(candidatePath) + mountedFolder, err := utils.IsMountedFolder(candidatePath) if err != nil { return "", err } @@ -417,51 +389,18 @@ func findClosestVolume(path string) (string, error) { return "", fmt.Errorf("failed to find the closest volume for path=%s", path) } -// isMountedFolder checks whether the `path` is a mounted folder. -func isMountedFolder(path string) (bool, error) { - // https://learn.microsoft.com/en-us/windows/win32/fileio/determining-whether-a-directory-is-a-volume-mount-point - utf16Path, _ := windows.UTF16PtrFromString(path) - attrs, err := windows.GetFileAttributes(utf16Path) - if err != nil { - return false, err - } - - if (attrs & windows.FILE_ATTRIBUTE_REPARSE_POINT) == 0 { - return false, nil - } - - var findData windows.Win32finddata - findHandle, err := windows.FindFirstFile(utf16Path, &findData) - if err != nil && !errors.Is(err, windows.ERROR_NO_MORE_FILES) { - return false, err - } - - for err == nil { - if findData.Reserved0&windows.IO_REPARSE_TAG_MOUNT_POINT != 0 { - return true, nil - } - - err = windows.FindNextFile(findHandle, &findData) - if err != nil && !errors.Is(err, windows.ERROR_NO_MORE_FILES) { - return false, err - } - } - - return false, nil -} - // getVolumeForDriveLetter gets a volume from a drive letter (e.g. C:/). func getVolumeForDriveLetter(path string) (string, error) { if len(path) != 1 { return "", fmt.Errorf("the path %s is not a valid drive letter", path) } - volume, err := cim.GetVolumeByDriveLetter(path, []string{"UniqueId"}) + volume, err := cim.GetVolumeByDriveLetter(path, cim.VolumeSelectorListUniqueID) if err != nil { return "", nil } - uniqueID, err := volume.GetPropertyUniqueId() + uniqueID, err := cim.GetVolumeUniqueID(volume) if err != nil { return "", fmt.Errorf("error query unique ID of volume (%v). error: %v", volume, err) } @@ -470,12 +409,12 @@ func getVolumeForDriveLetter(path string) (string, error) { } func writeCache(volumeID string) error { - volume, err := cim.QueryVolumeByUniqueID(volumeID, []string{}) - if err != nil && !wmierrors.IsNotFound(err) { + volume, err := cim.QueryVolumeByUniqueID(volumeID, nil) + if err != nil { return fmt.Errorf("error writing volume (%s) cache. error: %v", volumeID, err) } - result, err := volume.Flush() + result, err := cim.FlushVolume(volume) if result != 0 || err != nil { return fmt.Errorf("error writing volume (%s) cache. result: %d, error: %v", volumeID, result, err) } diff --git a/pkg/utils/utils.go b/pkg/utils/utils.go index bfe446f7..90c21125 100644 --- a/pkg/utils/utils.go +++ b/pkg/utils/utils.go @@ -3,7 +3,6 @@ package utils import ( "fmt" "os" - "os/exec" "strings" "github.com/pkg/errors" @@ -25,14 +24,6 @@ func EnsureLongPath(path string) string { return path } -func RunPowershellCmd(command string, envs ...string) ([]byte, error) { - cmd := exec.Command("powershell", "-Mta", "-NoProfile", "-Command", command) - cmd.Env = append(os.Environ(), envs...) - klog.V(8).Infof("Executing command: %q", cmd.String()) - out, err := cmd.CombinedOutput() - return out, err -} - func IsPathValid(path string) (bool, error) { pathString, err := windows.UTF16PtrFromString(path) if err != nil { @@ -52,3 +43,69 @@ func IsPathValid(path string) (bool, error) { klog.V(6).Infof("Path %s attribute: %d", path, attrs) return attrs != windows.INVALID_FILE_ATTRIBUTES, nil } + +// IsMountedFolder checks whether the `path` is a mounted folder. +func IsMountedFolder(path string) (bool, error) { + // https://learn.microsoft.com/en-us/windows/win32/fileio/determining-whether-a-directory-is-a-volume-mount-point + utf16Path, _ := windows.UTF16PtrFromString(path) + attrs, err := windows.GetFileAttributes(utf16Path) + if err != nil { + return false, err + } + + if (attrs & windows.FILE_ATTRIBUTE_REPARSE_POINT) == 0 { + return false, nil + } + + var findData windows.Win32finddata + findHandle, err := windows.FindFirstFile(utf16Path, &findData) + if err != nil && !errors.Is(err, windows.ERROR_NO_MORE_FILES) { + return false, err + } + + for err == nil { + if findData.Reserved0&windows.IO_REPARSE_TAG_MOUNT_POINT != 0 { + return true, nil + } + + err = windows.FindNextFile(findHandle, &findData) + if err != nil && !errors.Is(err, windows.ERROR_NO_MORE_FILES) { + return false, err + } + } + + return false, nil +} + +func IsPathSymlink(path string) (bool, error) { + fi, err := os.Lstat(path) + if err != nil { + return false, err + } + // for windows NTFS, check if the path is symlink instead of directory. + isSymlink := fi.Mode()&os.ModeSymlink != 0 || fi.Mode()&os.ModeIrregular != 0 + return isSymlink, nil +} + +func CreateSymlink(link, target string, isDir bool) error { + linkPtr, err := windows.UTF16PtrFromString(link) + if err != nil { + return err + } + targetPtr, err := windows.UTF16PtrFromString(target) + if err != nil { + return err + } + + var flags uint32 + if isDir { + flags = windows.SYMBOLIC_LINK_FLAG_DIRECTORY + } + + err = windows.CreateSymbolicLink( + linkPtr, + targetPtr, + flags, + ) + return err +} From 605d478a0a691547359f28b18a02fcbfc009ad52 Mon Sep 17 00:00:00 2001 From: Zhongcheng Lao Date: Tue, 17 Jun 2025 15:41:05 +0800 Subject: [PATCH 2/3] Ensure COM threading apartment for API calls --- pkg/cim/wmi.go | 39 +++++ pkg/os/disk/api.go | 379 ++++++++++++++++++++++++------------------- pkg/os/iscsi/api.go | 288 +++++++++++++++++--------------- pkg/os/smb/api.go | 53 +++--- pkg/os/system/api.go | 131 ++++++++------- pkg/os/volume/api.go | 297 ++++++++++++++++++--------------- 6 files changed, 665 insertions(+), 522 deletions(-) diff --git a/pkg/cim/wmi.go b/pkg/cim/wmi.go index ba75f747..ec9c8f08 100644 --- a/pkg/cim/wmi.go +++ b/pkg/cim/wmi.go @@ -4,13 +4,16 @@ package cim import ( + "errors" "fmt" + "runtime" "github.com/go-ole/go-ole" "github.com/go-ole/go-ole/oleutil" "github.com/microsoft/wmi/pkg/base/query" wmierrors "github.com/microsoft/wmi/pkg/errors" cim "github.com/microsoft/wmi/pkg/wmiinstance" + "golang.org/x/sys/windows" "k8s.io/klog/v2" ) @@ -248,3 +251,39 @@ func IgnoreNotFound(err error) error { } return err } + +// WithCOMThread runs the given function `fn` on a locked OS thread +// with COM initialized using COINIT_MULTITHREADED. +// +// This is necessary for using COM/OLE APIs directly (e.g., via go-ole), +// because COM requires that initialization and usage occur on the same thread. +// +// It performs the following steps: +// - Locks the current goroutine to its OS thread +// - Calls ole.CoInitializeEx with COINIT_MULTITHREADED +// - Executes the user-provided function +// - Uninitializes COM +// - Unlocks the thread +// +// If COM initialization fails, or if the user's function returns an error, +// that error is returned by WithCOMThread. +func WithCOMThread(fn func() error) error { + runtime.LockOSThread() + defer runtime.UnlockOSThread() + + if err := ole.CoInitializeEx(0, ole.COINIT_MULTITHREADED); err != nil { + var oleError *ole.OleError + if errors.As(err, &oleError) && oleError != nil && oleError.Code() == uintptr(windows.S_FALSE) { + klog.V(10).Infof("COM library has been already initialized for the calling thread, proceeding to the function with no error") + err = nil + } + if err != nil { + return err + } + } else { + klog.V(10).Infof("COM library is initialized for the calling thread") + } + defer ole.CoUninitialize() + + return fn() +} diff --git a/pkg/os/disk/api.go b/pkg/os/disk/api.go index b366b977..5b46992c 100644 --- a/pkg/os/disk/api.go +++ b/pkg/os/disk/api.go @@ -64,144 +64,162 @@ func New() DiskAPI { // ListDiskLocations - constructs a map with the disk number as the key and the DiskLocation structure // as the value. The DiskLocation struct has various fields like the Adapter, Bus, Target and LUNID. func (imp DiskAPI) ListDiskLocations() (map[uint32]shared.DiskLocation, error) { - // "location": "PCI Slot 3 : Adapter 0 : Port 0 : Target 1 : LUN 0" - disks, err := cim.ListDisks(cim.DiskSelectorListForDiskNumberAndLocation) - if err != nil { - return nil, fmt.Errorf("could not query disk locations") - } - m := make(map[uint32]shared.DiskLocation) - for _, disk := range disks { - num, err := cim.GetDiskNumber(disk) + err := cim.WithCOMThread(func() error { + // "location": "PCI Slot 3 : Adapter 0 : Port 0 : Target 1 : LUN 0" + disks, err := cim.ListDisks(cim.DiskSelectorListForDiskNumberAndLocation) if err != nil { - return m, fmt.Errorf("failed to query disk number: %v, %w", disk, err) + return fmt.Errorf("could not query disk locations") } - location, err := cim.GetDiskLocation(disk) - if err != nil { - return m, fmt.Errorf("failed to query disk location: %v, %w", disk, err) - } + for _, disk := range disks { + num, err := cim.GetDiskNumber(disk) + if err != nil { + return fmt.Errorf("failed to query disk number: %v, %w", disk, err) + } + + location, err := cim.GetDiskLocation(disk) + if err != nil { + return fmt.Errorf("failed to query disk location: %v, %w", disk, err) + } - found := false - s := strings.Split(location, ":") - if len(s) >= 5 { - var d shared.DiskLocation - for _, item := range s { - item = strings.TrimSpace(item) - itemSplit := strings.Split(item, " ") - if len(itemSplit) == 2 { - found = true - switch strings.TrimSpace(itemSplit[0]) { - case "Adapter": - d.Adapter = strings.TrimSpace(itemSplit[1]) - case "Target": - d.Target = strings.TrimSpace(itemSplit[1]) - case "LUN": - d.LUNID = strings.TrimSpace(itemSplit[1]) - default: - klog.Warningf("Got unknown field : %s=%s", itemSplit[0], itemSplit[1]) + found := false + s := strings.Split(location, ":") + if len(s) >= 5 { + var d shared.DiskLocation + for _, item := range s { + item = strings.TrimSpace(item) + itemSplit := strings.Split(item, " ") + if len(itemSplit) == 2 { + found = true + switch strings.TrimSpace(itemSplit[0]) { + case "Adapter": + d.Adapter = strings.TrimSpace(itemSplit[1]) + case "Target": + d.Target = strings.TrimSpace(itemSplit[1]) + case "LUN": + d.LUNID = strings.TrimSpace(itemSplit[1]) + default: + klog.Warningf("Got unknown field : %s=%s", itemSplit[0], itemSplit[1]) + } } } - } - if found { - m[num] = d + if found { + m[num] = d + } } } - } - return m, nil + return nil + }) + return m, err } func (imp DiskAPI) Rescan() error { - result, err := cim.RescanDisks() - if err != nil { - return fmt.Errorf("error updating host storage cache output. result: %d, err: %v", result, err) - } - return nil + return cim.WithCOMThread(func() error { + result, err := cim.RescanDisks() + if err != nil { + return fmt.Errorf("error updating host storage cache output. result: %d, err: %v", result, err) + } + return nil + }) } func (imp DiskAPI) IsDiskInitialized(diskNumber uint32) (bool, error) { - disk, err := cim.QueryDiskByNumber(diskNumber, cim.DiskSelectorListForPartitionStyle) - if err != nil { - return false, fmt.Errorf("error checking initialized status of disk %d: %v", diskNumber, err) - } + var partitionStyle int32 + err := cim.WithCOMThread(func() error { + disk, err := cim.QueryDiskByNumber(diskNumber, cim.DiskSelectorListForPartitionStyle) + if err != nil { + return fmt.Errorf("error checking initialized status of disk %d: %v", diskNumber, err) + } - partitionStyle, err := cim.GetDiskPartitionStyle(disk) - if err != nil { - return false, fmt.Errorf("failed to query partition style of disk %d: %v", diskNumber, err) - } + partitionStyle, err = cim.GetDiskPartitionStyle(disk) + if err != nil { + return fmt.Errorf("failed to query partition style of disk %d: %v", diskNumber, err) + } - return partitionStyle != cim.PartitionStyleUnknown, nil + return nil + }) + return partitionStyle != cim.PartitionStyleUnknown, err } func (imp DiskAPI) InitializeDisk(diskNumber uint32) error { - disk, err := cim.QueryDiskByNumber(diskNumber, nil) - if err != nil { - return fmt.Errorf("failed to initializing disk %d. error: %w", diskNumber, err) - } + return cim.WithCOMThread(func() error { + disk, err := cim.QueryDiskByNumber(diskNumber, nil) + if err != nil { + return fmt.Errorf("failed to initializing disk %d. error: %w", diskNumber, err) + } - result, err := cim.InitializeDisk(disk, cim.PartitionStyleGPT) - if result != 0 || err != nil { - return fmt.Errorf("failed to initializing disk %d: result %d, error: %w", diskNumber, result, err) - } + result, err := cim.InitializeDisk(disk, cim.PartitionStyleGPT) + if result != 0 || err != nil { + return fmt.Errorf("failed to initializing disk %d: result %d, error: %w", diskNumber, result, err) + } - return nil + return nil + }) } func (imp DiskAPI) BasicPartitionsExist(diskNumber uint32) (bool, error) { - partitions, err := cim.ListPartitionsWithFilters(nil, cim.FilterForPartitionOnDisk(diskNumber), cim.FilterForPartitionsOfTypeNormal()) - if cim.IgnoreNotFound(err) != nil { - return false, fmt.Errorf("error checking presence of partitions on disk %d:, %v", diskNumber, err) - } + var exist bool + err := cim.WithCOMThread(func() error { + partitions, err := cim.ListPartitionsWithFilters(nil, cim.FilterForPartitionOnDisk(diskNumber), cim.FilterForPartitionsOfTypeNormal()) + if cim.IgnoreNotFound(err) != nil { + return fmt.Errorf("error checking presence of partitions on disk %d:, %v", diskNumber, err) + } - return len(partitions) > 0, nil + exist = len(partitions) > 0 + return nil + }) + return exist, err } func (imp DiskAPI) CreateBasicPartition(diskNumber uint32) error { - disk, err := cim.QueryDiskByNumber(diskNumber, nil) - if err != nil { - return err - } + return cim.WithCOMThread(func() error { + disk, err := cim.QueryDiskByNumber(diskNumber, nil) + if err != nil { + return err + } - result, err := cim.CreatePartition( - disk, - nil, // Size - true, // UseMaximumSize - nil, // Offset - nil, // Alignment - nil, // DriveLetter - false, // AssignDriveLetter - nil, // MbrType, - cim.GPTPartitionTypeBasicData, // GPT Type - false, // IsHidden - false, // IsActive, - ) - if (result != 0 && result != cim.ErrorCodeCreatePartitionAccessPathAlreadyInUse) || err != nil { - return fmt.Errorf("error creating partition on disk %d. result: %d, err: %v", diskNumber, result, err) - } + result, err := cim.CreatePartition( + disk, + nil, // Size + true, // UseMaximumSize + nil, // Offset + nil, // Alignment + nil, // DriveLetter + false, // AssignDriveLetter + nil, // MbrType, + cim.GPTPartitionTypeBasicData, // GPT Type + false, // IsHidden + false, // IsActive, + ) + if (result != 0 && result != cim.ErrorCodeCreatePartitionAccessPathAlreadyInUse) || err != nil { + return fmt.Errorf("error creating partition on disk %d. result: %d, err: %v", diskNumber, result, err) + } - result, _, err = cim.RefreshDisk(disk) - if result != 0 || err != nil { - return fmt.Errorf("error rescan disk (%d). result %d, error: %v", diskNumber, result, err) - } + result, _, err = cim.RefreshDisk(disk) + if result != 0 || err != nil { + return fmt.Errorf("error rescan disk (%d). result %d, error: %v", diskNumber, result, err) + } - partitions, err := cim.ListPartitionsWithFilters(nil, cim.FilterForPartitionOnDisk(diskNumber), cim.FilterForPartitionsOfTypeNormal()) - if err != nil { - return fmt.Errorf("error query basic partition on disk %d:, %v", diskNumber, err) - } + partitions, err := cim.ListPartitionsWithFilters(nil, cim.FilterForPartitionOnDisk(diskNumber), cim.FilterForPartitionsOfTypeNormal()) + if err != nil { + return fmt.Errorf("error query basic partition on disk %d:, %v", diskNumber, err) + } - if len(partitions) == 0 { - return fmt.Errorf("failed to create basic partition on disk %d:, %v", diskNumber, err) - } + if len(partitions) == 0 { + return fmt.Errorf("failed to create basic partition on disk %d:, %v", diskNumber, err) + } - partition := partitions[0] - result, status, err := cim.SetPartitionState(partition, true) - if result != 0 || err != nil { - return fmt.Errorf("error bring partition %v on disk %d online. result: %d, status %s, err: %v", partition, diskNumber, result, status, err) - } + partition := partitions[0] + result, status, err := cim.SetPartitionState(partition, true) + if result != 0 || err != nil { + return fmt.Errorf("error bring partition %v on disk %d online. result: %d, status %s, err: %v", partition, diskNumber, result, status, err) + } - return nil + return nil + }) } func (imp DiskAPI) GetDiskNumberByName(page83ID string) (uint32, error) { @@ -261,28 +279,33 @@ func (imp DiskAPI) GetDiskPage83ID(disk syscall.Handle) (string, error) { } func (imp DiskAPI) GetDiskNumberWithID(page83ID string) (uint32, error) { - disks, err := cim.ListDisks(cim.DiskSelectorListForPathAndSerialNumber) - if err != nil { - return 0, err - } - - for _, disk := range disks { - path, err := cim.GetDiskPath(disk) + var diskNumberResult uint32 + err := cim.WithCOMThread(func() error { + disks, err := cim.ListDisks(cim.DiskSelectorListForPathAndSerialNumber) if err != nil { - return 0, fmt.Errorf("failed to query disk path: %v, %w", disk, err) + return err } - diskNumber, diskPage83ID, err := imp.GetDiskNumberAndPage83ID(path) - if err != nil { - return 0, err - } + for _, disk := range disks { + path, err := cim.GetDiskPath(disk) + if err != nil { + return fmt.Errorf("failed to query disk path: %v, %w", disk, err) + } - if diskPage83ID == page83ID { - return diskNumber, nil + diskNumber, diskPage83ID, err := imp.GetDiskNumberAndPage83ID(path) + if err != nil { + return err + } + + if diskPage83ID == page83ID { + diskNumberResult = diskNumber + return nil + } } - } - return 0, fmt.Errorf("could not find disk with Page83 ID %s", page83ID) + return fmt.Errorf("could not find disk with Page83 ID %s", page83ID) + }) + return diskNumberResult, err } func (imp DiskAPI) GetDiskNumberAndPage83ID(path string) (uint32, string, error) { @@ -308,84 +331,98 @@ func (imp DiskAPI) GetDiskNumberAndPage83ID(path string) (uint32, string, error) // ListDiskIDs - constructs a map with the disk number as the key and the DiskID structure // as the value. The DiskID struct has a field for the page83 ID. func (imp DiskAPI) ListDiskIDs() (map[uint32]shared.DiskIDs, error) { - disks, err := cim.ListDisks(cim.DiskSelectorListForPathAndSerialNumber) - if err != nil { - return nil, err - } - m := make(map[uint32]shared.DiskIDs) - for _, disk := range disks { - path, err := cim.GetDiskPath(disk) + err := cim.WithCOMThread(func() error { + disks, err := cim.ListDisks(cim.DiskSelectorListForPathAndSerialNumber) if err != nil { - return m, fmt.Errorf("failed to query disk path: %v, %w", disk, err) + return err } - sn, err := cim.GetDiskSerialNumber(disk) - if err != nil { - return m, fmt.Errorf("failed to query disk serial number: %v, %w", disk, err) - } + for _, disk := range disks { + path, err := cim.GetDiskPath(disk) + if err != nil { + return fmt.Errorf("failed to query disk path: %v, %w", disk, err) + } - diskNumber, page83, err := imp.GetDiskNumberAndPage83ID(path) - if err != nil { - return m, err - } + sn, err := cim.GetDiskSerialNumber(disk) + if err != nil { + return fmt.Errorf("failed to query disk serial number: %v, %w", disk, err) + } - m[diskNumber] = shared.DiskIDs{ - Page83: page83, - SerialNumber: sn, + diskNumber, page83, err := imp.GetDiskNumberAndPage83ID(path) + if err != nil { + return err + } + + m[diskNumber] = shared.DiskIDs{ + Page83: page83, + SerialNumber: sn, + } } - } - return m, nil + + return nil + }) + return m, err } func (imp DiskAPI) GetDiskStats(diskNumber uint32) (int64, error) { // TODO: change to uint64 as it does not make sense to use int64 for size - disk, err := cim.QueryDiskByNumber(diskNumber, cim.DiskSelectorListForSize) - if err != nil { - return -1, err - } + size := int64(-1) + err := cim.WithCOMThread(func() error { + disk, err := cim.QueryDiskByNumber(diskNumber, cim.DiskSelectorListForSize) + if err != nil { + return err + } - size, err := cim.GetDiskSize(disk) - if err != nil { - return -1, fmt.Errorf("failed to query size of disk %d. %v", diskNumber, err) - } + size, err = cim.GetDiskSize(disk) + if err != nil { + return fmt.Errorf("failed to query size of disk %d. %v", diskNumber, err) + } + return nil + }) return size, err } func (imp DiskAPI) SetDiskState(diskNumber uint32, isOnline bool) error { - disk, err := cim.QueryDiskByNumber(diskNumber, cim.DiskSelectorListForIsOffline) - if err != nil { - return err - } + return cim.WithCOMThread(func() error { + disk, err := cim.QueryDiskByNumber(diskNumber, cim.DiskSelectorListForIsOffline) + if err != nil { + return err + } - isOffline, err := cim.IsDiskOffline(disk) - if err != nil { - return fmt.Errorf("error setting disk %d attach state. error: %v", diskNumber, err) - } + isOffline, err := cim.IsDiskOffline(disk) + if err != nil { + return fmt.Errorf("error setting disk %d attach state. error: %v", diskNumber, err) + } - if isOnline == !isOffline { - return nil - } + if isOnline == !isOffline { + return nil + } - result, _, err := cim.SetDiskState(disk, isOnline) - if result != 0 || err != nil { - return fmt.Errorf("setting disk %d attach state (isOnline: %v): result %d, error: %w", diskNumber, isOnline, result, err) - } + result, _, err := cim.SetDiskState(disk, isOnline) + if result != 0 || err != nil { + return fmt.Errorf("setting disk %d attach state (isOnline: %v): result %d, error: %w", diskNumber, isOnline, result, err) + } - return nil + return nil + }) } func (imp DiskAPI) GetDiskState(diskNumber uint32) (bool, error) { - disk, err := cim.QueryDiskByNumber(diskNumber, cim.DiskSelectorListForIsOffline) - if err != nil { - return false, err - } + var isOffline bool + err := cim.WithCOMThread(func() error { + disk, err := cim.QueryDiskByNumber(diskNumber, cim.DiskSelectorListForIsOffline) + if err != nil { + return err + } - isOffline, err := cim.IsDiskOffline(disk) - if err != nil { - return false, fmt.Errorf("error parsing disk %d state. error: %v", diskNumber, err) - } + isOffline, err = cim.IsDiskOffline(disk) + if err != nil { + return fmt.Errorf("error parsing disk %d state. error: %v", diskNumber, err) + } - return !isOffline, nil + return nil + }) + return !isOffline, err } diff --git a/pkg/os/iscsi/api.go b/pkg/os/iscsi/api.go index 1dd385db..9508ac9c 100644 --- a/pkg/os/iscsi/api.go +++ b/pkg/os/iscsi/api.go @@ -21,190 +21,210 @@ func New() APIImplementor { } func (APIImplementor) AddTargetPortal(portal *TargetPortal) error { - existing, err := cim.QueryISCSITargetPortal(portal.Address, portal.Port, nil) - if cim.IgnoreNotFound(err) != nil { - return fmt.Errorf("error query target portal at (%s:%d). err: %v", portal.Address, portal.Port, err) - } + return cim.WithCOMThread(func() error { + existing, err := cim.QueryISCSITargetPortal(portal.Address, portal.Port, nil) + if cim.IgnoreNotFound(err) != nil { + return fmt.Errorf("error query target portal at (%s:%d). err: %v", portal.Address, portal.Port, err) + } - if existing != nil { - klog.V(2).Infof("target portal at (%s:%d) already exists", portal.Address, portal.Port) - return nil - } + if existing != nil { + klog.V(2).Infof("target portal at (%s:%d) already exists", portal.Address, portal.Port) + return nil + } - _, err = cim.NewISCSITargetPortal(portal.Address, portal.Port, nil, nil, nil, nil) - if err != nil { - return fmt.Errorf("error adding target portal at (%s:%d). err: %v", portal.Address, portal.Port, err) - } + _, err = cim.NewISCSITargetPortal(portal.Address, portal.Port, nil, nil, nil, nil) + if err != nil { + return fmt.Errorf("error adding target portal at (%s:%d). err: %v", portal.Address, portal.Port, err) + } - return nil + return nil + }) } func (APIImplementor) DiscoverTargetPortal(portal *TargetPortal) ([]string, error) { - targets, err := cim.ListISCSITargetsByTargetPortalAddressAndPort(portal.Address, portal.Port, nil) - if err != nil { - return nil, fmt.Errorf("error list targets by target portal at (%s:%d). err: %v", portal.Address, portal.Port, err) - } - var iqns []string - for _, target := range targets { - iqn, err := cim.GetISCSITargetNodeAddress(target) + err := cim.WithCOMThread(func() error { + targets, err := cim.ListISCSITargetsByTargetPortalAddressAndPort(portal.Address, portal.Port, nil) if err != nil { - return nil, fmt.Errorf("failed parsing node address of target %v to target portal at (%s:%d). err: %w", target, portal.Address, portal.Port, err) + return fmt.Errorf("error list targets by target portal at (%s:%d). err: %v", portal.Address, portal.Port, err) } - iqns = append(iqns, iqn) - } + for _, target := range targets { + iqn, err := cim.GetISCSITargetNodeAddress(target) + if err != nil { + return fmt.Errorf("failed parsing node address of target %v to target portal at (%s:%d). err: %w", target, portal.Address, portal.Port, err) + } + + iqns = append(iqns, iqn) + } - return iqns, nil + return nil + }) + return iqns, err } func (APIImplementor) ListTargetPortals() ([]TargetPortal, error) { - instances, err := cim.ListISCSITargetPortals(cim.ISCSITargetPortalDefaultSelectorList) - if err != nil { - return nil, fmt.Errorf("error list target portals. err: %v", err) - } - var portals []TargetPortal - for _, instance := range instances { - address, port, err := cim.ParseISCSITargetPortal(instance) + err := cim.WithCOMThread(func() error { + instances, err := cim.ListISCSITargetPortals(cim.ISCSITargetPortalDefaultSelectorList) if err != nil { - return nil, fmt.Errorf("failed parsing target portal %v. err: %w", instance, err) + return fmt.Errorf("error list target portals. err: %v", err) } - portals = append(portals, TargetPortal{ - Address: address, - Port: port, - }) - } + for _, instance := range instances { + address, port, err := cim.ParseISCSITargetPortal(instance) + if err != nil { + return fmt.Errorf("failed parsing target portal %v. err: %w", instance, err) + } + + portals = append(portals, TargetPortal{ + Address: address, + Port: port, + }) + } - return portals, nil + return nil + }) + return portals, err } func (APIImplementor) RemoveTargetPortal(portal *TargetPortal) error { - instance, err := cim.QueryISCSITargetPortal(portal.Address, portal.Port, nil) - if err != nil { - return fmt.Errorf("error query target portal at (%s:%d). err: %v", portal.Address, portal.Port, err) - } + return cim.WithCOMThread(func() error { + instance, err := cim.QueryISCSITargetPortal(portal.Address, portal.Port, nil) + if err != nil { + return fmt.Errorf("error query target portal at (%s:%d). err: %v", portal.Address, portal.Port, err) + } - result, err := cim.RemoveISCSITargetPortal(instance) - if result != 0 || err != nil { - return fmt.Errorf("error removing target portal at (%s:%d). result: %d, err: %w", portal.Address, portal.Port, result, err) - } + result, err := cim.RemoveISCSITargetPortal(instance) + if result != 0 || err != nil { + return fmt.Errorf("error removing target portal at (%s:%d). result: %d, err: %w", portal.Address, portal.Port, result, err) + } - return nil + return nil + }) } func (APIImplementor) ConnectTarget(portal *TargetPortal, iqn string, authType string, chapUser string, chapSecret string) error { - target, err := cim.QueryISCSITarget(portal.Address, portal.Port, iqn) - if err != nil { - return fmt.Errorf("error query target %s from target portal at (%s:%d). err: %w", iqn, portal.Address, portal.Port, err) - } - - connected, err := cim.IsISCSITargetConnected(target) - if err != nil { - return fmt.Errorf("error query connected of target %s from target portal at (%s:%d). err: %w", iqn, portal.Address, portal.Port, err) - } - - if connected { - klog.V(2).Infof("target %s from target portal at (%s:%d) is connected.", iqn, portal.Address, portal.Port) - return nil - } + return cim.WithCOMThread(func() error { + target, err := cim.QueryISCSITarget(portal.Address, portal.Port, iqn) + if err != nil { + return fmt.Errorf("error query target %s from target portal at (%s:%d). err: %w", iqn, portal.Address, portal.Port, err) + } - targetAuthType := strings.ToUpper(strings.ReplaceAll(authType, "_", "")) + connected, err := cim.IsISCSITargetConnected(target) + if err != nil { + return fmt.Errorf("error query connected of target %s from target portal at (%s:%d). err: %w", iqn, portal.Address, portal.Port, err) + } - result, err := cim.ConnectISCSITarget(portal.Address, portal.Port, iqn, targetAuthType, &chapUser, &chapSecret) - if err != nil { - return fmt.Errorf("error connecting to target portal. result: %d, err: %w", result, err) - } + if connected { + klog.V(2).Infof("target %s from target portal at (%s:%d) is connected.", iqn, portal.Address, portal.Port) + return nil + } - return nil + targetAuthType := strings.ToUpper(strings.ReplaceAll(authType, "_", "")) + + result, err := cim.ConnectISCSITarget(portal.Address, portal.Port, iqn, targetAuthType, &chapUser, &chapSecret) + if err != nil { + return fmt.Errorf("error connecting to target portal. result: %d, err: %w", result, err) + } + + return nil + }) } func (APIImplementor) DisconnectTarget(portal *TargetPortal, iqn string) error { - target, err := cim.QueryISCSITarget(portal.Address, portal.Port, iqn) - if err != nil { - return fmt.Errorf("error query target %s from target portal at (%s:%d). err: %w", iqn, portal.Address, portal.Port, err) - } - - connected, err := cim.IsISCSITargetConnected(target) - if err != nil { - return fmt.Errorf("error query connected of target %s from target portal at (%s:%d). err: %w", iqn, portal.Address, portal.Port, err) - } - - if !connected { - klog.V(2).Infof("target %s from target portal at (%s:%d) is not connected.", iqn, portal.Address, portal.Port) - return nil - } + return cim.WithCOMThread(func() error { + target, err := cim.QueryISCSITarget(portal.Address, portal.Port, iqn) + if err != nil { + return fmt.Errorf("error query target %s from target portal at (%s:%d). err: %w", iqn, portal.Address, portal.Port, err) + } - // get session - session, err := cim.QueryISCSISessionByTarget(target) - if err != nil { - return fmt.Errorf("error query session of target %s from target portal at (%s:%d). err: %w", iqn, portal.Address, portal.Port, err) - } + connected, err := cim.IsISCSITargetConnected(target) + if err != nil { + return fmt.Errorf("error query connected of target %s from target portal at (%s:%d). err: %w", iqn, portal.Address, portal.Port, err) + } - sessionIdentifier, err := cim.GetISCSISessionIdentifier(session) - if err != nil { - return fmt.Errorf("error query session identifier of target %s from target portal at (%s:%d). err: %w", iqn, portal.Address, portal.Port, err) - } + if !connected { + klog.V(2).Infof("target %s from target portal at (%s:%d) is not connected.", iqn, portal.Address, portal.Port) + return nil + } - persistent, err := cim.IsISCSISessionPersistent(session) - if err != nil { - return fmt.Errorf("error query session persistency of target %s from target portal at (%s:%d). err: %w", iqn, portal.Address, portal.Port, err) - } + // get session + session, err := cim.QueryISCSISessionByTarget(target) + if err != nil { + return fmt.Errorf("error query session of target %s from target portal at (%s:%d). err: %w", iqn, portal.Address, portal.Port, err) + } - if persistent { - result, err := cim.UnregisterISCSISession(session) + sessionIdentifier, err := cim.GetISCSISessionIdentifier(session) if err != nil { - return fmt.Errorf("error unregister session on target %s from target portal at (%s:%d). result: %d, err: %w", iqn, portal.Address, portal.Port, result, err) + return fmt.Errorf("error query session identifier of target %s from target portal at (%s:%d). err: %w", iqn, portal.Address, portal.Port, err) } - } - result, err := cim.DisconnectISCSITarget(target, sessionIdentifier) - if err != nil { - return fmt.Errorf("error disconnecting target %s from target portal at (%s:%d). result: %d, err: %w", iqn, portal.Address, portal.Port, result, err) - } + persistent, err := cim.IsISCSISessionPersistent(session) + if err != nil { + return fmt.Errorf("error query session persistency of target %s from target portal at (%s:%d). err: %w", iqn, portal.Address, portal.Port, err) + } - return nil + if persistent { + result, err := cim.UnregisterISCSISession(session) + if err != nil { + return fmt.Errorf("error unregister session on target %s from target portal at (%s:%d). result: %d, err: %w", iqn, portal.Address, portal.Port, result, err) + } + } + + result, err := cim.DisconnectISCSITarget(target, sessionIdentifier) + if err != nil { + return fmt.Errorf("error disconnecting target %s from target portal at (%s:%d). result: %d, err: %w", iqn, portal.Address, portal.Port, result, err) + } + + return nil + }) } func (APIImplementor) GetTargetDisks(portal *TargetPortal, iqn string) ([]string, error) { - target, err := cim.QueryISCSITarget(portal.Address, portal.Port, iqn) - if err != nil { - return nil, fmt.Errorf("error query target %s from target portal at (%s:%d). err: %w", iqn, portal.Address, portal.Port, err) - } - - connected, err := cim.IsISCSITargetConnected(target) - if err != nil { - return nil, fmt.Errorf("error query connected of target %s from target portal at (%s:%d). err: %w", iqn, portal.Address, portal.Port, err) - } - - if !connected { - klog.V(2).Infof("target %s from target portal at (%s:%d) is not connected.", iqn, portal.Address, portal.Port) - return nil, nil - } - - disks, err := cim.ListDisksByTarget(target) - if err != nil { - return nil, fmt.Errorf("error getting target disks on target %s from target portal at (%s:%d). err: %w", iqn, portal.Address, portal.Port, err) - } - var ids []string - for _, disk := range disks { - number, err := cim.GetDiskNumber(disk) + err := cim.WithCOMThread(func() error { + target, err := cim.QueryISCSITarget(portal.Address, portal.Port, iqn) if err != nil { - return nil, fmt.Errorf("error getting number of disk %v on target %s from target portal at (%s:%d). err: %w", disk, iqn, portal.Address, portal.Port, err) + return fmt.Errorf("error query target %s from target portal at (%s:%d). err: %w", iqn, portal.Address, portal.Port, err) } - ids = append(ids, strconv.Itoa(int(number))) - } - return ids, nil + connected, err := cim.IsISCSITargetConnected(target) + if err != nil { + return fmt.Errorf("error query connected of target %s from target portal at (%s:%d). err: %w", iqn, portal.Address, portal.Port, err) + } + + if !connected { + klog.V(2).Infof("target %s from target portal at (%s:%d) is not connected.", iqn, portal.Address, portal.Port) + return nil + } + + disks, err := cim.ListDisksByTarget(target) + if err != nil { + return fmt.Errorf("error getting target disks on target %s from target portal at (%s:%d). err: %w", iqn, portal.Address, portal.Port, err) + } + + for _, disk := range disks { + number, err := cim.GetDiskNumber(disk) + if err != nil { + return fmt.Errorf("error getting number of disk %v on target %s from target portal at (%s:%d). err: %w", disk, iqn, portal.Address, portal.Port, err) + } + + ids = append(ids, strconv.Itoa(int(number))) + } + + return nil + }) + return ids, err } func (APIImplementor) SetMutualChapSecret(mutualChapSecret string) error { - result, err := cim.SetISCSISessionChapSecret(mutualChapSecret) - if err != nil { - return fmt.Errorf("error setting mutual chap secret. result: %d, err: %v", result, err) - } + return cim.WithCOMThread(func() error { + result, err := cim.SetISCSISessionChapSecret(mutualChapSecret) + if err != nil { + return fmt.Errorf("error setting mutual chap secret. result: %d, err: %v", result, err) + } - return nil + return nil + }) } diff --git a/pkg/os/smb/api.go b/pkg/os/smb/api.go index f0d28da4..9e60c9dd 100644 --- a/pkg/os/smb/api.go +++ b/pkg/os/smb/api.go @@ -28,17 +28,22 @@ func New(requirePrivacy bool) *SmbAPI { } func (*SmbAPI) IsSmbMapped(remotePath string) (bool, error) { - inst, err := cim.QuerySmbGlobalMappingByRemotePath(remotePath) - if err != nil { - return false, cim.IgnoreNotFound(err) - } - - status, err := cim.GetSmbGlobalMappingStatus(inst) - if err != nil { - return false, err - } - - return status == cim.SmbMappingStatusOK, nil + var isMapped bool + err := cim.WithCOMThread(func() error { + inst, err := cim.QuerySmbGlobalMappingByRemotePath(remotePath) + if err != nil { + return err + } + + status, err := cim.GetSmbGlobalMappingStatus(inst) + if err != nil { + return err + } + + isMapped = status == cim.SmbMappingStatusOK + return nil + }) + return isMapped, cim.IgnoreNotFound(err) } // NewSmbLink - creates a directory symbolic link to the remote share. @@ -62,19 +67,21 @@ func (*SmbAPI) NewSmbLink(remotePath, localPath string) error { } func (api *SmbAPI) NewSmbGlobalMapping(remotePath, username, password string) error { - result, err := cim.NewSmbGlobalMapping(remotePath, username, password, api.RequirePrivacy) - if err != nil { - return fmt.Errorf("NewSmbGlobalMapping failed. result: %d, err: %v", result, err) - } - - return nil + return cim.WithCOMThread(func() error { + result, err := cim.NewSmbGlobalMapping(remotePath, username, password, api.RequirePrivacy) + if err != nil { + return fmt.Errorf("NewSmbGlobalMapping failed. result: %d, err: %v", result, err) + } + return nil + }) } func (*SmbAPI) RemoveSmbGlobalMapping(remotePath string) error { - err := cim.RemoveSmbGlobalMappingByRemotePath(remotePath) - if err != nil { - return fmt.Errorf("error remove smb mapping '%s'. err: %v", remotePath, err) - } - - return nil + return cim.WithCOMThread(func() error { + err := cim.RemoveSmbGlobalMappingByRemotePath(remotePath) + if err != nil { + return fmt.Errorf("error remove smb mapping '%s'. err: %v", remotePath, err) + } + return nil + }) } diff --git a/pkg/os/system/api.go b/pkg/os/system/api.go index 2a8ddaf8..d209b8e5 100644 --- a/pkg/os/system/api.go +++ b/pkg/os/system/api.go @@ -107,45 +107,54 @@ func New() APIImplementor { } func (APIImplementor) GetBIOSSerialNumber() (string, error) { - bios, err := cim.QueryBIOSElement(cim.BIOSSelectorList) - if err != nil { - return "", fmt.Errorf("failed to get BIOS element: %w", err) - } + var sn string + err := cim.WithCOMThread(func() error { + bios, err := cim.QueryBIOSElement(cim.BIOSSelectorList) + if err != nil { + return fmt.Errorf("failed to get BIOS element: %w", err) + } - sn, err := cim.GetBIOSSerialNumber(bios) - if err != nil { - return "", fmt.Errorf("failed to get BIOS serial number property: %w", err) - } + sn, err = cim.GetBIOSSerialNumber(bios) + if err != nil { + return fmt.Errorf("failed to get BIOS serial number property: %w", err) + } - return sn, nil + return nil + }) + return sn, err } func (impl APIImplementor) GetService(name string) (*ServiceInfo, error) { - service, err := impl.serviceFactory.GetService(name) - if err != nil { - return nil, fmt.Errorf("failed to get service %s. error: %w", name, err) - } + var serviceInfo *ServiceInfo + err := cim.WithCOMThread(func() error { + service, err := impl.serviceFactory.GetService(name) + if err != nil { + return fmt.Errorf("failed to get service %s. error: %w", name, err) + } - displayName, err := cim.GetServiceDisplayName(service) - if err != nil { - return nil, fmt.Errorf("failed to get displayName property of service %s: %w", name, err) - } + displayName, err := cim.GetServiceDisplayName(service) + if err != nil { + return fmt.Errorf("failed to get displayName property of service %s: %w", name, err) + } - state, err := cim.GetServiceState(service) - if err != nil { - return nil, fmt.Errorf("failed to get state property of service %s: %w", name, err) - } + state, err := cim.GetServiceState(service) + if err != nil { + return fmt.Errorf("failed to get state property of service %s: %w", name, err) + } - startMode, err := cim.GetServiceStartMode(service) - if err != nil { - return nil, fmt.Errorf("failed to get startMode property of service %s: %w", name, err) - } + startMode, err := cim.GetServiceStartMode(service) + if err != nil { + return fmt.Errorf("failed to get startMode property of service %s: %w", name, err) + } - return &ServiceInfo{ - DisplayName: displayName, - StartType: serviceStartModeToStartType(startMode), - Status: serviceState(state), - }, nil + serviceInfo = &ServiceInfo{ + DisplayName: displayName, + StartType: serviceStartModeToStartType(startMode), + Status: serviceState(state), + } + return nil + }) + return serviceInfo, err } func (impl APIImplementor) StartService(name string) error { @@ -171,21 +180,23 @@ func (impl APIImplementor) StartService(name string) error { return state == serviceStateRunning, newState, err } - service, err := impl.serviceFactory.GetService(name) - if err != nil { - return fmt.Errorf("failed to get service %s. error: %w", name, err) - } + return cim.WithCOMThread(func() error { + service, err := impl.serviceFactory.GetService(name) + if err != nil { + return fmt.Errorf("failed to get service %s. error: %w", name, err) + } - state, err := impl.serviceManager.WaitUntilServiceState(service, startService, serviceRunningCheck, serviceStateCheckInternal, serviceStateCheckTimeout) - if err != nil && !errors.Is(err, errTimedOut) { - return fmt.Errorf("failed to wait for service %s state change. error: %w", name, err) - } + state, err := impl.serviceManager.WaitUntilServiceState(service, startService, serviceRunningCheck, serviceStateCheckInternal, serviceStateCheckTimeout) + if err != nil && !errors.Is(err, errTimedOut) { + return fmt.Errorf("failed to wait for service %s state change. error: %w", name, err) + } - if state != serviceStateRunning { - return fmt.Errorf("timed out waiting for service %s to become running", name) - } + if state != serviceStateRunning { + return fmt.Errorf("timed out waiting for service %s to become running", name) + } - return nil + return nil + }) } func (impl APIImplementor) stopSingleService(name string) (bool, error) { @@ -234,27 +245,29 @@ func (impl APIImplementor) stopSingleService(name string) (bool, error) { } func (impl APIImplementor) StopService(name string, force bool) error { - dependentRunning, err := impl.stopSingleService(name) - if err == nil { - return nil - } - if !dependentRunning || !force { - return fmt.Errorf("failed to stop service %s. error: %w", name, err) - } - - serviceNames, err := impl.serviceManager.GetDependentsForService(name) - if err != nil { - return fmt.Errorf("error getting dependent services for service name %s", name) - } + return cim.WithCOMThread(func() error { + dependentRunning, err := impl.stopSingleService(name) + if err == nil { + return nil + } + if !dependentRunning || !force { + return fmt.Errorf("failed to stop service %s. error: %w", name, err) + } - for _, serviceName := range serviceNames { - _, err = impl.stopSingleService(serviceName) + serviceNames, err := impl.serviceManager.GetDependentsForService(name) if err != nil { - return fmt.Errorf("failed to stop service %s. error: %w", name, err) + return fmt.Errorf("error getting dependent services for service name %s", name) + } + + for _, serviceName := range serviceNames { + _, err = impl.stopSingleService(serviceName) + if err != nil { + return fmt.Errorf("failed to stop service %s. error: %w", name, err) + } } - } - return nil + return nil + }) } type ServiceManagerImpl struct { diff --git a/pkg/os/volume/api.go b/pkg/os/volume/api.go index ea667798..87a10f0f 100644 --- a/pkg/os/volume/api.go +++ b/pkg/os/volume/api.go @@ -69,50 +69,55 @@ func New() VolumeAPI { // ListVolumesOnDisk - returns back list of volumes(volumeIDs) in a disk and a partition. func (VolumeAPI) ListVolumesOnDisk(diskNumber uint32, partitionNumber uint32) (volumeIDs []string, err error) { - partitions, err := cim.ListPartitionsOnDisk(diskNumber, partitionNumber, cim.PartitionSelectorListObjectID) - if err != nil { - return nil, errors.Wrapf(err, "failed to list partition on disk %d", diskNumber) - } + err = cim.WithCOMThread(func() error { + partitions, err := cim.ListPartitionsOnDisk(diskNumber, partitionNumber, cim.PartitionSelectorListObjectID) + if err != nil { + return errors.Wrapf(err, "failed to list partition on disk %d", diskNumber) + } - volumes, err := cim.FindVolumesByPartition(partitions) - if cim.IgnoreNotFound(err) != nil { - return nil, errors.Wrapf(err, "failed to list volumes on disk %d", diskNumber) - } + volumes, err := cim.FindVolumesByPartition(partitions) + if cim.IgnoreNotFound(err) != nil { + return errors.Wrapf(err, "failed to list volumes on disk %d", diskNumber) + } - for _, volume := range volumes { - uniqueID, err := cim.GetVolumeUniqueID(volume) - if err != nil { - return nil, errors.Wrapf(err, "failed to get unique ID for volume %v", volume) + for _, volume := range volumes { + uniqueID, err := cim.GetVolumeUniqueID(volume) + if err != nil { + return errors.Wrapf(err, "failed to get unique ID for volume %v", volume) + } + volumeIDs = append(volumeIDs, uniqueID) } - volumeIDs = append(volumeIDs, uniqueID) - } - return volumeIDs, nil + return nil + }) + return } // FormatVolume - Formats a volume with the NTFS format. func (VolumeAPI) FormatVolume(volumeID string) (err error) { - volume, err := cim.QueryVolumeByUniqueID(volumeID, nil) - if err != nil { - return fmt.Errorf("error formatting volume (%s). error: %v", volumeID, err) - } + return cim.WithCOMThread(func() error { + volume, err := cim.QueryVolumeByUniqueID(volumeID, nil) + if err != nil { + return fmt.Errorf("error formatting volume (%s). error: %v", volumeID, err) + } - result, err := cim.FormatVolume(volume, - "NTFS", // Format, - "", // FileSystemLabel, - nil, // AllocationUnitSize, - false, // Full, - true, // Force - nil, // Compress, - nil, // ShortFileNameSupport, - nil, // SetIntegrityStreams, - nil, // UseLargeFRS, - nil, // DisableHeatGathering, - ) - if result != 0 || err != nil { - return fmt.Errorf("error formatting volume (%s). result: %d, error: %v", volumeID, result, err) - } - return nil + result, err := cim.FormatVolume(volume, + "NTFS", // Format, + "", // FileSystemLabel, + nil, // AllocationUnitSize, + false, // Full, + true, // Force + nil, // Compress, + nil, // ShortFileNameSupport, + nil, // SetIntegrityStreams, + nil, // UseLargeFRS, + nil, // DisableHeatGathering, + ) + if result != 0 || err != nil { + return fmt.Errorf("error formatting volume (%s). result: %d, error: %v", volumeID, result, err) + } + return nil + }) } // WriteVolumeCache - Writes the file system cache to disk with the given volume id @@ -122,17 +127,22 @@ func (VolumeAPI) WriteVolumeCache(volumeID string) (err error) { // IsVolumeFormatted - Check if the volume is formatted with the pre specified filesystem(typically ntfs). func (VolumeAPI) IsVolumeFormatted(volumeID string) (bool, error) { - volume, err := cim.QueryVolumeByUniqueID(volumeID, cim.VolumeSelectorListForFileSystemType) - if err != nil { - return false, fmt.Errorf("error checking if volume (%s) is formatted. error: %v", volumeID, err) - } + var formatted bool + err := cim.WithCOMThread(func() error { + volume, err := cim.QueryVolumeByUniqueID(volumeID, cim.VolumeSelectorListForFileSystemType) + if err != nil { + return fmt.Errorf("error checking if volume (%s) is formatted. error: %v", volumeID, err) + } - fsType, err := cim.GetVolumeFileSystemType(volume) - if err != nil { - return false, fmt.Errorf("failed to query volume file system type (%s): %w", volumeID, err) - } + fsType, err := cim.GetVolumeFileSystemType(volume) + if err != nil { + return fmt.Errorf("failed to query volume file system type (%s): %w", volumeID, err) + } - return fsType != cim.FileSystemUnknown, nil + formatted = fsType != cim.FileSystemUnknown + return nil + }) + return formatted, err } // MountVolume - mounts a volume to a path. This is done using Win32 API SetVolumeMountPoint for presenting the volume via a path. @@ -182,101 +192,112 @@ func (VolumeAPI) UnmountVolume(volumeID, path string) error { // ResizeVolume - resizes a volume with the given size, if size == 0 then max supported size is used func (VolumeAPI) ResizeVolume(volumeID string, size int64) error { - var err error - var finalSize int64 - part, err := cim.GetPartitionByVolumeUniqueID(volumeID) - if err != nil { - return err - } - - // If size is 0 then we will resize to the maximum size possible, otherwise just resize to size - if size == 0 { - var result int - var status string - result, _, finalSize, status, err = cim.GetPartitionSupportedSize(part) - if result != 0 || err != nil { - return fmt.Errorf("error getting sizeMin, sizeMax from volume (%s). result: %d, status: %s, error: %v", volumeID, result, status, err) + return cim.WithCOMThread(func() error { + var err error + var finalSize int64 + part, err := cim.GetPartitionByVolumeUniqueID(volumeID) + if err != nil { + return err } - } else { - finalSize = size - } + // If size is 0 then we will resize to the maximum size possible, otherwise just resize to size + if size == 0 { + var result int + var status string + result, _, finalSize, status, err = cim.GetPartitionSupportedSize(part) + if result != 0 || err != nil { + return fmt.Errorf("error getting sizeMin, sizeMax from volume (%s). result: %d, status: %s, error: %v", volumeID, result, status, err) + } - currentSize, err := cim.GetPartitionSize(part) - if err != nil { - return fmt.Errorf("error getting the current size of volume (%s) with error (%v)", volumeID, err) - } + } else { + finalSize = size + } - // only resize if finalSize - currentSize is greater than 100MB - if finalSize-currentSize < minimumResizeSize { - klog.V(2).Infof("minimum resize difference (100MB) not met, skipping resize. volumeID=%s currentSize=%d finalSize=%d", volumeID, currentSize, finalSize) - return nil - } + currentSize, err := cim.GetPartitionSize(part) + if err != nil { + return fmt.Errorf("error getting the current size of volume (%s) with error (%v)", volumeID, err) + } - //if the partition's size is already the size we want this is a noop, just return - if currentSize >= finalSize { - klog.V(2).Infof("Attempted to resize volume (%s) to a lower size, from currentBytes=%d wantedBytes=%d", volumeID, currentSize, finalSize) - return nil - } + // only resize if finalSize - currentSize is greater than 100MB + if finalSize-currentSize < minimumResizeSize { + klog.V(2).Infof("minimum resize difference (100MB) not met, skipping resize. volumeID=%s currentSize=%d finalSize=%d", volumeID, currentSize, finalSize) + return nil + } - result, _, err := cim.ResizePartition(part, finalSize) - if result != 0 || err != nil { - return fmt.Errorf("error resizing volume (%s). size:%v, finalSize %v, error: %v", volumeID, size, finalSize, err) - } + //if the partition's size is already the size we want this is a noop, just return + if currentSize >= finalSize { + klog.V(2).Infof("Attempted to resize volume (%s) to a lower size, from currentBytes=%d wantedBytes=%d", volumeID, currentSize, finalSize) + return nil + } - diskNumber, err := cim.GetPartitionDiskNumber(part) - if err != nil { - return fmt.Errorf("error parsing disk number of volume (%s). error: %v", volumeID, err) - } + result, _, err := cim.ResizePartition(part, finalSize) + if result != 0 || err != nil { + return fmt.Errorf("error resizing volume (%s). size:%v, finalSize %v, error: %v", volumeID, size, finalSize, err) + } - disk, err := cim.QueryDiskByNumber(diskNumber, nil) - if err != nil { - return fmt.Errorf("error query disk of volume (%s). error: %v", volumeID, err) - } + diskNumber, err := cim.GetPartitionDiskNumber(part) + if err != nil { + return fmt.Errorf("error parsing disk number of volume (%s). error: %v", volumeID, err) + } - result, _, err = cim.RefreshDisk(disk) - if result != 0 || err != nil { - return fmt.Errorf("error rescan disk (%d). result %d, error: %v", diskNumber, result, err) - } + disk, err := cim.QueryDiskByNumber(diskNumber, nil) + if err != nil { + return fmt.Errorf("error query disk of volume (%s). error: %v", volumeID, err) + } - return nil + result, _, err = cim.RefreshDisk(disk) + if result != 0 || err != nil { + return fmt.Errorf("error rescan disk (%d). result %d, error: %v", diskNumber, result, err) + } + + return nil + }) } // GetVolumeStats - retrieves the volume stats for a given volume -func (VolumeAPI) GetVolumeStats(volumeID string) (int64, int64, error) { - volume, err := cim.QueryVolumeByUniqueID(volumeID, cim.VolumeSelectorListForStats) - if err != nil { - return -1, -1, fmt.Errorf("error getting capacity and used size of volume (%s). error: %v", volumeID, err) - } +func (VolumeAPI) GetVolumeStats(volumeID string) (volumeSize, volumeUsedSize int64, err error) { + volumeSize = -1 + volumeUsedSize = -1 + err = cim.WithCOMThread(func() error { + volume, err := cim.QueryVolumeByUniqueID(volumeID, cim.VolumeSelectorListForStats) + if err != nil { + return fmt.Errorf("error getting capacity and used size of volume (%s). error: %v", volumeID, err) + } - volumeSize, err := cim.GetVolumeSize(volume) - if err != nil { - return -1, -1, fmt.Errorf("failed to query volume size (%s): %w", volumeID, err) - } + volumeSize, err = cim.GetVolumeSize(volume) + if err != nil { + return fmt.Errorf("failed to query volume size (%s): %w", volumeID, err) + } - volumeSizeRemaining, err := cim.GetVolumeSizeRemaining(volume) - if err != nil { - return -1, -1, fmt.Errorf("failed to query volume remaining size (%s): %w", volumeID, err) - } + volumeSizeRemaining, err := cim.GetVolumeSizeRemaining(volume) + if err != nil { + return fmt.Errorf("failed to query volume remaining size (%s): %w", volumeID, err) + } - volumeUsedSize := volumeSize - volumeSizeRemaining - return volumeSize, volumeUsedSize, nil + volumeUsedSize = volumeSize - volumeSizeRemaining + return nil + }) + return } // GetDiskNumberFromVolumeID - gets the disk number where the volume is. func (VolumeAPI) GetDiskNumberFromVolumeID(volumeID string) (uint32, error) { - // get the size and sizeRemaining for the volume - part, err := cim.GetPartitionByVolumeUniqueID(volumeID) - if err != nil { - return 0, err - } + var diskNumber uint32 + err := cim.WithCOMThread(func() error { + // get the size and sizeRemaining for the volume + part, err := cim.GetPartitionByVolumeUniqueID(volumeID) + if err != nil { + return err + } - diskNumber, err := cim.GetPartitionDiskNumber(part) - if err != nil { - return 0, fmt.Errorf("error query disk number of volume (%s). error: %v", volumeID, err) - } + diskNumber, err = cim.GetPartitionDiskNumber(part) + if err != nil { + return fmt.Errorf("error query disk number of volume (%s). error: %v", volumeID, err) + } - return diskNumber, nil + return nil + }) + return diskNumber, err } // GetVolumeIDFromTargetPath - gets the volume ID given a mount point, the function is recursive until it find a volume or errors out @@ -395,28 +416,34 @@ func getVolumeForDriveLetter(path string) (string, error) { return "", fmt.Errorf("the path %s is not a valid drive letter", path) } - volume, err := cim.GetVolumeByDriveLetter(path, cim.VolumeSelectorListUniqueID) - if err != nil { - return "", nil - } + var uniqueID string + err := cim.WithCOMThread(func() error { + volume, err := cim.GetVolumeByDriveLetter(path, cim.VolumeSelectorListUniqueID) + if err != nil { + return err + } - uniqueID, err := cim.GetVolumeUniqueID(volume) - if err != nil { - return "", fmt.Errorf("error query unique ID of volume (%v). error: %v", volume, err) - } + uniqueID, err = cim.GetVolumeUniqueID(volume) + if err != nil { + return fmt.Errorf("error query unique ID of volume (%v). error: %v", volume, err) + } - return uniqueID, nil + return nil + }) + return uniqueID, err } func writeCache(volumeID string) error { - volume, err := cim.QueryVolumeByUniqueID(volumeID, nil) - if err != nil { - return fmt.Errorf("error writing volume (%s) cache. error: %v", volumeID, err) - } + return cim.WithCOMThread(func() error { + volume, err := cim.QueryVolumeByUniqueID(volumeID, nil) + if err != nil { + return fmt.Errorf("error writing volume (%s) cache. error: %v", volumeID, err) + } - result, err := cim.FlushVolume(volume) - if result != 0 || err != nil { - return fmt.Errorf("error writing volume (%s) cache. result: %d, error: %v", volumeID, result, err) - } - return nil + result, err := cim.FlushVolume(volume) + if result != 0 || err != nil { + return fmt.Errorf("error writing volume (%s) cache. result: %d, error: %v", volumeID, result, err) + } + return nil + }) } From 3fd5d3968fafd4afabc8647d29a616efecb8420b Mon Sep 17 00:00:00 2001 From: Zhongcheng Lao Date: Wed, 2 Jul 2025 08:16:40 +0800 Subject: [PATCH 3/3] Bump microsoft/wmi --- .github/workflows/windows.yml | 6 +- Makefile | 5 +- go.mod | 8 +- go.sum | 8 +- pkg/cim/wmi.go | 102 +----------- release-tools/prow.sh | 2 +- scripts/run-integration.sh | 4 - .../wmi/pkg/base/instance/instancemanager.go | 6 +- .../microsoft/wmi/pkg/errors/errors.go | 25 +-- .../wmi/pkg/wmiinstance/WmiMethod.go | 39 +++-- vendor/golang.org/x/sys/unix/auxv.go | 36 +++++ .../golang.org/x/sys/unix/auxv_unsupported.go | 13 ++ .../golang.org/x/sys/unix/syscall_darwin.go | 149 +++++++++++++++++- .../x/sys/unix/syscall_dragonfly.go | 12 ++ vendor/golang.org/x/sys/unix/syscall_linux.go | 42 ++--- .../golang.org/x/sys/unix/syscall_solaris.go | 87 ++++++++++ vendor/golang.org/x/sys/unix/zerrors_linux.go | 20 ++- .../x/sys/unix/zerrors_linux_386.go | 3 + .../x/sys/unix/zerrors_linux_amd64.go | 3 + .../x/sys/unix/zerrors_linux_arm.go | 3 + .../x/sys/unix/zerrors_linux_arm64.go | 4 + .../x/sys/unix/zerrors_linux_loong64.go | 3 + .../x/sys/unix/zerrors_linux_mips.go | 3 + .../x/sys/unix/zerrors_linux_mips64.go | 3 + .../x/sys/unix/zerrors_linux_mips64le.go | 3 + .../x/sys/unix/zerrors_linux_mipsle.go | 3 + .../x/sys/unix/zerrors_linux_ppc.go | 3 + .../x/sys/unix/zerrors_linux_ppc64.go | 3 + .../x/sys/unix/zerrors_linux_ppc64le.go | 3 + .../x/sys/unix/zerrors_linux_riscv64.go | 3 + .../x/sys/unix/zerrors_linux_s390x.go | 3 + .../x/sys/unix/zerrors_linux_sparc64.go | 3 + .../x/sys/unix/zsyscall_darwin_amd64.go | 84 ++++++++++ .../x/sys/unix/zsyscall_darwin_amd64.s | 20 +++ .../x/sys/unix/zsyscall_darwin_arm64.go | 84 ++++++++++ .../x/sys/unix/zsyscall_darwin_arm64.s | 20 +++ .../x/sys/unix/zsyscall_solaris_amd64.go | 114 ++++++++++++++ .../x/sys/unix/zsysnum_linux_386.go | 4 + .../x/sys/unix/zsysnum_linux_amd64.go | 4 + .../x/sys/unix/zsysnum_linux_arm.go | 4 + .../x/sys/unix/zsysnum_linux_arm64.go | 4 + .../x/sys/unix/zsysnum_linux_loong64.go | 4 + .../x/sys/unix/zsysnum_linux_mips.go | 4 + .../x/sys/unix/zsysnum_linux_mips64.go | 4 + .../x/sys/unix/zsysnum_linux_mips64le.go | 4 + .../x/sys/unix/zsysnum_linux_mipsle.go | 4 + .../x/sys/unix/zsysnum_linux_ppc.go | 4 + .../x/sys/unix/zsysnum_linux_ppc64.go | 4 + .../x/sys/unix/zsysnum_linux_ppc64le.go | 4 + .../x/sys/unix/zsysnum_linux_riscv64.go | 4 + .../x/sys/unix/zsysnum_linux_s390x.go | 4 + .../x/sys/unix/zsysnum_linux_sparc64.go | 4 + vendor/golang.org/x/sys/unix/ztypes_linux.go | 6 +- .../golang.org/x/sys/windows/dll_windows.go | 11 +- .../golang.org/x/sys/windows/svc/service.go | 20 ++- .../golang.org/x/sys/windows/types_windows.go | 27 ++++ vendor/modules.txt | 8 +- 57 files changed, 868 insertions(+), 196 deletions(-) create mode 100644 vendor/golang.org/x/sys/unix/auxv.go create mode 100644 vendor/golang.org/x/sys/unix/auxv_unsupported.go diff --git a/.github/workflows/windows.yml b/.github/workflows/windows.yml index f0d136d8..54f5cfce 100644 --- a/.github/workflows/windows.yml +++ b/.github/workflows/windows.yml @@ -4,7 +4,7 @@ jobs: integration_tests: strategy: matrix: - go: ['1.22'] + go: ['1.24'] platform: [windows-latest] runs-on: ${{ matrix.platform }} steps: @@ -51,7 +51,7 @@ jobs: unit_tests: strategy: matrix: - go: ['1.22'] + go: ['1.24'] platform: [windows-latest] runs-on: ${{ matrix.platform }} steps: @@ -69,7 +69,7 @@ jobs: bump_version_test: strategy: matrix: - go: ['1.22'] + go: ['1.24'] platform: [ubuntu-latest] runs-on: ${{ matrix.platform }} steps: diff --git a/Makefile b/Makefile index e9d222d4..59a21b37 100644 --- a/Makefile +++ b/Makefile @@ -13,10 +13,7 @@ GO_ENV_VARS = GO111MODULE=on GOOS=windows CSI_PROXY_API_GEN = $(BUILD_DIR)/csi-proxy-api-gen # overrides the $(CMDS:%=build-%) rule in release-tools/build.make because this project is not compatible with go >1.23 -# TODO: remove this override as part of https://github.com/kubernetes-csi/csi-proxy/issues/361 -build-csi-proxy: check-go-version-go - # Checks that the go version is 1.22 or lower - if (( "$$(go version | awk '{print $3}' | sed 's/go//' | cut -d'.' -f2)" > 22 )); then echo "This project requires go 1.22 or lower"; exit 1; fi; +build-csi-proxy: mkdir -p bin # os_arch_seen captures all of the $$os-$$arch-$$buildx_platform seen for the current binary # that we want to build, if we've seen an $$os-$$arch-$$buildx_platform before it means that diff --git a/go.mod b/go.mod index c35fe375..7b8565a3 100644 --- a/go.mod +++ b/go.mod @@ -3,9 +3,9 @@ module github.com/kubernetes-csi/csi-proxy // NOTE: This project must be built with go < 1.23 // `make build` will error if go1.23 or higher is used. -go 1.22.0 +go 1.24.3 -toolchain go1.22.3 +toolchain go1.24.4 require ( github.com/Microsoft/go-winio v0.6.2 @@ -14,13 +14,13 @@ require ( github.com/grpc-ecosystem/go-grpc-middleware/providers/prometheus v1.0.1 github.com/iancoleman/strcase v0.3.0 github.com/kubernetes-csi/csi-proxy/client v1.1.3 - github.com/microsoft/wmi v0.25.1 + github.com/microsoft/wmi v0.31.2 github.com/pkg/errors v0.9.1 github.com/prometheus/client_golang v1.20.5 github.com/sergi/go-diff v1.3.1 github.com/spf13/pflag v1.0.5 github.com/stretchr/testify v1.10.0 - golang.org/x/sys v0.28.0 + golang.org/x/sys v0.32.0 google.golang.org/grpc v1.69.2 google.golang.org/protobuf v1.36.0 k8s.io/component-base v0.28.4 diff --git a/go.sum b/go.sum index 4167e64c..acd08cb5 100644 --- a/go.sum +++ b/go.sum @@ -71,8 +71,8 @@ github.com/kylelemons/godebug v1.1.0 h1:RPNrshWIDI6G2gRW9EHilWtl7Z6Sb1BR0xunSBf0 github.com/kylelemons/godebug v1.1.0/go.mod h1:9/0rRGxNHcop5bhtWyNeEfOS8JIWk580+fNqagV/RAw= github.com/mauriciopoppe/gengo v0.0.0-20210525224835-9c78f58f3486 h1:+l047vEi0SyAzdVToIaAcfoY5DwwGW+OyqTdH/P3TTg= github.com/mauriciopoppe/gengo v0.0.0-20210525224835-9c78f58f3486/go.mod h1:xXv3T4UXTLta31wMhVezwVkc26OLei4hMbLeBJbPmxc= -github.com/microsoft/wmi v0.25.1 h1:sQv9hCEHtW5K6yEVL78T6XGRMGxk4aTpcJwCiB5rLN0= -github.com/microsoft/wmi v0.25.1/go.mod h1:1zbdSF0A+5OwTUII5p3hN7/K6KF2m3o27pSG6Y51VU8= +github.com/microsoft/wmi v0.31.2 h1:yRu5Jys/vedyV7aHb/mR2HA0n9WECi3CFw+af4CdR5k= +github.com/microsoft/wmi v0.31.2/go.mod h1:uImvBuQss3NEnzU5bcwq0DsUh54seU3Sl//oBn62LDw= github.com/munnerz/goautoneg v0.0.0-20191010083416-a7dc8b61c822 h1:C3w9PqII01/Oq1c1nUAm88MOHcQC9l5mIlSMApZMrHA= github.com/munnerz/goautoneg v0.0.0-20191010083416-a7dc8b61c822/go.mod h1:+n7T8mK8HuQTcFwEeznm/DIxMOiR9yIdICNftLE1DvQ= github.com/pkg/errors v0.9.1 h1:FEBLx1zS214owpjy7qsBeixbURkuhQAwrK5UwLGTwt4= @@ -139,8 +139,8 @@ golang.org/x/sys v0.0.0-20180905080454-ebe1bf3edb33/go.mod h1:STP8DvDyc/dI5b8T5h golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20190916202348-b4ddaad3f8a3/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.1.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.28.0 h1:Fksou7UEQUWlKvIdsqzJmUmCX3cZuD2+P3XyyzwMhlA= -golang.org/x/sys v0.28.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= +golang.org/x/sys v0.32.0 h1:s77OFDvIQeibCmezSnk/q6iAfkdiQaJi4VzroCFrN20= +golang.org/x/sys v0.32.0/go.mod h1:BJP2sWEmIv4KK5OTEluFJCKSidICx8ciO85XgH3Ak8k= golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= golang.org/x/text v0.21.0 h1:zyQAAkrwaneQ066sspRyJaG9VNi/YJ1NfzcGB3hZ/qo= golang.org/x/text v0.21.0/go.mod h1:4IBbMaMmOPCJ8SecivzSH54+73PCFmPWxNTLm+vZkEQ= diff --git a/pkg/cim/wmi.go b/pkg/cim/wmi.go index ec9c8f08..cc41ed5c 100644 --- a/pkg/cim/wmi.go +++ b/pkg/cim/wmi.go @@ -9,7 +9,6 @@ import ( "runtime" "github.com/go-ole/go-ole" - "github.com/go-ole/go-ole/oleutil" "github.com/microsoft/wmi/pkg/base/query" wmierrors "github.com/microsoft/wmi/pkg/errors" cim "github.com/microsoft/wmi/pkg/wmiinstance" @@ -91,105 +90,6 @@ func QueryInstances(namespace string, query *query.WmiQuery) ([]*cim.WmiInstance return instances, err } -// TODO: fix the panic in microsoft/wmi library and remove this workaround -// Refer to https://github.com/microsoft/wmi/issues/167 -func executeClassMethodParam(classInst *cim.WmiInstance, method *cim.WmiMethod, inParam, outParam cim.WmiMethodParamCollection) (result *cim.WmiMethodResult, err error) { - klog.V(6).Infof("[WMI] - Executing Method [%s]\n", method.Name) - - iDispatchInstance := classInst.GetIDispatch() - if iDispatchInstance == nil { - return nil, wmierrors.Wrapf(wmierrors.InvalidInput, "InvalidInstance") - } - rawResult, err := iDispatchInstance.GetProperty("Methods_") - if err != nil { - return nil, err - } - defer rawResult.Clear() - // Retrieve the method - rawMethod, err := rawResult.ToIDispatch().CallMethod("Item", method.Name) - if err != nil { - return nil, err - } - defer rawMethod.Clear() - - addInParam := func(inparamVariant *ole.VARIANT, paramName string, paramValue interface{}) error { - rawProperties, err := inparamVariant.ToIDispatch().GetProperty("Properties_") - if err != nil { - return err - } - defer rawProperties.Clear() - rawProperty, err := rawProperties.ToIDispatch().CallMethod("Item", paramName) - if err != nil { - return err - } - defer rawProperty.Clear() - - p, err := rawProperty.ToIDispatch().PutProperty("Value", paramValue) - if err != nil { - return err - } - defer p.Clear() - return nil - } - - params := []interface{}{method.Name} - if len(inParam) > 0 { - inparamsRaw, err := rawMethod.ToIDispatch().GetProperty("InParameters") - if err != nil { - return nil, err - } - defer inparamsRaw.Clear() - - inparams, err := oleutil.CallMethod(inparamsRaw.ToIDispatch(), "SpawnInstance_") - if err != nil { - return nil, err - } - defer inparams.Clear() - - for _, inp := range inParam { - addInParam(inparams, inp.Name, inp.Value) - } - - params = append(params, inparams) - } - - result = &cim.WmiMethodResult{ - OutMethodParams: map[string]*cim.WmiMethodParam{}, - } - outparams, err := classInst.GetIDispatch().CallMethod("ExecMethod_", params...) - if err != nil { - return - } - defer outparams.Clear() - returnRaw, err := outparams.ToIDispatch().GetProperty("ReturnValue") - if err != nil { - return - } - defer returnRaw.Clear() - if returnRaw.Value() != nil { - result.ReturnValue = returnRaw.Value().(int32) - klog.V(6).Infof("[WMI] - Return [%d] ", result.ReturnValue) - } - - for _, outp := range outParam { - returnRawIn, err1 := outparams.ToIDispatch().GetProperty(outp.Name) - if err1 != nil { - err = err1 - return - } - defer returnRawIn.Clear() - - value, err1 := cim.GetVariantValue(returnRawIn) - if err1 != nil { - err = err1 - return - } - - result.OutMethodParams[outp.Name] = cim.NewWmiMethodParam(outp.Name, value) - } - return -} - // InvokeCimMethod calls a static method on a specific WMI class with given input parameters, // returning the method's return value, output parameters, and any error encountered. func InvokeCimMethod(namespace, class, methodName string, inputParameters map[string]interface{}) (int, map[string]interface{}, error) { @@ -225,7 +125,7 @@ func InvokeCimMethod(namespace, class, methodName string, inputParameters map[st var outParam cim.WmiMethodParamCollection var result *cim.WmiMethodResult - result, err = executeClassMethodParam(classInst, method, inParam, outParam) + result, err = method.Execute(inParam, outParam) if err != nil { return -1, nil, err } diff --git a/release-tools/prow.sh b/release-tools/prow.sh index ac0663f2..cc72e697 100755 --- a/release-tools/prow.sh +++ b/release-tools/prow.sh @@ -86,7 +86,7 @@ configvar CSI_PROW_BUILD_PLATFORMS "linux amd64 amd64; linux ppc64le ppc64le -pp # which is disabled with GOFLAGS=-mod=vendor). configvar GOFLAGS_VENDOR "$( [ -d vendor ] && echo '-mod=vendor' )" "Go flags for using the vendor directory" -configvar CSI_PROW_GO_VERSION_BUILD "1.23.1" "Go version for building the component" # depends on component's source code +configvar CSI_PROW_GO_VERSION_BUILD "1.24.3" "Go version for building the component" # depends on component's source code configvar CSI_PROW_GO_VERSION_E2E "" "override Go version for building the Kubernetes E2E test suite" # normally doesn't need to be set, see install_e2e configvar CSI_PROW_GO_VERSION_SANITY "${CSI_PROW_GO_VERSION_BUILD}" "Go version for building the csi-sanity test suite" # depends on CSI_PROW_SANITY settings below configvar CSI_PROW_GO_VERSION_KIND "${CSI_PROW_GO_VERSION_BUILD}" "Go version for building 'kind'" # depends on CSI_PROW_KIND_VERSION below diff --git a/scripts/run-integration.sh b/scripts/run-integration.sh index 4e9a01c8..7cc048a9 100755 --- a/scripts/run-integration.sh +++ b/scripts/run-integration.sh @@ -18,10 +18,6 @@ pkgdir=${GOPATH}/src/github.com/kubernetes-csi/csi-proxy source $pkgdir/scripts/utils.sh main() { - # TODO: remove go version pin as part of https://github.com/kubernetes-csi/csi-proxy/issues/361 - wget -q https://go.dev/dl/go1.22.12.linux-amd64.tar.gz - rm -rf /usr/local/go && tar -C /usr/local -xzf go1.22.12.linux-amd64.tar.gz - compile_csi_proxy compile_csi_proxy_integration_tests sync_csi_proxy diff --git a/vendor/github.com/microsoft/wmi/pkg/base/instance/instancemanager.go b/vendor/github.com/microsoft/wmi/pkg/base/instance/instancemanager.go index ecb68b45..90058f00 100644 --- a/vendor/github.com/microsoft/wmi/pkg/base/instance/instancemanager.go +++ b/vendor/github.com/microsoft/wmi/pkg/base/instance/instancemanager.go @@ -54,20 +54,20 @@ func GetWmiInstanceManagerFromCred(hostname, namespaceName string, cred *credent return GetWmiInstanceManager(hostname, namespaceName, cred.UserName, cred.Password, cred.Domain) } func GetWmiInstanceManager(hostname, namespaceName, userName, password, domainName string) (*WmiInstanceManager, error) { + mutex.Lock() + defer mutex.Unlock() + mapId := strings.Join([]string{hostname, namespaceName, domainName}, "_") if val, ok := instanceManagerMap[mapId]; ok { return val, nil } - mutex.Lock() - defer mutex.Unlock() var err error instanceManagerMap[mapId], err = newWmiInstanceManager(hostname, namespaceName, userName, password, domainName) if err != nil { return nil, err } return instanceManagerMap[mapId], nil - } func (im *WmiInstanceManager) CreateInstance(className string) (*wmi.WmiInstance, error) { diff --git a/vendor/github.com/microsoft/wmi/pkg/errors/errors.go b/vendor/github.com/microsoft/wmi/pkg/errors/errors.go index ffad9b5d..f74ffbf9 100644 --- a/vendor/github.com/microsoft/wmi/pkg/errors/errors.go +++ b/vendor/github.com/microsoft/wmi/pkg/errors/errors.go @@ -15,16 +15,17 @@ const ( ) var ( - NotFound error = errors.New("Not Found") - Timedout error = errors.New("Timedout") - InvalidInput error = errors.New("Invalid Input") - InvalidType error = errors.New("Invalid Type") - NotSupported error = errors.New("Not Supported") - AlreadyExists error = errors.New("Already Exists") - InvalidFilter error = errors.New("Invalid Filter") - Failed error = errors.New("Failed") - NotImplemented error = errors.New("Not Implemented") - Unknown error = errors.New("Unknown Reason") + NotFound error = errors.New("Not Found") + Timedout error = errors.New("Timedout") + InvalidInput error = errors.New("Invalid Input") + InvalidType error = errors.New("Invalid Type") + NotSupported error = errors.New("Not Supported") + AlreadyExists error = errors.New("Already Exists") + InvalidFilter error = errors.New("Invalid Filter") + Failed error = errors.New("Failed") + NotImplemented error = errors.New("Not Implemented") + Unknown error = errors.New("Unknown Reason") + DvdDriveNotFound error = errors.New("DVDDriveNotFound") ) func Wrap(cause error, message string) error { @@ -65,6 +66,10 @@ func IsNotImplemented(err error) bool { func IsUnknown(err error) bool { return checkError(err, Unknown) } +func IsDvdDriveNotFound(err error) bool { + return checkError(err, DvdDriveNotFound) +} + func IsWMIError(err error) bool { if err == nil { return false diff --git a/vendor/github.com/microsoft/wmi/pkg/wmiinstance/WmiMethod.go b/vendor/github.com/microsoft/wmi/pkg/wmiinstance/WmiMethod.go index b1be6e8a..bae88ee8 100644 --- a/vendor/github.com/microsoft/wmi/pkg/wmiinstance/WmiMethod.go +++ b/vendor/github.com/microsoft/wmi/pkg/wmiinstance/WmiMethod.go @@ -75,27 +75,36 @@ func (c *WmiMethod) Execute(inParam, outParam WmiMethodParamCollection) (result } defer rawMethod.Clear() - inparamsRaw, err := rawMethod.ToIDispatch().GetProperty("InParameters") - if err != nil { - return nil, err - } - defer inparamsRaw.Clear() + params := []interface{}{c.Name} - inparams, err := oleutil.CallMethod(inparamsRaw.ToIDispatch(), "SpawnInstance_") - if err != nil { - return nil, err - } - defer inparams.Clear() - - for _, inp := range inParam { - // log.Printf("InParam [%s]=>[%+v]\n", inp.Name, inp.Value) - c.addInParam(inparams, inp.Name, inp.Value) + if len(inParam) > 0 { + inparamsRaw, err := rawMethod.ToIDispatch().GetProperty("InParameters") + if err != nil { + return nil, err + } + defer inparamsRaw.Clear() + + // Method with no parameters may return a VARIANT with nil IDispatch + if inparamsRaw.Val != 0 { + inparams, err := oleutil.CallMethod(inparamsRaw.ToIDispatch(), "SpawnInstance_") + if err != nil { + return nil, err + } + defer inparams.Clear() + + for _, inp := range inParam { + // log.Printf("InParam [%s]=>[%+v]\n", inp.Name, inp.Value) + c.addInParam(inparams, inp.Name, inp.Value) + } + + params = append(params, inparams) + } } result = &WmiMethodResult{ OutMethodParams: map[string]*WmiMethodParam{}, } - outparams, err := c.classInstance.GetIDispatch().CallMethod("ExecMethod_", c.Name, inparams) + outparams, err := c.classInstance.GetIDispatch().CallMethod("ExecMethod_", params...) if err != nil { return } diff --git a/vendor/golang.org/x/sys/unix/auxv.go b/vendor/golang.org/x/sys/unix/auxv.go new file mode 100644 index 00000000..37a82528 --- /dev/null +++ b/vendor/golang.org/x/sys/unix/auxv.go @@ -0,0 +1,36 @@ +// Copyright 2025 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +//go:build go1.21 && (aix || darwin || dragonfly || freebsd || linux || netbsd || openbsd || solaris || zos) + +package unix + +import ( + "syscall" + "unsafe" +) + +//go:linkname runtime_getAuxv runtime.getAuxv +func runtime_getAuxv() []uintptr + +// Auxv returns the ELF auxiliary vector as a sequence of key/value pairs. +// The returned slice is always a fresh copy, owned by the caller. +// It returns an error on non-ELF platforms, or if the auxiliary vector cannot be accessed, +// which happens in some locked-down environments and build modes. +func Auxv() ([][2]uintptr, error) { + vec := runtime_getAuxv() + vecLen := len(vec) + + if vecLen == 0 { + return nil, syscall.ENOENT + } + + if vecLen%2 != 0 { + return nil, syscall.EINVAL + } + + result := make([]uintptr, vecLen) + copy(result, vec) + return unsafe.Slice((*[2]uintptr)(unsafe.Pointer(&result[0])), vecLen/2), nil +} diff --git a/vendor/golang.org/x/sys/unix/auxv_unsupported.go b/vendor/golang.org/x/sys/unix/auxv_unsupported.go new file mode 100644 index 00000000..1200487f --- /dev/null +++ b/vendor/golang.org/x/sys/unix/auxv_unsupported.go @@ -0,0 +1,13 @@ +// Copyright 2025 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +//go:build !go1.21 && (aix || darwin || dragonfly || freebsd || linux || netbsd || openbsd || solaris || zos) + +package unix + +import "syscall" + +func Auxv() ([][2]uintptr, error) { + return nil, syscall.ENOTSUP +} diff --git a/vendor/golang.org/x/sys/unix/syscall_darwin.go b/vendor/golang.org/x/sys/unix/syscall_darwin.go index 099867de..798f61ad 100644 --- a/vendor/golang.org/x/sys/unix/syscall_darwin.go +++ b/vendor/golang.org/x/sys/unix/syscall_darwin.go @@ -602,7 +602,150 @@ func Connectx(fd int, srcIf uint32, srcAddr, dstAddr Sockaddr, associd SaeAssocI return } -//sys connectx(fd int, endpoints *SaEndpoints, associd SaeAssocID, flags uint32, iov []Iovec, n *uintptr, connid *SaeConnID) (err error) +// sys connectx(fd int, endpoints *SaEndpoints, associd SaeAssocID, flags uint32, iov []Iovec, n *uintptr, connid *SaeConnID) (err error) +const minIovec = 8 + +func Readv(fd int, iovs [][]byte) (n int, err error) { + if !darwinKernelVersionMin(11, 0, 0) { + return 0, ENOSYS + } + + iovecs := make([]Iovec, 0, minIovec) + iovecs = appendBytes(iovecs, iovs) + n, err = readv(fd, iovecs) + readvRacedetect(iovecs, n, err) + return n, err +} + +func Preadv(fd int, iovs [][]byte, offset int64) (n int, err error) { + if !darwinKernelVersionMin(11, 0, 0) { + return 0, ENOSYS + } + iovecs := make([]Iovec, 0, minIovec) + iovecs = appendBytes(iovecs, iovs) + n, err = preadv(fd, iovecs, offset) + readvRacedetect(iovecs, n, err) + return n, err +} + +func Writev(fd int, iovs [][]byte) (n int, err error) { + if !darwinKernelVersionMin(11, 0, 0) { + return 0, ENOSYS + } + + iovecs := make([]Iovec, 0, minIovec) + iovecs = appendBytes(iovecs, iovs) + if raceenabled { + raceReleaseMerge(unsafe.Pointer(&ioSync)) + } + n, err = writev(fd, iovecs) + writevRacedetect(iovecs, n) + return n, err +} + +func Pwritev(fd int, iovs [][]byte, offset int64) (n int, err error) { + if !darwinKernelVersionMin(11, 0, 0) { + return 0, ENOSYS + } + + iovecs := make([]Iovec, 0, minIovec) + iovecs = appendBytes(iovecs, iovs) + if raceenabled { + raceReleaseMerge(unsafe.Pointer(&ioSync)) + } + n, err = pwritev(fd, iovecs, offset) + writevRacedetect(iovecs, n) + return n, err +} + +func appendBytes(vecs []Iovec, bs [][]byte) []Iovec { + for _, b := range bs { + var v Iovec + v.SetLen(len(b)) + if len(b) > 0 { + v.Base = &b[0] + } else { + v.Base = (*byte)(unsafe.Pointer(&_zero)) + } + vecs = append(vecs, v) + } + return vecs +} + +func writevRacedetect(iovecs []Iovec, n int) { + if !raceenabled { + return + } + for i := 0; n > 0 && i < len(iovecs); i++ { + m := int(iovecs[i].Len) + if m > n { + m = n + } + n -= m + if m > 0 { + raceReadRange(unsafe.Pointer(iovecs[i].Base), m) + } + } +} + +func readvRacedetect(iovecs []Iovec, n int, err error) { + if !raceenabled { + return + } + for i := 0; n > 0 && i < len(iovecs); i++ { + m := int(iovecs[i].Len) + if m > n { + m = n + } + n -= m + if m > 0 { + raceWriteRange(unsafe.Pointer(iovecs[i].Base), m) + } + } + if err == nil { + raceAcquire(unsafe.Pointer(&ioSync)) + } +} + +func darwinMajorMinPatch() (maj, min, patch int, err error) { + var un Utsname + err = Uname(&un) + if err != nil { + return + } + + var mmp [3]int + c := 0 +Loop: + for _, b := range un.Release[:] { + switch { + case b >= '0' && b <= '9': + mmp[c] = 10*mmp[c] + int(b-'0') + case b == '.': + c++ + if c > 2 { + return 0, 0, 0, ENOTSUP + } + case b == 0: + break Loop + default: + return 0, 0, 0, ENOTSUP + } + } + if c != 2 { + return 0, 0, 0, ENOTSUP + } + return mmp[0], mmp[1], mmp[2], nil +} + +func darwinKernelVersionMin(maj, min, patch int) bool { + actualMaj, actualMin, actualPatch, err := darwinMajorMinPatch() + if err != nil { + return false + } + return actualMaj > maj || actualMaj == maj && (actualMin > min || actualMin == min && actualPatch >= patch) +} + //sys sendfile(infd int, outfd int, offset int64, len *int64, hdtr unsafe.Pointer, flags int) (err error) //sys shmat(id int, addr uintptr, flag int) (ret uintptr, err error) @@ -705,3 +848,7 @@ func Connectx(fd int, srcIf uint32, srcAddr, dstAddr Sockaddr, associd SaeAssocI //sys write(fd int, p []byte) (n int, err error) //sys mmap(addr uintptr, length uintptr, prot int, flag int, fd int, pos int64) (ret uintptr, err error) //sys munmap(addr uintptr, length uintptr) (err error) +//sys readv(fd int, iovecs []Iovec) (n int, err error) +//sys preadv(fd int, iovecs []Iovec, offset int64) (n int, err error) +//sys writev(fd int, iovecs []Iovec) (n int, err error) +//sys pwritev(fd int, iovecs []Iovec, offset int64) (n int, err error) diff --git a/vendor/golang.org/x/sys/unix/syscall_dragonfly.go b/vendor/golang.org/x/sys/unix/syscall_dragonfly.go index 97cb916f..be8c0020 100644 --- a/vendor/golang.org/x/sys/unix/syscall_dragonfly.go +++ b/vendor/golang.org/x/sys/unix/syscall_dragonfly.go @@ -246,6 +246,18 @@ func Sendfile(outfd int, infd int, offset *int64, count int) (written int, err e return sendfile(outfd, infd, offset, count) } +func Dup3(oldfd, newfd, flags int) error { + if oldfd == newfd || flags&^O_CLOEXEC != 0 { + return EINVAL + } + how := F_DUP2FD + if flags&O_CLOEXEC != 0 { + how = F_DUP2FD_CLOEXEC + } + _, err := fcntl(oldfd, how, newfd) + return err +} + /* * Exposed directly */ diff --git a/vendor/golang.org/x/sys/unix/syscall_linux.go b/vendor/golang.org/x/sys/unix/syscall_linux.go index 230a9454..4958a657 100644 --- a/vendor/golang.org/x/sys/unix/syscall_linux.go +++ b/vendor/golang.org/x/sys/unix/syscall_linux.go @@ -13,6 +13,7 @@ package unix import ( "encoding/binary" + "slices" "strconv" "syscall" "time" @@ -417,7 +418,7 @@ func (sa *SockaddrUnix) sockaddr() (unsafe.Pointer, _Socklen, error) { return nil, 0, EINVAL } sa.raw.Family = AF_UNIX - for i := 0; i < n; i++ { + for i := range n { sa.raw.Path[i] = int8(name[i]) } // length is family (uint16), name, NUL. @@ -507,7 +508,7 @@ func (sa *SockaddrL2) sockaddr() (unsafe.Pointer, _Socklen, error) { psm := (*[2]byte)(unsafe.Pointer(&sa.raw.Psm)) psm[0] = byte(sa.PSM) psm[1] = byte(sa.PSM >> 8) - for i := 0; i < len(sa.Addr); i++ { + for i := range len(sa.Addr) { sa.raw.Bdaddr[i] = sa.Addr[len(sa.Addr)-1-i] } cid := (*[2]byte)(unsafe.Pointer(&sa.raw.Cid)) @@ -589,11 +590,11 @@ func (sa *SockaddrCAN) sockaddr() (unsafe.Pointer, _Socklen, error) { sa.raw.Family = AF_CAN sa.raw.Ifindex = int32(sa.Ifindex) rx := (*[4]byte)(unsafe.Pointer(&sa.RxID)) - for i := 0; i < 4; i++ { + for i := range 4 { sa.raw.Addr[i] = rx[i] } tx := (*[4]byte)(unsafe.Pointer(&sa.TxID)) - for i := 0; i < 4; i++ { + for i := range 4 { sa.raw.Addr[i+4] = tx[i] } return unsafe.Pointer(&sa.raw), SizeofSockaddrCAN, nil @@ -618,11 +619,11 @@ func (sa *SockaddrCANJ1939) sockaddr() (unsafe.Pointer, _Socklen, error) { sa.raw.Family = AF_CAN sa.raw.Ifindex = int32(sa.Ifindex) n := (*[8]byte)(unsafe.Pointer(&sa.Name)) - for i := 0; i < 8; i++ { + for i := range 8 { sa.raw.Addr[i] = n[i] } p := (*[4]byte)(unsafe.Pointer(&sa.PGN)) - for i := 0; i < 4; i++ { + for i := range 4 { sa.raw.Addr[i+8] = p[i] } sa.raw.Addr[12] = sa.Addr @@ -911,7 +912,7 @@ func (sa *SockaddrIUCV) sockaddr() (unsafe.Pointer, _Socklen, error) { // These are EBCDIC encoded by the kernel, but we still need to pad them // with blanks. Initializing with blanks allows the caller to feed in either // a padded or an unpadded string. - for i := 0; i < 8; i++ { + for i := range 8 { sa.raw.Nodeid[i] = ' ' sa.raw.User_id[i] = ' ' sa.raw.Name[i] = ' ' @@ -1148,7 +1149,7 @@ func anyToSockaddr(fd int, rsa *RawSockaddrAny) (Sockaddr, error) { var user [8]byte var name [8]byte - for i := 0; i < 8; i++ { + for i := range 8 { user[i] = byte(pp.User_id[i]) name[i] = byte(pp.Name[i]) } @@ -1173,11 +1174,11 @@ func anyToSockaddr(fd int, rsa *RawSockaddrAny) (Sockaddr, error) { Ifindex: int(pp.Ifindex), } name := (*[8]byte)(unsafe.Pointer(&sa.Name)) - for i := 0; i < 8; i++ { + for i := range 8 { name[i] = pp.Addr[i] } pgn := (*[4]byte)(unsafe.Pointer(&sa.PGN)) - for i := 0; i < 4; i++ { + for i := range 4 { pgn[i] = pp.Addr[i+8] } addr := (*[1]byte)(unsafe.Pointer(&sa.Addr)) @@ -1188,11 +1189,11 @@ func anyToSockaddr(fd int, rsa *RawSockaddrAny) (Sockaddr, error) { Ifindex: int(pp.Ifindex), } rx := (*[4]byte)(unsafe.Pointer(&sa.RxID)) - for i := 0; i < 4; i++ { + for i := range 4 { rx[i] = pp.Addr[i] } tx := (*[4]byte)(unsafe.Pointer(&sa.TxID)) - for i := 0; i < 4; i++ { + for i := range 4 { tx[i] = pp.Addr[i+4] } return sa, nil @@ -2216,10 +2217,7 @@ func readvRacedetect(iovecs []Iovec, n int, err error) { return } for i := 0; n > 0 && i < len(iovecs); i++ { - m := int(iovecs[i].Len) - if m > n { - m = n - } + m := min(int(iovecs[i].Len), n) n -= m if m > 0 { raceWriteRange(unsafe.Pointer(iovecs[i].Base), m) @@ -2270,10 +2268,7 @@ func writevRacedetect(iovecs []Iovec, n int) { return } for i := 0; n > 0 && i < len(iovecs); i++ { - m := int(iovecs[i].Len) - if m > n { - m = n - } + m := min(int(iovecs[i].Len), n) n -= m if m > 0 { raceReadRange(unsafe.Pointer(iovecs[i].Base), m) @@ -2320,12 +2315,7 @@ func isGroupMember(gid int) bool { return false } - for _, g := range groups { - if g == gid { - return true - } - } - return false + return slices.Contains(groups, gid) } func isCapDacOverrideSet() bool { diff --git a/vendor/golang.org/x/sys/unix/syscall_solaris.go b/vendor/golang.org/x/sys/unix/syscall_solaris.go index 21974af0..abc39554 100644 --- a/vendor/golang.org/x/sys/unix/syscall_solaris.go +++ b/vendor/golang.org/x/sys/unix/syscall_solaris.go @@ -1102,3 +1102,90 @@ func (s *Strioctl) SetInt(i int) { func IoctlSetStrioctlRetInt(fd int, req int, s *Strioctl) (int, error) { return ioctlPtrRet(fd, req, unsafe.Pointer(s)) } + +// Ucred Helpers +// See ucred(3c) and getpeerucred(3c) + +//sys getpeerucred(fd uintptr, ucred *uintptr) (err error) +//sys ucredFree(ucred uintptr) = ucred_free +//sys ucredGet(pid int) (ucred uintptr, err error) = ucred_get +//sys ucredGeteuid(ucred uintptr) (uid int) = ucred_geteuid +//sys ucredGetegid(ucred uintptr) (gid int) = ucred_getegid +//sys ucredGetruid(ucred uintptr) (uid int) = ucred_getruid +//sys ucredGetrgid(ucred uintptr) (gid int) = ucred_getrgid +//sys ucredGetsuid(ucred uintptr) (uid int) = ucred_getsuid +//sys ucredGetsgid(ucred uintptr) (gid int) = ucred_getsgid +//sys ucredGetpid(ucred uintptr) (pid int) = ucred_getpid + +// Ucred is an opaque struct that holds user credentials. +type Ucred struct { + ucred uintptr +} + +// We need to ensure that ucredFree is called on the underlying ucred +// when the Ucred is garbage collected. +func ucredFinalizer(u *Ucred) { + ucredFree(u.ucred) +} + +func GetPeerUcred(fd uintptr) (*Ucred, error) { + var ucred uintptr + err := getpeerucred(fd, &ucred) + if err != nil { + return nil, err + } + result := &Ucred{ + ucred: ucred, + } + // set the finalizer on the result so that the ucred will be freed + runtime.SetFinalizer(result, ucredFinalizer) + return result, nil +} + +func UcredGet(pid int) (*Ucred, error) { + ucred, err := ucredGet(pid) + if err != nil { + return nil, err + } + result := &Ucred{ + ucred: ucred, + } + // set the finalizer on the result so that the ucred will be freed + runtime.SetFinalizer(result, ucredFinalizer) + return result, nil +} + +func (u *Ucred) Geteuid() int { + defer runtime.KeepAlive(u) + return ucredGeteuid(u.ucred) +} + +func (u *Ucred) Getruid() int { + defer runtime.KeepAlive(u) + return ucredGetruid(u.ucred) +} + +func (u *Ucred) Getsuid() int { + defer runtime.KeepAlive(u) + return ucredGetsuid(u.ucred) +} + +func (u *Ucred) Getegid() int { + defer runtime.KeepAlive(u) + return ucredGetegid(u.ucred) +} + +func (u *Ucred) Getrgid() int { + defer runtime.KeepAlive(u) + return ucredGetrgid(u.ucred) +} + +func (u *Ucred) Getsgid() int { + defer runtime.KeepAlive(u) + return ucredGetsgid(u.ucred) +} + +func (u *Ucred) Getpid() int { + defer runtime.KeepAlive(u) + return ucredGetpid(u.ucred) +} diff --git a/vendor/golang.org/x/sys/unix/zerrors_linux.go b/vendor/golang.org/x/sys/unix/zerrors_linux.go index 6ebc48b3..4f432bfe 100644 --- a/vendor/golang.org/x/sys/unix/zerrors_linux.go +++ b/vendor/golang.org/x/sys/unix/zerrors_linux.go @@ -1245,6 +1245,7 @@ const ( FAN_REPORT_DFID_NAME = 0xc00 FAN_REPORT_DFID_NAME_TARGET = 0x1e00 FAN_REPORT_DIR_FID = 0x400 + FAN_REPORT_FD_ERROR = 0x2000 FAN_REPORT_FID = 0x200 FAN_REPORT_NAME = 0x800 FAN_REPORT_PIDFD = 0x80 @@ -1330,8 +1331,10 @@ const ( FUSE_SUPER_MAGIC = 0x65735546 FUTEXFS_SUPER_MAGIC = 0xbad1dea F_ADD_SEALS = 0x409 + F_CREATED_QUERY = 0x404 F_DUPFD = 0x0 F_DUPFD_CLOEXEC = 0x406 + F_DUPFD_QUERY = 0x403 F_EXLCK = 0x4 F_GETFD = 0x1 F_GETFL = 0x3 @@ -1551,6 +1554,7 @@ const ( IPPROTO_ROUTING = 0x2b IPPROTO_RSVP = 0x2e IPPROTO_SCTP = 0x84 + IPPROTO_SMC = 0x100 IPPROTO_TCP = 0x6 IPPROTO_TP = 0x1d IPPROTO_UDP = 0x11 @@ -1623,6 +1627,8 @@ const ( IPV6_UNICAST_IF = 0x4c IPV6_USER_FLOW = 0xe IPV6_V6ONLY = 0x1a + IPV6_VERSION = 0x60 + IPV6_VERSION_MASK = 0xf0 IPV6_XFRM_POLICY = 0x23 IP_ADD_MEMBERSHIP = 0x23 IP_ADD_SOURCE_MEMBERSHIP = 0x27 @@ -1867,6 +1873,7 @@ const ( MADV_UNMERGEABLE = 0xd MADV_WILLNEED = 0x3 MADV_WIPEONFORK = 0x12 + MAP_DROPPABLE = 0x8 MAP_FILE = 0x0 MAP_FIXED = 0x10 MAP_FIXED_NOREPLACE = 0x100000 @@ -1967,6 +1974,7 @@ const ( MSG_PEEK = 0x2 MSG_PROXY = 0x10 MSG_RST = 0x1000 + MSG_SOCK_DEVMEM = 0x2000000 MSG_SYN = 0x400 MSG_TRUNC = 0x20 MSG_TRYHARD = 0x4 @@ -2083,6 +2091,7 @@ const ( NFC_ATR_REQ_MAXSIZE = 0x40 NFC_ATR_RES_GB_MAXSIZE = 0x2f NFC_ATR_RES_MAXSIZE = 0x40 + NFC_ATS_MAXSIZE = 0x14 NFC_COMM_ACTIVE = 0x0 NFC_COMM_PASSIVE = 0x1 NFC_DEVICE_NAME_MAXSIZE = 0x8 @@ -2163,6 +2172,7 @@ const ( NFNL_SUBSYS_QUEUE = 0x3 NFNL_SUBSYS_ULOG = 0x4 NFS_SUPER_MAGIC = 0x6969 + NFT_BITWISE_BOOL = 0x0 NFT_CHAIN_FLAGS = 0x7 NFT_CHAIN_MAXNAMELEN = 0x100 NFT_CT_MAX = 0x17 @@ -2491,6 +2501,7 @@ const ( PR_GET_PDEATHSIG = 0x2 PR_GET_SECCOMP = 0x15 PR_GET_SECUREBITS = 0x1b + PR_GET_SHADOW_STACK_STATUS = 0x4a PR_GET_SPECULATION_CTRL = 0x34 PR_GET_TAGGED_ADDR_CTRL = 0x38 PR_GET_THP_DISABLE = 0x2a @@ -2499,6 +2510,7 @@ const ( PR_GET_TIMING = 0xd PR_GET_TSC = 0x19 PR_GET_UNALIGN = 0x5 + PR_LOCK_SHADOW_STACK_STATUS = 0x4c PR_MCE_KILL = 0x21 PR_MCE_KILL_CLEAR = 0x0 PR_MCE_KILL_DEFAULT = 0x2 @@ -2525,6 +2537,8 @@ const ( PR_PAC_GET_ENABLED_KEYS = 0x3d PR_PAC_RESET_KEYS = 0x36 PR_PAC_SET_ENABLED_KEYS = 0x3c + PR_PMLEN_MASK = 0x7f000000 + PR_PMLEN_SHIFT = 0x18 PR_PPC_DEXCR_CTRL_CLEAR = 0x4 PR_PPC_DEXCR_CTRL_CLEAR_ONEXEC = 0x10 PR_PPC_DEXCR_CTRL_EDITABLE = 0x1 @@ -2592,6 +2606,7 @@ const ( PR_SET_PTRACER = 0x59616d61 PR_SET_SECCOMP = 0x16 PR_SET_SECUREBITS = 0x1c + PR_SET_SHADOW_STACK_STATUS = 0x4b PR_SET_SPECULATION_CTRL = 0x35 PR_SET_SYSCALL_USER_DISPATCH = 0x3b PR_SET_TAGGED_ADDR_CTRL = 0x37 @@ -2602,6 +2617,9 @@ const ( PR_SET_UNALIGN = 0x6 PR_SET_VMA = 0x53564d41 PR_SET_VMA_ANON_NAME = 0x0 + PR_SHADOW_STACK_ENABLE = 0x1 + PR_SHADOW_STACK_PUSH = 0x4 + PR_SHADOW_STACK_WRITE = 0x2 PR_SME_GET_VL = 0x40 PR_SME_SET_VL = 0x3f PR_SME_SET_VL_ONEXEC = 0x40000 @@ -2911,7 +2929,6 @@ const ( RTM_NEWNEXTHOP = 0x68 RTM_NEWNEXTHOPBUCKET = 0x74 RTM_NEWNSID = 0x58 - RTM_NEWNVLAN = 0x70 RTM_NEWPREFIX = 0x34 RTM_NEWQDISC = 0x24 RTM_NEWROUTE = 0x18 @@ -2920,6 +2937,7 @@ const ( RTM_NEWTCLASS = 0x28 RTM_NEWTFILTER = 0x2c RTM_NEWTUNNEL = 0x78 + RTM_NEWVLAN = 0x70 RTM_NR_FAMILIES = 0x1b RTM_NR_MSGTYPES = 0x6c RTM_SETDCB = 0x4f 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 c0d45e32..75207613 100644 --- a/vendor/golang.org/x/sys/unix/zerrors_linux_386.go +++ b/vendor/golang.org/x/sys/unix/zerrors_linux_386.go @@ -116,6 +116,8 @@ const ( IN_CLOEXEC = 0x80000 IN_NONBLOCK = 0x800 IOCTL_VM_SOCKETS_GET_LOCAL_CID = 0x7b9 + IPV6_FLOWINFO_MASK = 0xffffff0f + IPV6_FLOWLABEL_MASK = 0xffff0f00 ISIG = 0x1 IUCLC = 0x200 IXOFF = 0x1000 @@ -304,6 +306,7 @@ const ( SCM_TIMESTAMPING_OPT_STATS = 0x36 SCM_TIMESTAMPING_PKTINFO = 0x3a SCM_TIMESTAMPNS = 0x23 + SCM_TS_OPT_ID = 0x51 SCM_TXTIME = 0x3d SCM_WIFI_STATUS = 0x29 SECCOMP_IOCTL_NOTIF_ADDFD = 0x40182103 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 c731d24f..c68acda5 100644 --- a/vendor/golang.org/x/sys/unix/zerrors_linux_amd64.go +++ b/vendor/golang.org/x/sys/unix/zerrors_linux_amd64.go @@ -116,6 +116,8 @@ const ( IN_CLOEXEC = 0x80000 IN_NONBLOCK = 0x800 IOCTL_VM_SOCKETS_GET_LOCAL_CID = 0x7b9 + IPV6_FLOWINFO_MASK = 0xffffff0f + IPV6_FLOWLABEL_MASK = 0xffff0f00 ISIG = 0x1 IUCLC = 0x200 IXOFF = 0x1000 @@ -305,6 +307,7 @@ const ( SCM_TIMESTAMPING_OPT_STATS = 0x36 SCM_TIMESTAMPING_PKTINFO = 0x3a SCM_TIMESTAMPNS = 0x23 + SCM_TS_OPT_ID = 0x51 SCM_TXTIME = 0x3d SCM_WIFI_STATUS = 0x29 SECCOMP_IOCTL_NOTIF_ADDFD = 0x40182103 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 680018a4..a8c607ab 100644 --- a/vendor/golang.org/x/sys/unix/zerrors_linux_arm.go +++ b/vendor/golang.org/x/sys/unix/zerrors_linux_arm.go @@ -115,6 +115,8 @@ const ( IN_CLOEXEC = 0x80000 IN_NONBLOCK = 0x800 IOCTL_VM_SOCKETS_GET_LOCAL_CID = 0x7b9 + IPV6_FLOWINFO_MASK = 0xffffff0f + IPV6_FLOWLABEL_MASK = 0xffff0f00 ISIG = 0x1 IUCLC = 0x200 IXOFF = 0x1000 @@ -310,6 +312,7 @@ const ( SCM_TIMESTAMPING_OPT_STATS = 0x36 SCM_TIMESTAMPING_PKTINFO = 0x3a SCM_TIMESTAMPNS = 0x23 + SCM_TS_OPT_ID = 0x51 SCM_TXTIME = 0x3d SCM_WIFI_STATUS = 0x29 SECCOMP_IOCTL_NOTIF_ADDFD = 0x40182103 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 a63909f3..18563dd8 100644 --- a/vendor/golang.org/x/sys/unix/zerrors_linux_arm64.go +++ b/vendor/golang.org/x/sys/unix/zerrors_linux_arm64.go @@ -109,6 +109,7 @@ const ( F_SETOWN = 0x8 F_UNLCK = 0x2 F_WRLCK = 0x1 + GCS_MAGIC = 0x47435300 HIDIOCGRAWINFO = 0x80084803 HIDIOCGRDESC = 0x90044802 HIDIOCGRDESCSIZE = 0x80044801 @@ -119,6 +120,8 @@ const ( IN_CLOEXEC = 0x80000 IN_NONBLOCK = 0x800 IOCTL_VM_SOCKETS_GET_LOCAL_CID = 0x7b9 + IPV6_FLOWINFO_MASK = 0xffffff0f + IPV6_FLOWLABEL_MASK = 0xffff0f00 ISIG = 0x1 IUCLC = 0x200 IXOFF = 0x1000 @@ -302,6 +305,7 @@ const ( SCM_TIMESTAMPING_OPT_STATS = 0x36 SCM_TIMESTAMPING_PKTINFO = 0x3a SCM_TIMESTAMPNS = 0x23 + SCM_TS_OPT_ID = 0x51 SCM_TXTIME = 0x3d SCM_WIFI_STATUS = 0x29 SECCOMP_IOCTL_NOTIF_ADDFD = 0x40182103 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 9b0a2573..22912cda 100644 --- a/vendor/golang.org/x/sys/unix/zerrors_linux_loong64.go +++ b/vendor/golang.org/x/sys/unix/zerrors_linux_loong64.go @@ -116,6 +116,8 @@ const ( IN_CLOEXEC = 0x80000 IN_NONBLOCK = 0x800 IOCTL_VM_SOCKETS_GET_LOCAL_CID = 0x7b9 + IPV6_FLOWINFO_MASK = 0xffffff0f + IPV6_FLOWLABEL_MASK = 0xffff0f00 ISIG = 0x1 IUCLC = 0x200 IXOFF = 0x1000 @@ -297,6 +299,7 @@ const ( SCM_TIMESTAMPING_OPT_STATS = 0x36 SCM_TIMESTAMPING_PKTINFO = 0x3a SCM_TIMESTAMPNS = 0x23 + SCM_TS_OPT_ID = 0x51 SCM_TXTIME = 0x3d SCM_WIFI_STATUS = 0x29 SECCOMP_IOCTL_NOTIF_ADDFD = 0x40182103 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 958e6e06..29344eb3 100644 --- a/vendor/golang.org/x/sys/unix/zerrors_linux_mips.go +++ b/vendor/golang.org/x/sys/unix/zerrors_linux_mips.go @@ -115,6 +115,8 @@ const ( IN_CLOEXEC = 0x80000 IN_NONBLOCK = 0x80 IOCTL_VM_SOCKETS_GET_LOCAL_CID = 0x200007b9 + IPV6_FLOWINFO_MASK = 0xfffffff + IPV6_FLOWLABEL_MASK = 0xfffff ISIG = 0x1 IUCLC = 0x200 IXOFF = 0x1000 @@ -303,6 +305,7 @@ const ( SCM_TIMESTAMPING_OPT_STATS = 0x36 SCM_TIMESTAMPING_PKTINFO = 0x3a SCM_TIMESTAMPNS = 0x23 + SCM_TS_OPT_ID = 0x51 SCM_TXTIME = 0x3d SCM_WIFI_STATUS = 0x29 SECCOMP_IOCTL_NOTIF_ADDFD = 0x80182103 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 50c7f25b..20d51fb9 100644 --- a/vendor/golang.org/x/sys/unix/zerrors_linux_mips64.go +++ b/vendor/golang.org/x/sys/unix/zerrors_linux_mips64.go @@ -115,6 +115,8 @@ const ( IN_CLOEXEC = 0x80000 IN_NONBLOCK = 0x80 IOCTL_VM_SOCKETS_GET_LOCAL_CID = 0x200007b9 + IPV6_FLOWINFO_MASK = 0xfffffff + IPV6_FLOWLABEL_MASK = 0xfffff ISIG = 0x1 IUCLC = 0x200 IXOFF = 0x1000 @@ -303,6 +305,7 @@ const ( SCM_TIMESTAMPING_OPT_STATS = 0x36 SCM_TIMESTAMPING_PKTINFO = 0x3a SCM_TIMESTAMPNS = 0x23 + SCM_TS_OPT_ID = 0x51 SCM_TXTIME = 0x3d SCM_WIFI_STATUS = 0x29 SECCOMP_IOCTL_NOTIF_ADDFD = 0x80182103 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 ced21d66..321b6090 100644 --- a/vendor/golang.org/x/sys/unix/zerrors_linux_mips64le.go +++ b/vendor/golang.org/x/sys/unix/zerrors_linux_mips64le.go @@ -115,6 +115,8 @@ const ( IN_CLOEXEC = 0x80000 IN_NONBLOCK = 0x80 IOCTL_VM_SOCKETS_GET_LOCAL_CID = 0x200007b9 + IPV6_FLOWINFO_MASK = 0xffffff0f + IPV6_FLOWLABEL_MASK = 0xffff0f00 ISIG = 0x1 IUCLC = 0x200 IXOFF = 0x1000 @@ -303,6 +305,7 @@ const ( SCM_TIMESTAMPING_OPT_STATS = 0x36 SCM_TIMESTAMPING_PKTINFO = 0x3a SCM_TIMESTAMPNS = 0x23 + SCM_TS_OPT_ID = 0x51 SCM_TXTIME = 0x3d SCM_WIFI_STATUS = 0x29 SECCOMP_IOCTL_NOTIF_ADDFD = 0x80182103 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 226c0441..9bacdf1e 100644 --- a/vendor/golang.org/x/sys/unix/zerrors_linux_mipsle.go +++ b/vendor/golang.org/x/sys/unix/zerrors_linux_mipsle.go @@ -115,6 +115,8 @@ const ( IN_CLOEXEC = 0x80000 IN_NONBLOCK = 0x80 IOCTL_VM_SOCKETS_GET_LOCAL_CID = 0x200007b9 + IPV6_FLOWINFO_MASK = 0xffffff0f + IPV6_FLOWLABEL_MASK = 0xffff0f00 ISIG = 0x1 IUCLC = 0x200 IXOFF = 0x1000 @@ -303,6 +305,7 @@ const ( SCM_TIMESTAMPING_OPT_STATS = 0x36 SCM_TIMESTAMPING_PKTINFO = 0x3a SCM_TIMESTAMPNS = 0x23 + SCM_TS_OPT_ID = 0x51 SCM_TXTIME = 0x3d SCM_WIFI_STATUS = 0x29 SECCOMP_IOCTL_NOTIF_ADDFD = 0x80182103 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 3122737c..c2242726 100644 --- a/vendor/golang.org/x/sys/unix/zerrors_linux_ppc.go +++ b/vendor/golang.org/x/sys/unix/zerrors_linux_ppc.go @@ -115,6 +115,8 @@ const ( IN_CLOEXEC = 0x80000 IN_NONBLOCK = 0x800 IOCTL_VM_SOCKETS_GET_LOCAL_CID = 0x200007b9 + IPV6_FLOWINFO_MASK = 0xfffffff + IPV6_FLOWLABEL_MASK = 0xfffff ISIG = 0x80 IUCLC = 0x1000 IXOFF = 0x400 @@ -358,6 +360,7 @@ const ( SCM_TIMESTAMPING_OPT_STATS = 0x36 SCM_TIMESTAMPING_PKTINFO = 0x3a SCM_TIMESTAMPNS = 0x23 + SCM_TS_OPT_ID = 0x51 SCM_TXTIME = 0x3d SCM_WIFI_STATUS = 0x29 SECCOMP_IOCTL_NOTIF_ADDFD = 0x80182103 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 eb5d3467..6270c8ee 100644 --- a/vendor/golang.org/x/sys/unix/zerrors_linux_ppc64.go +++ b/vendor/golang.org/x/sys/unix/zerrors_linux_ppc64.go @@ -115,6 +115,8 @@ const ( IN_CLOEXEC = 0x80000 IN_NONBLOCK = 0x800 IOCTL_VM_SOCKETS_GET_LOCAL_CID = 0x200007b9 + IPV6_FLOWINFO_MASK = 0xfffffff + IPV6_FLOWLABEL_MASK = 0xfffff ISIG = 0x80 IUCLC = 0x1000 IXOFF = 0x400 @@ -362,6 +364,7 @@ const ( SCM_TIMESTAMPING_OPT_STATS = 0x36 SCM_TIMESTAMPING_PKTINFO = 0x3a SCM_TIMESTAMPNS = 0x23 + SCM_TS_OPT_ID = 0x51 SCM_TXTIME = 0x3d SCM_WIFI_STATUS = 0x29 SECCOMP_IOCTL_NOTIF_ADDFD = 0x80182103 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 e921ebc6..9966c194 100644 --- a/vendor/golang.org/x/sys/unix/zerrors_linux_ppc64le.go +++ b/vendor/golang.org/x/sys/unix/zerrors_linux_ppc64le.go @@ -115,6 +115,8 @@ const ( IN_CLOEXEC = 0x80000 IN_NONBLOCK = 0x800 IOCTL_VM_SOCKETS_GET_LOCAL_CID = 0x200007b9 + IPV6_FLOWINFO_MASK = 0xffffff0f + IPV6_FLOWLABEL_MASK = 0xffff0f00 ISIG = 0x80 IUCLC = 0x1000 IXOFF = 0x400 @@ -362,6 +364,7 @@ const ( SCM_TIMESTAMPING_OPT_STATS = 0x36 SCM_TIMESTAMPING_PKTINFO = 0x3a SCM_TIMESTAMPNS = 0x23 + SCM_TS_OPT_ID = 0x51 SCM_TXTIME = 0x3d SCM_WIFI_STATUS = 0x29 SECCOMP_IOCTL_NOTIF_ADDFD = 0x80182103 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 38ba81c5..848e5fcc 100644 --- a/vendor/golang.org/x/sys/unix/zerrors_linux_riscv64.go +++ b/vendor/golang.org/x/sys/unix/zerrors_linux_riscv64.go @@ -115,6 +115,8 @@ const ( IN_CLOEXEC = 0x80000 IN_NONBLOCK = 0x800 IOCTL_VM_SOCKETS_GET_LOCAL_CID = 0x7b9 + IPV6_FLOWINFO_MASK = 0xffffff0f + IPV6_FLOWLABEL_MASK = 0xffff0f00 ISIG = 0x1 IUCLC = 0x200 IXOFF = 0x1000 @@ -294,6 +296,7 @@ const ( SCM_TIMESTAMPING_OPT_STATS = 0x36 SCM_TIMESTAMPING_PKTINFO = 0x3a SCM_TIMESTAMPNS = 0x23 + SCM_TS_OPT_ID = 0x51 SCM_TXTIME = 0x3d SCM_WIFI_STATUS = 0x29 SECCOMP_IOCTL_NOTIF_ADDFD = 0x40182103 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 71f04009..669b2adb 100644 --- a/vendor/golang.org/x/sys/unix/zerrors_linux_s390x.go +++ b/vendor/golang.org/x/sys/unix/zerrors_linux_s390x.go @@ -115,6 +115,8 @@ const ( IN_CLOEXEC = 0x80000 IN_NONBLOCK = 0x800 IOCTL_VM_SOCKETS_GET_LOCAL_CID = 0x7b9 + IPV6_FLOWINFO_MASK = 0xfffffff + IPV6_FLOWLABEL_MASK = 0xfffff ISIG = 0x1 IUCLC = 0x200 IXOFF = 0x1000 @@ -366,6 +368,7 @@ const ( SCM_TIMESTAMPING_OPT_STATS = 0x36 SCM_TIMESTAMPING_PKTINFO = 0x3a SCM_TIMESTAMPNS = 0x23 + SCM_TS_OPT_ID = 0x51 SCM_TXTIME = 0x3d SCM_WIFI_STATUS = 0x29 SECCOMP_IOCTL_NOTIF_ADDFD = 0x40182103 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 c44a3133..4834e575 100644 --- a/vendor/golang.org/x/sys/unix/zerrors_linux_sparc64.go +++ b/vendor/golang.org/x/sys/unix/zerrors_linux_sparc64.go @@ -119,6 +119,8 @@ const ( IN_CLOEXEC = 0x400000 IN_NONBLOCK = 0x4000 IOCTL_VM_SOCKETS_GET_LOCAL_CID = 0x200007b9 + IPV6_FLOWINFO_MASK = 0xfffffff + IPV6_FLOWLABEL_MASK = 0xfffff ISIG = 0x1 IUCLC = 0x200 IXOFF = 0x1000 @@ -357,6 +359,7 @@ const ( SCM_TIMESTAMPING_OPT_STATS = 0x38 SCM_TIMESTAMPING_PKTINFO = 0x3c SCM_TIMESTAMPNS = 0x21 + SCM_TS_OPT_ID = 0x5a SCM_TXTIME = 0x3f SCM_WIFI_STATUS = 0x25 SECCOMP_IOCTL_NOTIF_ADDFD = 0x80182103 diff --git a/vendor/golang.org/x/sys/unix/zsyscall_darwin_amd64.go b/vendor/golang.org/x/sys/unix/zsyscall_darwin_amd64.go index 24b346e1..813c05b6 100644 --- a/vendor/golang.org/x/sys/unix/zsyscall_darwin_amd64.go +++ b/vendor/golang.org/x/sys/unix/zsyscall_darwin_amd64.go @@ -2512,6 +2512,90 @@ var libc_munmap_trampoline_addr uintptr // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT +func readv(fd int, iovecs []Iovec) (n int, err error) { + var _p0 unsafe.Pointer + if len(iovecs) > 0 { + _p0 = unsafe.Pointer(&iovecs[0]) + } else { + _p0 = unsafe.Pointer(&_zero) + } + r0, _, e1 := syscall_syscall(libc_readv_trampoline_addr, uintptr(fd), uintptr(_p0), uintptr(len(iovecs))) + n = int(r0) + if e1 != 0 { + err = errnoErr(e1) + } + return +} + +var libc_readv_trampoline_addr uintptr + +//go:cgo_import_dynamic libc_readv readv "/usr/lib/libSystem.B.dylib" + +// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT + +func preadv(fd int, iovecs []Iovec, offset int64) (n int, err error) { + var _p0 unsafe.Pointer + if len(iovecs) > 0 { + _p0 = unsafe.Pointer(&iovecs[0]) + } else { + _p0 = unsafe.Pointer(&_zero) + } + r0, _, e1 := syscall_syscall6(libc_preadv_trampoline_addr, uintptr(fd), uintptr(_p0), uintptr(len(iovecs)), uintptr(offset), 0, 0) + n = int(r0) + if e1 != 0 { + err = errnoErr(e1) + } + return +} + +var libc_preadv_trampoline_addr uintptr + +//go:cgo_import_dynamic libc_preadv preadv "/usr/lib/libSystem.B.dylib" + +// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT + +func writev(fd int, iovecs []Iovec) (n int, err error) { + var _p0 unsafe.Pointer + if len(iovecs) > 0 { + _p0 = unsafe.Pointer(&iovecs[0]) + } else { + _p0 = unsafe.Pointer(&_zero) + } + r0, _, e1 := syscall_syscall(libc_writev_trampoline_addr, uintptr(fd), uintptr(_p0), uintptr(len(iovecs))) + n = int(r0) + if e1 != 0 { + err = errnoErr(e1) + } + return +} + +var libc_writev_trampoline_addr uintptr + +//go:cgo_import_dynamic libc_writev writev "/usr/lib/libSystem.B.dylib" + +// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT + +func pwritev(fd int, iovecs []Iovec, offset int64) (n int, err error) { + var _p0 unsafe.Pointer + if len(iovecs) > 0 { + _p0 = unsafe.Pointer(&iovecs[0]) + } else { + _p0 = unsafe.Pointer(&_zero) + } + r0, _, e1 := syscall_syscall6(libc_pwritev_trampoline_addr, uintptr(fd), uintptr(_p0), uintptr(len(iovecs)), uintptr(offset), 0, 0) + n = int(r0) + if e1 != 0 { + err = errnoErr(e1) + } + return +} + +var libc_pwritev_trampoline_addr uintptr + +//go:cgo_import_dynamic libc_pwritev pwritev "/usr/lib/libSystem.B.dylib" + +// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT + func Fstat(fd int, stat *Stat_t) (err error) { _, _, e1 := syscall_syscall(libc_fstat64_trampoline_addr, uintptr(fd), uintptr(unsafe.Pointer(stat)), 0) if e1 != 0 { diff --git a/vendor/golang.org/x/sys/unix/zsyscall_darwin_amd64.s b/vendor/golang.org/x/sys/unix/zsyscall_darwin_amd64.s index ebd21310..fda32858 100644 --- a/vendor/golang.org/x/sys/unix/zsyscall_darwin_amd64.s +++ b/vendor/golang.org/x/sys/unix/zsyscall_darwin_amd64.s @@ -738,6 +738,26 @@ TEXT libc_munmap_trampoline<>(SB),NOSPLIT,$0-0 GLOBL ·libc_munmap_trampoline_addr(SB), RODATA, $8 DATA ·libc_munmap_trampoline_addr(SB)/8, $libc_munmap_trampoline<>(SB) +TEXT libc_readv_trampoline<>(SB),NOSPLIT,$0-0 + JMP libc_readv(SB) +GLOBL ·libc_readv_trampoline_addr(SB), RODATA, $8 +DATA ·libc_readv_trampoline_addr(SB)/8, $libc_readv_trampoline<>(SB) + +TEXT libc_preadv_trampoline<>(SB),NOSPLIT,$0-0 + JMP libc_preadv(SB) +GLOBL ·libc_preadv_trampoline_addr(SB), RODATA, $8 +DATA ·libc_preadv_trampoline_addr(SB)/8, $libc_preadv_trampoline<>(SB) + +TEXT libc_writev_trampoline<>(SB),NOSPLIT,$0-0 + JMP libc_writev(SB) +GLOBL ·libc_writev_trampoline_addr(SB), RODATA, $8 +DATA ·libc_writev_trampoline_addr(SB)/8, $libc_writev_trampoline<>(SB) + +TEXT libc_pwritev_trampoline<>(SB),NOSPLIT,$0-0 + JMP libc_pwritev(SB) +GLOBL ·libc_pwritev_trampoline_addr(SB), RODATA, $8 +DATA ·libc_pwritev_trampoline_addr(SB)/8, $libc_pwritev_trampoline<>(SB) + TEXT libc_fstat64_trampoline<>(SB),NOSPLIT,$0-0 JMP libc_fstat64(SB) GLOBL ·libc_fstat64_trampoline_addr(SB), RODATA, $8 diff --git a/vendor/golang.org/x/sys/unix/zsyscall_darwin_arm64.go b/vendor/golang.org/x/sys/unix/zsyscall_darwin_arm64.go index 824b9c2d..e6f58f3c 100644 --- a/vendor/golang.org/x/sys/unix/zsyscall_darwin_arm64.go +++ b/vendor/golang.org/x/sys/unix/zsyscall_darwin_arm64.go @@ -2512,6 +2512,90 @@ var libc_munmap_trampoline_addr uintptr // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT +func readv(fd int, iovecs []Iovec) (n int, err error) { + var _p0 unsafe.Pointer + if len(iovecs) > 0 { + _p0 = unsafe.Pointer(&iovecs[0]) + } else { + _p0 = unsafe.Pointer(&_zero) + } + r0, _, e1 := syscall_syscall(libc_readv_trampoline_addr, uintptr(fd), uintptr(_p0), uintptr(len(iovecs))) + n = int(r0) + if e1 != 0 { + err = errnoErr(e1) + } + return +} + +var libc_readv_trampoline_addr uintptr + +//go:cgo_import_dynamic libc_readv readv "/usr/lib/libSystem.B.dylib" + +// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT + +func preadv(fd int, iovecs []Iovec, offset int64) (n int, err error) { + var _p0 unsafe.Pointer + if len(iovecs) > 0 { + _p0 = unsafe.Pointer(&iovecs[0]) + } else { + _p0 = unsafe.Pointer(&_zero) + } + r0, _, e1 := syscall_syscall6(libc_preadv_trampoline_addr, uintptr(fd), uintptr(_p0), uintptr(len(iovecs)), uintptr(offset), 0, 0) + n = int(r0) + if e1 != 0 { + err = errnoErr(e1) + } + return +} + +var libc_preadv_trampoline_addr uintptr + +//go:cgo_import_dynamic libc_preadv preadv "/usr/lib/libSystem.B.dylib" + +// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT + +func writev(fd int, iovecs []Iovec) (n int, err error) { + var _p0 unsafe.Pointer + if len(iovecs) > 0 { + _p0 = unsafe.Pointer(&iovecs[0]) + } else { + _p0 = unsafe.Pointer(&_zero) + } + r0, _, e1 := syscall_syscall(libc_writev_trampoline_addr, uintptr(fd), uintptr(_p0), uintptr(len(iovecs))) + n = int(r0) + if e1 != 0 { + err = errnoErr(e1) + } + return +} + +var libc_writev_trampoline_addr uintptr + +//go:cgo_import_dynamic libc_writev writev "/usr/lib/libSystem.B.dylib" + +// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT + +func pwritev(fd int, iovecs []Iovec, offset int64) (n int, err error) { + var _p0 unsafe.Pointer + if len(iovecs) > 0 { + _p0 = unsafe.Pointer(&iovecs[0]) + } else { + _p0 = unsafe.Pointer(&_zero) + } + r0, _, e1 := syscall_syscall6(libc_pwritev_trampoline_addr, uintptr(fd), uintptr(_p0), uintptr(len(iovecs)), uintptr(offset), 0, 0) + n = int(r0) + if e1 != 0 { + err = errnoErr(e1) + } + return +} + +var libc_pwritev_trampoline_addr uintptr + +//go:cgo_import_dynamic libc_pwritev pwritev "/usr/lib/libSystem.B.dylib" + +// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT + func Fstat(fd int, stat *Stat_t) (err error) { _, _, e1 := syscall_syscall(libc_fstat_trampoline_addr, uintptr(fd), uintptr(unsafe.Pointer(stat)), 0) if e1 != 0 { diff --git a/vendor/golang.org/x/sys/unix/zsyscall_darwin_arm64.s b/vendor/golang.org/x/sys/unix/zsyscall_darwin_arm64.s index 4f178a22..7f8998b9 100644 --- a/vendor/golang.org/x/sys/unix/zsyscall_darwin_arm64.s +++ b/vendor/golang.org/x/sys/unix/zsyscall_darwin_arm64.s @@ -738,6 +738,26 @@ TEXT libc_munmap_trampoline<>(SB),NOSPLIT,$0-0 GLOBL ·libc_munmap_trampoline_addr(SB), RODATA, $8 DATA ·libc_munmap_trampoline_addr(SB)/8, $libc_munmap_trampoline<>(SB) +TEXT libc_readv_trampoline<>(SB),NOSPLIT,$0-0 + JMP libc_readv(SB) +GLOBL ·libc_readv_trampoline_addr(SB), RODATA, $8 +DATA ·libc_readv_trampoline_addr(SB)/8, $libc_readv_trampoline<>(SB) + +TEXT libc_preadv_trampoline<>(SB),NOSPLIT,$0-0 + JMP libc_preadv(SB) +GLOBL ·libc_preadv_trampoline_addr(SB), RODATA, $8 +DATA ·libc_preadv_trampoline_addr(SB)/8, $libc_preadv_trampoline<>(SB) + +TEXT libc_writev_trampoline<>(SB),NOSPLIT,$0-0 + JMP libc_writev(SB) +GLOBL ·libc_writev_trampoline_addr(SB), RODATA, $8 +DATA ·libc_writev_trampoline_addr(SB)/8, $libc_writev_trampoline<>(SB) + +TEXT libc_pwritev_trampoline<>(SB),NOSPLIT,$0-0 + JMP libc_pwritev(SB) +GLOBL ·libc_pwritev_trampoline_addr(SB), RODATA, $8 +DATA ·libc_pwritev_trampoline_addr(SB)/8, $libc_pwritev_trampoline<>(SB) + TEXT libc_fstat_trampoline<>(SB),NOSPLIT,$0-0 JMP libc_fstat(SB) GLOBL ·libc_fstat_trampoline_addr(SB), RODATA, $8 diff --git a/vendor/golang.org/x/sys/unix/zsyscall_solaris_amd64.go b/vendor/golang.org/x/sys/unix/zsyscall_solaris_amd64.go index 829b87fe..c6545413 100644 --- a/vendor/golang.org/x/sys/unix/zsyscall_solaris_amd64.go +++ b/vendor/golang.org/x/sys/unix/zsyscall_solaris_amd64.go @@ -141,6 +141,16 @@ import ( //go:cgo_import_dynamic libc_getpeername getpeername "libsocket.so" //go:cgo_import_dynamic libc_setsockopt setsockopt "libsocket.so" //go:cgo_import_dynamic libc_recvfrom recvfrom "libsocket.so" +//go:cgo_import_dynamic libc_getpeerucred getpeerucred "libc.so" +//go:cgo_import_dynamic libc_ucred_get ucred_get "libc.so" +//go:cgo_import_dynamic libc_ucred_geteuid ucred_geteuid "libc.so" +//go:cgo_import_dynamic libc_ucred_getegid ucred_getegid "libc.so" +//go:cgo_import_dynamic libc_ucred_getruid ucred_getruid "libc.so" +//go:cgo_import_dynamic libc_ucred_getrgid ucred_getrgid "libc.so" +//go:cgo_import_dynamic libc_ucred_getsuid ucred_getsuid "libc.so" +//go:cgo_import_dynamic libc_ucred_getsgid ucred_getsgid "libc.so" +//go:cgo_import_dynamic libc_ucred_getpid ucred_getpid "libc.so" +//go:cgo_import_dynamic libc_ucred_free ucred_free "libc.so" //go:cgo_import_dynamic libc_port_create port_create "libc.so" //go:cgo_import_dynamic libc_port_associate port_associate "libc.so" //go:cgo_import_dynamic libc_port_dissociate port_dissociate "libc.so" @@ -280,6 +290,16 @@ import ( //go:linkname procgetpeername libc_getpeername //go:linkname procsetsockopt libc_setsockopt //go:linkname procrecvfrom libc_recvfrom +//go:linkname procgetpeerucred libc_getpeerucred +//go:linkname procucred_get libc_ucred_get +//go:linkname procucred_geteuid libc_ucred_geteuid +//go:linkname procucred_getegid libc_ucred_getegid +//go:linkname procucred_getruid libc_ucred_getruid +//go:linkname procucred_getrgid libc_ucred_getrgid +//go:linkname procucred_getsuid libc_ucred_getsuid +//go:linkname procucred_getsgid libc_ucred_getsgid +//go:linkname procucred_getpid libc_ucred_getpid +//go:linkname procucred_free libc_ucred_free //go:linkname procport_create libc_port_create //go:linkname procport_associate libc_port_associate //go:linkname procport_dissociate libc_port_dissociate @@ -420,6 +440,16 @@ var ( procgetpeername, procsetsockopt, procrecvfrom, + procgetpeerucred, + procucred_get, + procucred_geteuid, + procucred_getegid, + procucred_getruid, + procucred_getrgid, + procucred_getsuid, + procucred_getsgid, + procucred_getpid, + procucred_free, procport_create, procport_associate, procport_dissociate, @@ -2029,6 +2059,90 @@ func recvfrom(fd int, p []byte, flags int, from *RawSockaddrAny, fromlen *_Sockl // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT +func getpeerucred(fd uintptr, ucred *uintptr) (err error) { + _, _, e1 := sysvicall6(uintptr(unsafe.Pointer(&procgetpeerucred)), 2, uintptr(fd), uintptr(unsafe.Pointer(ucred)), 0, 0, 0, 0) + if e1 != 0 { + err = errnoErr(e1) + } + return +} + +// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT + +func ucredGet(pid int) (ucred uintptr, err error) { + r0, _, e1 := sysvicall6(uintptr(unsafe.Pointer(&procucred_get)), 1, uintptr(pid), 0, 0, 0, 0, 0) + ucred = uintptr(r0) + if e1 != 0 { + err = errnoErr(e1) + } + return +} + +// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT + +func ucredGeteuid(ucred uintptr) (uid int) { + r0, _, _ := sysvicall6(uintptr(unsafe.Pointer(&procucred_geteuid)), 1, uintptr(ucred), 0, 0, 0, 0, 0) + uid = int(r0) + return +} + +// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT + +func ucredGetegid(ucred uintptr) (gid int) { + r0, _, _ := sysvicall6(uintptr(unsafe.Pointer(&procucred_getegid)), 1, uintptr(ucred), 0, 0, 0, 0, 0) + gid = int(r0) + return +} + +// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT + +func ucredGetruid(ucred uintptr) (uid int) { + r0, _, _ := sysvicall6(uintptr(unsafe.Pointer(&procucred_getruid)), 1, uintptr(ucred), 0, 0, 0, 0, 0) + uid = int(r0) + return +} + +// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT + +func ucredGetrgid(ucred uintptr) (gid int) { + r0, _, _ := sysvicall6(uintptr(unsafe.Pointer(&procucred_getrgid)), 1, uintptr(ucred), 0, 0, 0, 0, 0) + gid = int(r0) + return +} + +// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT + +func ucredGetsuid(ucred uintptr) (uid int) { + r0, _, _ := sysvicall6(uintptr(unsafe.Pointer(&procucred_getsuid)), 1, uintptr(ucred), 0, 0, 0, 0, 0) + uid = int(r0) + return +} + +// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT + +func ucredGetsgid(ucred uintptr) (gid int) { + r0, _, _ := sysvicall6(uintptr(unsafe.Pointer(&procucred_getsgid)), 1, uintptr(ucred), 0, 0, 0, 0, 0) + gid = int(r0) + return +} + +// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT + +func ucredGetpid(ucred uintptr) (pid int) { + r0, _, _ := sysvicall6(uintptr(unsafe.Pointer(&procucred_getpid)), 1, uintptr(ucred), 0, 0, 0, 0, 0) + pid = int(r0) + return +} + +// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT + +func ucredFree(ucred uintptr) { + sysvicall6(uintptr(unsafe.Pointer(&procucred_free)), 1, uintptr(ucred), 0, 0, 0, 0, 0) + return +} + +// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT + func port_create() (n int, err error) { r0, _, e1 := sysvicall6(uintptr(unsafe.Pointer(&procport_create)), 0, 0, 0, 0, 0, 0, 0) n = int(r0) diff --git a/vendor/golang.org/x/sys/unix/zsysnum_linux_386.go b/vendor/golang.org/x/sys/unix/zsysnum_linux_386.go index 524b0820..c79aaff3 100644 --- a/vendor/golang.org/x/sys/unix/zsysnum_linux_386.go +++ b/vendor/golang.org/x/sys/unix/zsysnum_linux_386.go @@ -458,4 +458,8 @@ const ( SYS_LSM_SET_SELF_ATTR = 460 SYS_LSM_LIST_MODULES = 461 SYS_MSEAL = 462 + SYS_SETXATTRAT = 463 + SYS_GETXATTRAT = 464 + SYS_LISTXATTRAT = 465 + SYS_REMOVEXATTRAT = 466 ) diff --git a/vendor/golang.org/x/sys/unix/zsysnum_linux_amd64.go b/vendor/golang.org/x/sys/unix/zsysnum_linux_amd64.go index f485dbf4..5eb45069 100644 --- a/vendor/golang.org/x/sys/unix/zsysnum_linux_amd64.go +++ b/vendor/golang.org/x/sys/unix/zsysnum_linux_amd64.go @@ -381,4 +381,8 @@ const ( SYS_LSM_SET_SELF_ATTR = 460 SYS_LSM_LIST_MODULES = 461 SYS_MSEAL = 462 + SYS_SETXATTRAT = 463 + SYS_GETXATTRAT = 464 + SYS_LISTXATTRAT = 465 + SYS_REMOVEXATTRAT = 466 ) diff --git a/vendor/golang.org/x/sys/unix/zsysnum_linux_arm.go b/vendor/golang.org/x/sys/unix/zsysnum_linux_arm.go index 70b35bf3..05e50297 100644 --- a/vendor/golang.org/x/sys/unix/zsysnum_linux_arm.go +++ b/vendor/golang.org/x/sys/unix/zsysnum_linux_arm.go @@ -422,4 +422,8 @@ const ( SYS_LSM_SET_SELF_ATTR = 460 SYS_LSM_LIST_MODULES = 461 SYS_MSEAL = 462 + SYS_SETXATTRAT = 463 + SYS_GETXATTRAT = 464 + SYS_LISTXATTRAT = 465 + SYS_REMOVEXATTRAT = 466 ) diff --git a/vendor/golang.org/x/sys/unix/zsysnum_linux_arm64.go b/vendor/golang.org/x/sys/unix/zsysnum_linux_arm64.go index 1893e2fe..38c53ec5 100644 --- a/vendor/golang.org/x/sys/unix/zsysnum_linux_arm64.go +++ b/vendor/golang.org/x/sys/unix/zsysnum_linux_arm64.go @@ -325,4 +325,8 @@ const ( SYS_LSM_SET_SELF_ATTR = 460 SYS_LSM_LIST_MODULES = 461 SYS_MSEAL = 462 + SYS_SETXATTRAT = 463 + SYS_GETXATTRAT = 464 + SYS_LISTXATTRAT = 465 + SYS_REMOVEXATTRAT = 466 ) diff --git a/vendor/golang.org/x/sys/unix/zsysnum_linux_loong64.go b/vendor/golang.org/x/sys/unix/zsysnum_linux_loong64.go index 16a4017d..31d2e71a 100644 --- a/vendor/golang.org/x/sys/unix/zsysnum_linux_loong64.go +++ b/vendor/golang.org/x/sys/unix/zsysnum_linux_loong64.go @@ -321,4 +321,8 @@ const ( SYS_LSM_SET_SELF_ATTR = 460 SYS_LSM_LIST_MODULES = 461 SYS_MSEAL = 462 + SYS_SETXATTRAT = 463 + SYS_GETXATTRAT = 464 + SYS_LISTXATTRAT = 465 + SYS_REMOVEXATTRAT = 466 ) diff --git a/vendor/golang.org/x/sys/unix/zsysnum_linux_mips.go b/vendor/golang.org/x/sys/unix/zsysnum_linux_mips.go index 7e567f1e..f4184a33 100644 --- a/vendor/golang.org/x/sys/unix/zsysnum_linux_mips.go +++ b/vendor/golang.org/x/sys/unix/zsysnum_linux_mips.go @@ -442,4 +442,8 @@ const ( SYS_LSM_SET_SELF_ATTR = 4460 SYS_LSM_LIST_MODULES = 4461 SYS_MSEAL = 4462 + SYS_SETXATTRAT = 4463 + SYS_GETXATTRAT = 4464 + SYS_LISTXATTRAT = 4465 + SYS_REMOVEXATTRAT = 4466 ) diff --git a/vendor/golang.org/x/sys/unix/zsysnum_linux_mips64.go b/vendor/golang.org/x/sys/unix/zsysnum_linux_mips64.go index 38ae55e5..05b99622 100644 --- a/vendor/golang.org/x/sys/unix/zsysnum_linux_mips64.go +++ b/vendor/golang.org/x/sys/unix/zsysnum_linux_mips64.go @@ -372,4 +372,8 @@ const ( SYS_LSM_SET_SELF_ATTR = 5460 SYS_LSM_LIST_MODULES = 5461 SYS_MSEAL = 5462 + SYS_SETXATTRAT = 5463 + SYS_GETXATTRAT = 5464 + SYS_LISTXATTRAT = 5465 + SYS_REMOVEXATTRAT = 5466 ) diff --git a/vendor/golang.org/x/sys/unix/zsysnum_linux_mips64le.go b/vendor/golang.org/x/sys/unix/zsysnum_linux_mips64le.go index 55e92e60..43a256e9 100644 --- a/vendor/golang.org/x/sys/unix/zsysnum_linux_mips64le.go +++ b/vendor/golang.org/x/sys/unix/zsysnum_linux_mips64le.go @@ -372,4 +372,8 @@ const ( SYS_LSM_SET_SELF_ATTR = 5460 SYS_LSM_LIST_MODULES = 5461 SYS_MSEAL = 5462 + SYS_SETXATTRAT = 5463 + SYS_GETXATTRAT = 5464 + SYS_LISTXATTRAT = 5465 + SYS_REMOVEXATTRAT = 5466 ) diff --git a/vendor/golang.org/x/sys/unix/zsysnum_linux_mipsle.go b/vendor/golang.org/x/sys/unix/zsysnum_linux_mipsle.go index 60658d6a..eea5ddfc 100644 --- a/vendor/golang.org/x/sys/unix/zsysnum_linux_mipsle.go +++ b/vendor/golang.org/x/sys/unix/zsysnum_linux_mipsle.go @@ -442,4 +442,8 @@ const ( SYS_LSM_SET_SELF_ATTR = 4460 SYS_LSM_LIST_MODULES = 4461 SYS_MSEAL = 4462 + SYS_SETXATTRAT = 4463 + SYS_GETXATTRAT = 4464 + SYS_LISTXATTRAT = 4465 + SYS_REMOVEXATTRAT = 4466 ) diff --git a/vendor/golang.org/x/sys/unix/zsysnum_linux_ppc.go b/vendor/golang.org/x/sys/unix/zsysnum_linux_ppc.go index e203e8a7..0d777bfb 100644 --- a/vendor/golang.org/x/sys/unix/zsysnum_linux_ppc.go +++ b/vendor/golang.org/x/sys/unix/zsysnum_linux_ppc.go @@ -449,4 +449,8 @@ const ( SYS_LSM_SET_SELF_ATTR = 460 SYS_LSM_LIST_MODULES = 461 SYS_MSEAL = 462 + SYS_SETXATTRAT = 463 + SYS_GETXATTRAT = 464 + SYS_LISTXATTRAT = 465 + SYS_REMOVEXATTRAT = 466 ) diff --git a/vendor/golang.org/x/sys/unix/zsysnum_linux_ppc64.go b/vendor/golang.org/x/sys/unix/zsysnum_linux_ppc64.go index 5944b97d..b4463650 100644 --- a/vendor/golang.org/x/sys/unix/zsysnum_linux_ppc64.go +++ b/vendor/golang.org/x/sys/unix/zsysnum_linux_ppc64.go @@ -421,4 +421,8 @@ const ( SYS_LSM_SET_SELF_ATTR = 460 SYS_LSM_LIST_MODULES = 461 SYS_MSEAL = 462 + SYS_SETXATTRAT = 463 + SYS_GETXATTRAT = 464 + SYS_LISTXATTRAT = 465 + SYS_REMOVEXATTRAT = 466 ) diff --git a/vendor/golang.org/x/sys/unix/zsysnum_linux_ppc64le.go b/vendor/golang.org/x/sys/unix/zsysnum_linux_ppc64le.go index c66d416d..0c7d21c1 100644 --- a/vendor/golang.org/x/sys/unix/zsysnum_linux_ppc64le.go +++ b/vendor/golang.org/x/sys/unix/zsysnum_linux_ppc64le.go @@ -421,4 +421,8 @@ const ( SYS_LSM_SET_SELF_ATTR = 460 SYS_LSM_LIST_MODULES = 461 SYS_MSEAL = 462 + SYS_SETXATTRAT = 463 + SYS_GETXATTRAT = 464 + SYS_LISTXATTRAT = 465 + SYS_REMOVEXATTRAT = 466 ) diff --git a/vendor/golang.org/x/sys/unix/zsysnum_linux_riscv64.go b/vendor/golang.org/x/sys/unix/zsysnum_linux_riscv64.go index a5459e76..84053916 100644 --- a/vendor/golang.org/x/sys/unix/zsysnum_linux_riscv64.go +++ b/vendor/golang.org/x/sys/unix/zsysnum_linux_riscv64.go @@ -326,4 +326,8 @@ const ( SYS_LSM_SET_SELF_ATTR = 460 SYS_LSM_LIST_MODULES = 461 SYS_MSEAL = 462 + SYS_SETXATTRAT = 463 + SYS_GETXATTRAT = 464 + SYS_LISTXATTRAT = 465 + SYS_REMOVEXATTRAT = 466 ) diff --git a/vendor/golang.org/x/sys/unix/zsysnum_linux_s390x.go b/vendor/golang.org/x/sys/unix/zsysnum_linux_s390x.go index 01d86825..fcf1b790 100644 --- a/vendor/golang.org/x/sys/unix/zsysnum_linux_s390x.go +++ b/vendor/golang.org/x/sys/unix/zsysnum_linux_s390x.go @@ -387,4 +387,8 @@ const ( SYS_LSM_SET_SELF_ATTR = 460 SYS_LSM_LIST_MODULES = 461 SYS_MSEAL = 462 + SYS_SETXATTRAT = 463 + SYS_GETXATTRAT = 464 + SYS_LISTXATTRAT = 465 + SYS_REMOVEXATTRAT = 466 ) diff --git a/vendor/golang.org/x/sys/unix/zsysnum_linux_sparc64.go b/vendor/golang.org/x/sys/unix/zsysnum_linux_sparc64.go index 7b703e77..52d15b5f 100644 --- a/vendor/golang.org/x/sys/unix/zsysnum_linux_sparc64.go +++ b/vendor/golang.org/x/sys/unix/zsysnum_linux_sparc64.go @@ -400,4 +400,8 @@ const ( SYS_LSM_SET_SELF_ATTR = 460 SYS_LSM_LIST_MODULES = 461 SYS_MSEAL = 462 + SYS_SETXATTRAT = 463 + SYS_GETXATTRAT = 464 + SYS_LISTXATTRAT = 465 + SYS_REMOVEXATTRAT = 466 ) diff --git a/vendor/golang.org/x/sys/unix/ztypes_linux.go b/vendor/golang.org/x/sys/unix/ztypes_linux.go index 5537148d..a46abe64 100644 --- a/vendor/golang.org/x/sys/unix/ztypes_linux.go +++ b/vendor/golang.org/x/sys/unix/ztypes_linux.go @@ -4747,7 +4747,7 @@ const ( NL80211_ATTR_MAC_HINT = 0xc8 NL80211_ATTR_MAC_MASK = 0xd7 NL80211_ATTR_MAX_AP_ASSOC_STA = 0xca - NL80211_ATTR_MAX = 0x14c + NL80211_ATTR_MAX = 0x14d NL80211_ATTR_MAX_CRIT_PROT_DURATION = 0xb4 NL80211_ATTR_MAX_CSA_COUNTERS = 0xce NL80211_ATTR_MAX_MATCH_SETS = 0x85 @@ -5519,7 +5519,7 @@ const ( NL80211_MNTR_FLAG_CONTROL = 0x3 NL80211_MNTR_FLAG_COOK_FRAMES = 0x5 NL80211_MNTR_FLAG_FCSFAIL = 0x1 - NL80211_MNTR_FLAG_MAX = 0x6 + NL80211_MNTR_FLAG_MAX = 0x7 NL80211_MNTR_FLAG_OTHER_BSS = 0x4 NL80211_MNTR_FLAG_PLCPFAIL = 0x2 NL80211_MPATH_FLAG_ACTIVE = 0x1 @@ -6174,3 +6174,5 @@ type SockDiagReq struct { Family uint8 Protocol uint8 } + +const RTM_NEWNVLAN = 0x70 diff --git a/vendor/golang.org/x/sys/windows/dll_windows.go b/vendor/golang.org/x/sys/windows/dll_windows.go index 4e613cf6..3ca814f5 100644 --- a/vendor/golang.org/x/sys/windows/dll_windows.go +++ b/vendor/golang.org/x/sys/windows/dll_windows.go @@ -43,8 +43,8 @@ type DLL struct { // LoadDLL loads DLL file into memory. // // Warning: using LoadDLL without an absolute path name is subject to -// DLL preloading attacks. To safely load a system DLL, use LazyDLL -// with System set to true, or use LoadLibraryEx directly. +// DLL preloading attacks. To safely load a system DLL, use [NewLazySystemDLL], +// or use [LoadLibraryEx] directly. func LoadDLL(name string) (dll *DLL, err error) { namep, err := UTF16PtrFromString(name) if err != nil { @@ -271,6 +271,9 @@ func (d *LazyDLL) NewProc(name string) *LazyProc { } // NewLazyDLL creates new LazyDLL associated with DLL file. +// +// Warning: using NewLazyDLL without an absolute path name is subject to +// DLL preloading attacks. To safely load a system DLL, use [NewLazySystemDLL]. func NewLazyDLL(name string) *LazyDLL { return &LazyDLL{Name: name} } @@ -410,7 +413,3 @@ func loadLibraryEx(name string, system bool) (*DLL, error) { } return &DLL{Name: name, Handle: h}, nil } - -type errString string - -func (s errString) Error() string { return string(s) } diff --git a/vendor/golang.org/x/sys/windows/svc/service.go b/vendor/golang.org/x/sys/windows/svc/service.go index c4f74924..a9b1c192 100644 --- a/vendor/golang.org/x/sys/windows/svc/service.go +++ b/vendor/golang.org/x/sys/windows/svc/service.go @@ -132,10 +132,10 @@ type ctlEvent struct { // service provides access to windows service api. type service struct { - name string - h windows.Handle - c chan ctlEvent - handler Handler + namePointer *uint16 + h windows.Handle + c chan ctlEvent + handler Handler } type exitCode struct { @@ -209,7 +209,7 @@ var theService service // This is, unfortunately, a global, which means only one // serviceMain is the entry point called by the service manager, registered earlier by // the call to StartServiceCtrlDispatcher. func serviceMain(argc uint32, argv **uint16) uintptr { - handle, err := windows.RegisterServiceCtrlHandlerEx(windows.StringToUTF16Ptr(theService.name), ctlHandlerCallback, 0) + handle, err := windows.RegisterServiceCtrlHandlerEx(theService.namePointer, ctlHandlerCallback, 0) if sysErr, ok := err.(windows.Errno); ok { return uintptr(sysErr) } else if err != nil { @@ -280,15 +280,21 @@ loop: // Run executes service name by calling appropriate handler function. func Run(name string, handler Handler) error { + // Check to make sure that the service name is valid. + namePointer, err := windows.UTF16PtrFromString(name) + if err != nil { + return err + } + initCallbacks.Do(func() { ctlHandlerCallback = windows.NewCallback(ctlHandler) serviceMainCallback = windows.NewCallback(serviceMain) }) - theService.name = name + theService.namePointer = namePointer theService.handler = handler theService.c = make(chan ctlEvent) t := []windows.SERVICE_TABLE_ENTRY{ - {ServiceName: windows.StringToUTF16Ptr(theService.name), ServiceProc: serviceMainCallback}, + {ServiceName: namePointer, ServiceProc: serviceMainCallback}, {ServiceName: nil, ServiceProc: 0}, } return windows.StartServiceCtrlDispatcher(&t[0]) diff --git a/vendor/golang.org/x/sys/windows/types_windows.go b/vendor/golang.org/x/sys/windows/types_windows.go index 9d138de5..ad67df2f 100644 --- a/vendor/golang.org/x/sys/windows/types_windows.go +++ b/vendor/golang.org/x/sys/windows/types_windows.go @@ -1074,6 +1074,7 @@ const ( IP_ADD_MEMBERSHIP = 0xc IP_DROP_MEMBERSHIP = 0xd IP_PKTINFO = 0x13 + IP_MTU_DISCOVER = 0x47 IPV6_V6ONLY = 0x1b IPV6_UNICAST_HOPS = 0x4 @@ -1083,6 +1084,7 @@ const ( IPV6_JOIN_GROUP = 0xc IPV6_LEAVE_GROUP = 0xd IPV6_PKTINFO = 0x13 + IPV6_MTU_DISCOVER = 0x47 MSG_OOB = 0x1 MSG_PEEK = 0x2 @@ -1132,6 +1134,15 @@ const ( WSASYS_STATUS_LEN = 128 ) +// enum PMTUD_STATE from ws2ipdef.h +const ( + IP_PMTUDISC_NOT_SET = 0 + IP_PMTUDISC_DO = 1 + IP_PMTUDISC_DONT = 2 + IP_PMTUDISC_PROBE = 3 + IP_PMTUDISC_MAX = 4 +) + type WSABuf struct { Len uint32 Buf *byte @@ -1146,6 +1157,22 @@ type WSAMsg struct { Flags uint32 } +type WSACMSGHDR struct { + Len uintptr + Level int32 + Type int32 +} + +type IN_PKTINFO struct { + Addr [4]byte + Ifindex uint32 +} + +type IN6_PKTINFO struct { + Addr [16]byte + Ifindex uint32 +} + // Flags for WSASocket const ( WSA_FLAG_OVERLAPPED = 0x01 diff --git a/vendor/modules.txt b/vendor/modules.txt index 4b390501..25cfe508 100644 --- a/vendor/modules.txt +++ b/vendor/modules.txt @@ -102,8 +102,8 @@ github.com/kubernetes-csi/csi-proxy/client/groups/volume/v1beta1 github.com/kubernetes-csi/csi-proxy/client/groups/volume/v1beta2 github.com/kubernetes-csi/csi-proxy/client/groups/volume/v1beta3 github.com/kubernetes-csi/csi-proxy/client/groups/volume/v2alpha1 -# github.com/microsoft/wmi v0.25.1 -## explicit; go 1.22 +# github.com/microsoft/wmi v0.31.2 +## explicit; go 1.24.3 github.com/microsoft/wmi/go/wmi github.com/microsoft/wmi/pkg/base/credential github.com/microsoft/wmi/pkg/base/host @@ -174,8 +174,8 @@ golang.org/x/net/trace # golang.org/x/sync v0.10.0 ## explicit; go 1.18 golang.org/x/sync/errgroup -# golang.org/x/sys v0.28.0 -## explicit; go 1.18 +# golang.org/x/sys v0.32.0 +## explicit; go 1.23.0 golang.org/x/sys/unix golang.org/x/sys/windows golang.org/x/sys/windows/svc