Merge pull request #116 from ceph/devel

Sync devel branch with upstream
This commit is contained in:
openshift-ci[bot] 2022-08-04 13:33:23 +00:00 committed by GitHub
commit 7cf881f339
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
146 changed files with 9213 additions and 1032 deletions

View File

@ -21,15 +21,15 @@ Card](https://goreportcard.com/badge/github.com/ceph/ceph-csi)](https://goreport
- [Dev standup](#dev-standup)
- [Contact](#contact)
This repo contains Ceph
This repo contains the Ceph
[Container Storage Interface (CSI)](https://github.com/container-storage-interface/)
driver for RBD, CephFS and kubernetes sidecar deployment yamls of provisioner,
attacher, resizer, driver-registrar and snapshotter for supporting CSI functionalities.
driver for RBD, CephFS and Kubernetes sidecar deployment YAMLs to support CSI
functionality: provisioner, attacher, resizer, driver-registrar and snapshotter.
## Overview
Ceph CSI plugins implement an interface between CSI enabled Container Orchestrator
(CO) and Ceph cluster. It allows dynamically provisioning Ceph volumes and
Ceph CSI plugins implement an interface between a CSI-enabled Container Orchestrator
(CO) and Ceph clusters. They enable dynamically provisioning Ceph volumes and
attaching them to workloads.
Independent CSI plugins are provided to support RBD and CephFS backed volumes,
@ -38,7 +38,7 @@ Independent CSI plugins are provided to support RBD and CephFS backed volumes,
[rbd doc](https://github.com/ceph/ceph-csi/blob/devel/docs/deploy-rbd.md) and
for CephFS plugin configuration and deployment please
refer [cephFS doc](https://github.com/ceph/ceph-csi/blob/devel/docs/deploy-cephfs.md).
- For example usage of RBD and CephFS CSI plugins, see examples in `examples/`.
- For example usage of the RBD and CephFS CSI plugins, see examples in `examples/`.
- Stale resource cleanup, please refer [cleanup doc](docs/resource-cleanup.md).
NOTE:
@ -51,7 +51,7 @@ Status: **GA**
## Known to work CO platforms
Ceph CSI drivers are currently developed and tested **exclusively** on Kubernetes
Ceph CSI drivers are currently developed and tested **exclusively** in Kubernetes
environments.
| Ceph CSI Version | Container Orchestrator Name | Version Tested|
@ -62,18 +62,17 @@ environments.
| v3.5.0 | Kubernetes | v1.21, v1.22, v1.23|
| v3.4.0 | Kubernetes | v1.20, v1.21, v1.22|
There is work in progress to make this CO independent and thus
support other orchestration environments (Nomad, Mesos..etc) in the future.
There is work in progress to make this CO-independent and thus
support other orchestration environments (Nomad, Mesos..etc).
NOTE:
The supported window of Ceph CSI versions is known as "N.(x-1)":
The supported window of Ceph CSI versions is "N.(x-1)":
(N (Latest major release) . (x (Latest minor release) - 1)).
For example, if Ceph CSI latest major version is `3.6.0` today, support is
For example, if the Ceph CSI latest major version is `3.6.0` today, support is
provided for the versions above `3.5.0`. If users are running an unsupported
Ceph CSI version, they will be asked to upgrade when requesting support for the
cluster.
Ceph CSI version, they will be asked to upgrade when requesting support.
## Support Matrix

View File

@ -86,6 +86,7 @@ charts and their default values.
| `serviceAccounts.provisioner.name` | The name of the provisioner ServiceAccount of provisioner to use. If not set and create is true, a name is generated using the fullname | "" |
| `csiConfig` | Configuration for the CSI to connect to the cluster | [] |
| `logLevel` | Set logging level for csi containers. Supported values from 0 to 5. 0 for general useful logs, 5 for trace level verbosity. | `5` |
| `sidecarLogLevel` | Set logging level for csi sidecar containers. Supported values from 0 to 5. 0 for general useful logs, 5 for trace level verbosity. | `1` |
| `nodeplugin.name` | Specifies the nodeplugin name | `nodeplugin` |
| `nodeplugin.updateStrategy` | Specifies the update Strategy. If you are using ceph-fuse client set this value to OnDelete | `RollingUpdate` |
| `nodeplugin.priorityClassName` | Set user created priorityclassName for csi plugin pods. default is system-node-critical which is highest priority | `system-node-critical` |
@ -105,6 +106,8 @@ charts and their default values.
| `provisioner.name` | Specifies the name of provisioner | `provisioner` |
| `provisioner.replicaCount` | Specifies the replicaCount | `3` |
| `provisioner.timeout` | GRPC timeout for waiting for creation or deletion of a volume | `60s` |
| `provisioner.clustername` | Cluster name to set on the subvolume | "" |
| `provisioner.setmetadata` | Set metadata on volume | `true` |
| `provisioner.priorityClassName` | Set user created priorityclassName for csi provisioner pods. Default is `system-cluster-critical` which is less priority than `system-node-critical` | `system-cluster-critical` |
| `provisioner.enableHostNetwork` | Specifies whether hostNetwork is enabled for provisioner pod. | `false` |
| `provisioner.profiling.enabled` | Specifies whether profiling should be enabled | `false` |

View File

@ -58,7 +58,7 @@ spec:
imagePullPolicy: {{ .Values.provisioner.provisioner.image.pullPolicy }}
args:
- "--csi-address=$(ADDRESS)"
- "--v={{ .Values.logLevel }}"
- "--v={{ .Values.sidecarLogLevel }}"
- "--timeout={{ .Values.provisioner.timeout }}"
- "--leader-election=true"
- "--retry-interval-start=500ms"
@ -78,9 +78,10 @@ spec:
imagePullPolicy: {{ .Values.provisioner.snapshotter.image.pullPolicy }}
args:
- "--csi-address=$(ADDRESS)"
- "--v={{ .Values.logLevel }}"
- "--v={{ .Values.sidecarLogLevel }}"
- "--timeout={{ .Values.provisioner.timeout }}"
- "--leader-election=true"
- "--extra-create-metadata=true"
env:
- name: ADDRESS
value: "unix:///csi/{{ .Values.provisionerSocketFile }}"
@ -94,7 +95,7 @@ spec:
image: "{{ .Values.provisioner.resizer.image.repository }}:{{ .Values.provisioner.resizer.image.tag }}"
imagePullPolicy: {{ .Values.provisioner.resizer.image.pullPolicy }}
args:
- "--v={{ .Values.logLevel }}"
- "--v={{ .Values.sidecarLogLevel }}"
- "--csi-address=$(ADDRESS)"
- "--timeout={{ .Values.provisioner.timeout }}"
- "--leader-election"
@ -124,6 +125,10 @@ spec:
{{- if .Values.provisioner.profiling.enabled }}
- "--enableprofiling={{ .Values.provisioner.profiling.enabled }}"
{{- end }}
{{- if .Values.provisioner.clustername }}
- "--clustername={{ .Values.provisioner.clustername }}"
{{- end }}
- "--setmetadata={{ .Values.provisioner.setmetadata }}"
env:
- name: POD_IP
valueFrom:

View File

@ -33,7 +33,10 @@ csiConfig: []
# Set logging level for csi containers.
# Supported values from 0 to 5. 0 for general useful logs,
# 5 for trace level verbosity.
# logLevel is the variable for CSI driver containers's log level
logLevel: 5
# sidecarLogLevel is the variable for Kubernetes sidecar container's log level
sidecarLogLevel: 1
nodeplugin:
name: nodeplugin
@ -125,6 +128,8 @@ provisioner:
maxUnavailable: 50%
# Timeout for waiting for creation or deletion of a volume
timeout: 60s
# cluster name to set on the subvolume
# clustername: "k8s-cluster-1"
# set user created priorityclassName for csi provisioner pods. default is
# system-cluster-critical which is less priority than system-node-critical
@ -175,6 +180,9 @@ provisioner:
pullPolicy: IfNotPresent
resources: {}
# set metadata on volume
setmetadata: true
resizer:
name: resizer
enabled: true

View File

@ -88,6 +88,7 @@ charts and their default values.
| `csiMapping` | Configuration details of clusterID,PoolID,FscID mapping | [] |
| `encryptionKMSConfig` | Configuration for the encryption KMS | `{}` |
| `logLevel` | Set logging level for csi containers. Supported values from 0 to 5. 0 for general useful logs, 5 for trace level verbosity. | `5` |
| `sidecarLogLevel` | Set logging level for csi sidecar containers. Supported values from 0 to 5. 0 for general useful logs, 5 for trace level verbosity. | `1` |
| `nodeplugin.name` | Specifies the nodeplugins name | `nodeplugin` |
| `nodeplugin.updateStrategy` | Specifies the update Strategy. If you are using ceph-fuse client set this value to OnDelete | `RollingUpdate` |
| `nodeplugin.priorityClassName` | Set user created priorityclassName for csi plugin pods. default is system-node-critical which is highest priority | `system-node-critical` |

View File

@ -58,7 +58,7 @@ spec:
imagePullPolicy: {{ .Values.provisioner.provisioner.image.pullPolicy }}
args:
- "--csi-address=$(ADDRESS)"
- "--v={{ .Values.logLevel }}"
- "--v={{ .Values.sidecarLogLevel }}"
- "--timeout={{ .Values.provisioner.timeout }}"
- "--leader-election=true"
- "--retry-interval-start=500ms"
@ -82,7 +82,7 @@ spec:
image: "{{ .Values.provisioner.resizer.image.repository }}:{{ .Values.provisioner.resizer.image.tag }}"
imagePullPolicy: {{ .Values.provisioner.resizer.image.pullPolicy }}
args:
- "--v={{ .Values.logLevel }}"
- "--v={{ .Values.sidecarLogLevel }}"
- "--csi-address=$(ADDRESS)"
- "--timeout={{ .Values.provisioner.timeout }}"
- "--leader-election"
@ -103,7 +103,7 @@ spec:
imagePullPolicy: {{ .Values.provisioner.snapshotter.image.pullPolicy }}
args:
- "--csi-address=$(ADDRESS)"
- "--v={{ .Values.logLevel }}"
- "--v={{ .Values.sidecarLogLevel }}"
- "--timeout={{ .Values.provisioner.timeout }}"
- "--leader-election=true"
- "--extra-create-metadata=true"
@ -120,7 +120,7 @@ spec:
image: "{{ .Values.provisioner.attacher.image.repository }}:{{ .Values.provisioner.attacher.image.tag }}"
imagePullPolicy: {{ .Values.provisioner.attacher.image.pullPolicy }}
args:
- "--v={{ .Values.logLevel }}"
- "--v={{ .Values.sidecarLogLevel }}"
- "--csi-address=$(ADDRESS)"
- "--leader-election=true"
- "--retry-interval-start=500ms"

View File

@ -56,7 +56,10 @@ encryptionKMSConfig: {}
# Set logging level for csi containers.
# Supported values from 0 to 5. 0 for general useful logs,
# 5 for trace level verbosity.
# logLevel is the variable for CSI driver containers's log level
logLevel: 5
# sidecarLogLevel is the variable for Kubernetes sidecar container's log level
sidecarLogLevel: 1
nodeplugin:
name: nodeplugin

View File

@ -46,7 +46,7 @@ spec:
image: registry.k8s.io/sig-storage/csi-provisioner:v3.2.1
args:
- "--csi-address=$(ADDRESS)"
- "--v=5"
- "--v=1"
- "--timeout=150s"
- "--leader-election=true"
- "--retry-interval-start=500ms"
@ -65,7 +65,7 @@ spec:
image: registry.k8s.io/sig-storage/csi-resizer:v1.5.0
args:
- "--csi-address=$(ADDRESS)"
- "--v=5"
- "--v=1"
- "--timeout=150s"
- "--leader-election"
- "--retry-interval-start=500ms"
@ -82,9 +82,10 @@ spec:
image: registry.k8s.io/sig-storage/csi-snapshotter:v6.0.1
args:
- "--csi-address=$(ADDRESS)"
- "--v=5"
- "--v=1"
- "--timeout=150s"
- "--leader-election=true"
- "--extra-create-metadata=true"
env:
- name: ADDRESS
value: unix:///csi/csi-provisioner.sock
@ -104,6 +105,7 @@ spec:
- "--drivername=cephfs.csi.ceph.com"
- "--pidlimit=-1"
- "--enableprofiling=false"
- "--setmetadata=true"
env:
- name: POD_IP
valueFrom:

View File

@ -29,7 +29,7 @@ spec:
allowPrivilegeEscalation: true
image: registry.k8s.io/sig-storage/csi-node-driver-registrar:v2.5.1
args:
- "--v=5"
- "--v=1"
- "--csi-address=/csi/csi.sock"
- "--kubelet-registration-path=/var/lib/kubelet/plugins/cephfs.csi.ceph.com/csi.sock"
env:

View File

@ -43,13 +43,11 @@ spec:
image: registry.k8s.io/sig-storage/csi-provisioner:v3.2.1
args:
- "--csi-address=$(ADDRESS)"
- "--v=5"
- "--v=1"
- "--timeout=150s"
- "--leader-election=true"
- "--retry-interval-start=500ms"
# TODO: enable the feature-gate once error has been handled in nfs.
# Issue #3230
# - "--feature-gates=HonorPVReclaimPolicy=true"
- "--feature-gates=HonorPVReclaimPolicy=true"
- "--prevent-volume-mode-conversion=true"
env:
- name: ADDRESS
@ -62,7 +60,7 @@ spec:
image: registry.k8s.io/sig-storage/csi-resizer:v1.5.0
args:
- "--csi-address=$(ADDRESS)"
- "--v=5"
- "--v=1"
- "--timeout=150s"
- "--leader-election"
- "--retry-interval-start=500ms"
@ -78,7 +76,7 @@ spec:
image: registry.k8s.io/sig-storage/csi-snapshotter:v6.0.1
args:
- "--csi-address=$(ADDRESS)"
- "--v=5"
- "--v=1"
- "--timeout=150s"
- "--leader-election=true"
env:

View File

@ -33,7 +33,7 @@ spec:
- mountPath: /csi
name: socket-dir
- args:
- --v=5
- --v=1
- --csi-address=/csi/csi.sock
- --kubelet-registration-path=$(DRIVER_REG_SOCK_PATH)
env:
@ -74,7 +74,7 @@ spec:
- mountPath: /registration
name: registration-dir
- args:
- -v=5
- -v=1
- --drivername=nfs.csi.ceph.com
- --nodeid=$(NODE_ID)
- --endpoint=$(CSI_ENDPOINT)

View File

@ -20,7 +20,7 @@ rules:
verbs: ["list", "watch", "create", "update", "patch"]
- apiGroups: [""]
resources: ["persistentvolumes"]
verbs: ["get", "list", "watch", "create", "delete", "patch"]
verbs: ["get", "list", "watch", "create", "update", "delete", "patch"]
- apiGroups: [""]
resources: ["persistentvolumeclaims"]
verbs: ["get", "list", "watch", "update"]

View File

@ -50,7 +50,7 @@ spec:
image: k8s.gcr.io/sig-storage/csi-provisioner:v3.2.1
args:
- "--csi-address=$(ADDRESS)"
- "--v=5"
- "--v=1"
- "--timeout=150s"
- "--retry-interval-start=500ms"
- "--leader-election=true"
@ -72,7 +72,7 @@ spec:
image: registry.k8s.io/sig-storage/csi-snapshotter:v6.0.1
args:
- "--csi-address=$(ADDRESS)"
- "--v=5"
- "--v=1"
- "--timeout=150s"
- "--leader-election=true"
- "--extra-create-metadata=true"
@ -86,7 +86,7 @@ spec:
- name: csi-attacher
image: registry.k8s.io/sig-storage/csi-attacher:v3.5.0
args:
- "--v=5"
- "--v=1"
- "--csi-address=$(ADDRESS)"
- "--leader-election=true"
- "--retry-interval-start=500ms"
@ -101,7 +101,7 @@ spec:
image: registry.k8s.io/sig-storage/csi-resizer:v1.5.0
args:
- "--csi-address=$(ADDRESS)"
- "--v=5"
- "--v=1"
- "--timeout=150s"
- "--leader-election"
- "--retry-interval-start=500ms"

View File

@ -31,7 +31,7 @@ spec:
allowPrivilegeEscalation: true
image: registry.k8s.io/sig-storage/csi-node-driver-registrar:v2.5.1
args:
- "--v=5"
- "--v=1"
- "--csi-address=/csi/csi.sock"
- "--kubelet-registration-path=/var/lib/kubelet/plugins/rbd.csi.ceph.com/csi.sock"
env:

View File

@ -1,6 +1,7 @@
# Capabilities of a user required for ceph-csi in a Ceph cluster
Ceph uses the term capabilities to describe authorizing an authenticated user
Ceph uses the term _capabilities_ to describe authorizations for an
authenticated user
to exercise the functionality of the monitors, OSDs and metadata servers.
Capabilities can also restrict access to data within a pool or pool namespace.
A Ceph administrative user sets a user's capabilities when creating or
@ -10,9 +11,9 @@ Hence, those capabilities are documented below.
## RBD
We have provisioner, controller expand and node stage secrets in storage class.
For the provisioner and controller expand stage secret in storageclass, the
user needs to have the below mentioned ceph capabilities.
We have provisioner, controller expand and node stage secrets in storageclass.
For the provisioner and controller expand stage secrets in storageclass, the
user needs to have the below Ceph capabilities.
```
"mon", "profile rbd",
@ -50,7 +51,7 @@ the below mentioned ceph capabilities.
"mds", "allow rw"
```
To get more insights on capabilities of cephfs you can refer
To get more insights on capabilities of CephFS you can refer
[this document](https://ceph.readthedocs.io/en/latest/cephfs/client-auth/)
## Command to a create user with required capabilities

View File

@ -57,6 +57,7 @@ that should be resolved in v14.2.3.
| `--enablegrpcmetrics` | `false` | [Deprecated] Enable grpc metrics collection and start prometheus server |
| `--polltime` | `60s` | Time interval in between each poll |
| `--timeout` | `3s` | Probe timeout in seconds |
| `--clustername` | _empty_ | Cluster name to set on subvolume |
| `--histogramoption` | `0.5,2,6` | [Deprecated] Histogram option for grpc metrics, should be comma separated value (ex:= "0.5,2,6" where start=0.5 factor=2, count=6) |
| `--forcecephkernelclient` | `false` | Force enabling Ceph Kernel clients for mounting on kernels < 4.17 |
| `--kernelmountoptions` | _empty_ | Comma separated string of mount options accepted by cephfs kernel mounter |
@ -163,7 +164,7 @@ for more information.
**Deploy Ceph configuration ConfigMap for CSI pods:**
```bash
kubectl create -f ../example/ceph-config.yaml
kubectl create -f ../../../example/ceph-config.yaml
```
**Deploy CSI sidecar containers:**

View File

@ -194,6 +194,14 @@ var _ = Describe(cephfsType, func() {
if err != nil {
e2elog.Failf("failed to create node secret: %v", err)
}
// wait for cluster name update in deployment
containers := []string{cephFSContainerName}
err = waitForContainersArgsUpdate(c, cephCSINamespace, cephFSDeploymentName,
"clustername", defaultClusterName, containers, deployTimeout)
if err != nil {
e2elog.Failf("timeout waiting for deployment update %s/%s: %v", cephCSINamespace, cephFSDeploymentName, err)
}
})
AfterEach(func() {
@ -397,6 +405,66 @@ var _ = Describe(cephfsType, func() {
}
})
By("create a PVC and check PVC/PV metadata on CephFS subvolume", func() {
err := createCephfsStorageClass(f.ClientSet, f, true, nil)
if err != nil {
e2elog.Failf("failed to create CephFS storageclass: %v", err)
}
pvc, err := loadPVC(pvcPath)
if err != nil {
e2elog.Failf("failed to load PVC: %v", err)
}
pvc.Namespace = f.UniqueName
err = createPVCAndvalidatePV(f.ClientSet, pvc, deployTimeout)
if err != nil {
e2elog.Failf("failed to create PVC: %v", err)
}
validateSubvolumeCount(f, 1, fileSystemName, subvolumegroup)
validateOmapCount(f, 1, cephfsType, metadataPool, volumesType)
pvcObj, err := getPersistentVolumeClaim(c, pvc.Namespace, pvc.Name)
if err != nil {
e2elog.Logf("error getting pvc %q in namespace %q: %v", pvc.Name, pvc.Namespace, err)
}
if pvcObj.Spec.VolumeName == "" {
e2elog.Logf("pv name is empty %q in namespace %q: %v", pvc.Name, pvc.Namespace, err)
}
subvol, err := listCephFSSubVolumes(f, fileSystemName, subvolumegroup)
if err != nil {
e2elog.Failf("failed to list CephFS subvolumes: %v", err)
}
if len(subvol) == 0 {
e2elog.Failf("cephFS subvolumes list is empty %s", fileSystemName)
}
metadata, err := listCephFSSubvolumeMetadata(f, fileSystemName, subvol[0].Name, subvolumegroup)
if err != nil {
e2elog.Failf("failed to list subvolume metadata: %v", err)
}
if metadata.PVCNameKey != pvc.Name {
e2elog.Failf("expected pvcName %q got %q", pvc.Name, metadata.PVCNameKey)
} else if metadata.PVCNamespaceKey != pvc.Namespace {
e2elog.Failf("expected pvcNamespace %q got %q", pvc.Namespace, metadata.PVCNamespaceKey)
} else if metadata.PVNameKey != pvcObj.Spec.VolumeName {
e2elog.Failf("expected pvName %q got %q", pvcObj.Spec.VolumeName, metadata.PVNameKey)
} else if metadata.ClusterNameKey != defaultClusterName {
e2elog.Failf("expected clusterName %q got %q", defaultClusterName, metadata.ClusterNameKey)
}
err = deletePVCAndValidatePV(f.ClientSet, pvc, deployTimeout)
if err != nil {
e2elog.Failf("failed to delete PVC: %v", err)
}
validateSubvolumeCount(f, 0, fileSystemName, subvolumegroup)
validateOmapCount(f, 0, cephfsType, metadataPool, volumesType)
err = deleteResource(cephFSExamplePath + "storageclass.yaml")
if err != nil {
e2elog.Failf("failed to delete CephFS storageclass: %v", err)
}
})
By("create PVC in storageClass with volumeNamePrefix", func() {
volumeNamePrefix := "foo-bar-"
err := createCephfsStorageClass(
@ -848,6 +916,174 @@ var _ = Describe(cephfsType, func() {
}
})
By("Test subvolume snapshot and restored PVC metadata", func() {
err := createCephFSSnapshotClass(f)
if err != nil {
e2elog.Failf("failed to create CephFS snapshotclass: %v", err)
}
pvc, err := loadPVC(pvcPath)
if err != nil {
e2elog.Failf("failed to load PVC: %v", err)
}
pvc.Namespace = f.UniqueName
err = createPVCAndvalidatePV(f.ClientSet, pvc, deployTimeout)
if err != nil {
e2elog.Failf("failed to create PVC: %v", err)
}
snap := getSnapshot(snapshotPath)
snap.Namespace = f.UniqueName
snap.Spec.Source.PersistentVolumeClaimName = &pvc.Name
// create snapshot
snap.Name = f.UniqueName
err = createSnapshot(&snap, deployTimeout)
if err != nil {
e2elog.Failf("failed to create snapshot (%s): %v", snap.Name, err)
}
_, pv, err := getPVCAndPV(f.ClientSet, pvc.Name, pvc.Namespace)
if err != nil {
e2elog.Failf("failed to get PV object for %s: %v", pvc.Name, err)
}
subVolumeName := pv.Spec.CSI.VolumeAttributes["subvolumeName"]
snaps, err := listCephFSSnapshots(f, fileSystemName, subVolumeName, subvolumegroup)
if err != nil {
e2elog.Failf("failed to list subvolume snapshots: %v", err)
}
if len(snaps) == 0 {
e2elog.Failf("cephFS snapshots list is empty %s/%s", fileSystemName, subVolumeName)
}
content, err := getVolumeSnapshotContent(snap.Namespace, snap.Name)
if err != nil {
e2elog.Failf("failed to get snapshotcontent for %s in namespace %s: %v",
snap.Name, snap.Namespace, err)
}
metadata, err := listCephFSSnapshotMetadata(f,
fileSystemName, subVolumeName, snaps[0].Name, subvolumegroup)
if err != nil {
e2elog.Failf("failed to list subvolume snapshots metadata: %v", err)
}
if metadata.VolSnapNameKey != snap.Name {
e2elog.Failf("failed, snapname expected:%s got:%s",
snap.Name, metadata.VolSnapNameKey)
} else if metadata.VolSnapNamespaceKey != snap.Namespace {
e2elog.Failf("failed, snapnamespace expected:%s got:%s",
snap.Namespace, metadata.VolSnapNamespaceKey)
} else if metadata.VolSnapContentNameKey != content.Name {
e2elog.Failf("failed, contentname expected:%s got:%s",
content.Name, metadata.VolSnapContentNameKey)
} else if metadata.ClusterNameKey != defaultClusterName {
e2elog.Failf("expected clusterName %q got %q", defaultClusterName, metadata.ClusterNameKey)
}
// Delete the parent pvc before restoring
// another one from snapshot.
err = deletePVCAndValidatePV(f.ClientSet, pvc, deployTimeout)
if err != nil {
e2elog.Failf("failed to delete PVC: %v", err)
}
// Test Restore snapshot
pvcClone, err := loadPVC(pvcClonePath)
if err != nil {
e2elog.Failf("failed to load PVC: %v", err)
}
pvcClone.Namespace = f.UniqueName
pvcClone.Spec.DataSource.Name = snap.Name
// create PVC from the snapshot
err = createPVCAndvalidatePV(f.ClientSet, pvcClone, deployTimeout)
if err != nil {
e2elog.Failf("failed to create pvc clone: %v", err)
}
pvcCloneObj, pvCloneObj, err := getPVCAndPV(f.ClientSet, pvcClone.Name, pvcClone.Namespace)
if err != nil {
e2elog.Logf("error getting pvc %q in namespace %q: %v", pvcClone.Name, pvcClone.Namespace, err)
}
subVolumeCloneName := pvCloneObj.Spec.CSI.VolumeAttributes["subvolumeName"]
cloneMetadata, err := listCephFSSubvolumeMetadata(f, fileSystemName, subVolumeCloneName, subvolumegroup)
if err != nil {
e2elog.Failf("failed to list subvolume clone metadata: %v", err)
}
if cloneMetadata.PVCNameKey != pvcClone.Name {
e2elog.Failf("expected pvcName %q got %q", pvcClone.Name, cloneMetadata.PVCNameKey)
} else if cloneMetadata.PVCNamespaceKey != pvcClone.Namespace {
e2elog.Failf("expected pvcNamespace %q got %q", pvcClone.Namespace, cloneMetadata.PVCNamespaceKey)
} else if cloneMetadata.PVNameKey != pvcCloneObj.Spec.VolumeName {
e2elog.Failf("expected pvName %q got %q", pvcCloneObj.Spec.VolumeName, cloneMetadata.PVNameKey)
} else if cloneMetadata.ClusterNameKey != defaultClusterName {
e2elog.Failf("expected clusterName %q got %q", defaultClusterName, cloneMetadata.ClusterNameKey)
}
// delete clone
err = deletePVCAndValidatePV(f.ClientSet, pvcClone, deployTimeout)
if err != nil {
e2elog.Failf("failed to delete pvc clone: %v", err)
}
// delete snapshot
err = deleteSnapshot(&snap, deployTimeout)
if err != nil {
e2elog.Failf("failed to delete snapshot (%s): %v", f.UniqueName, err)
}
validateSubvolumeCount(f, 0, fileSystemName, subvolumegroup)
validateOmapCount(f, 0, cephfsType, metadataPool, volumesType)
err = deleteResource(cephFSExamplePath + "snapshotclass.yaml")
if err != nil {
e2elog.Failf("failed to delete CephFS snapshotclass: %v", err)
}
})
By("Test Clone metadata", func() {
pvc, err := loadPVC(pvcPath)
if err != nil {
e2elog.Failf("failed to load PVC: %v", err)
}
pvc.Namespace = f.UniqueName
err = createPVCAndvalidatePV(f.ClientSet, pvc, deployTimeout)
if err != nil {
e2elog.Failf("failed to create pvc: %v", err)
}
pvcClone, err := loadPVC(pvcSmartClonePath)
if err != nil {
e2elog.Failf("failed to load PVC: %v", err)
}
pvcClone.Namespace = f.UniqueName
pvcClone.Spec.DataSource.Name = pvc.Name
err = createPVCAndvalidatePV(f.ClientSet, pvcClone, deployTimeout)
if err != nil {
e2elog.Failf("failed to create pvc clone: %v", err)
}
// delete parent PVC
err = deletePVCAndValidatePV(f.ClientSet, pvc, deployTimeout)
if err != nil {
e2elog.Failf("failed to delete pvc: %v", err)
}
pvcCloneObj, pvCloneObj, err := getPVCAndPV(f.ClientSet, pvcClone.Name, pvcClone.Namespace)
if err != nil {
e2elog.Logf("error getting pvc %q in namespace %q: %v", pvcClone.Name, pvcClone.Namespace, err)
}
subVolumeCloneName := pvCloneObj.Spec.CSI.VolumeAttributes["subvolumeName"]
cloneMetadata, err := listCephFSSubvolumeMetadata(f, fileSystemName, subVolumeCloneName, subvolumegroup)
if err != nil {
e2elog.Failf("failed to list subvolume clone metadata: %v", err)
}
if cloneMetadata.PVCNameKey != pvcClone.Name {
e2elog.Failf("expected pvcName %q got %q", pvc.Name, cloneMetadata.PVCNameKey)
} else if cloneMetadata.PVCNamespaceKey != pvcClone.Namespace {
e2elog.Failf("expected pvcNamespace %q got %q", pvc.Namespace, cloneMetadata.PVCNamespaceKey)
} else if cloneMetadata.PVNameKey != pvcCloneObj.Spec.VolumeName {
e2elog.Failf("expected pvName %q got %q", pvcCloneObj.Spec.VolumeName, cloneMetadata.PVNameKey)
} else if cloneMetadata.ClusterNameKey != defaultClusterName {
e2elog.Failf("expected clusterName %q got %q", defaultClusterName, cloneMetadata.ClusterNameKey)
}
err = deletePVCAndValidatePV(f.ClientSet, pvcClone, deployTimeout)
if err != nil {
e2elog.Failf("failed to delete pvc clone: %v", err)
}
validateSubvolumeCount(f, 0, fileSystemName, subvolumegroup)
validateOmapCount(f, 0, cephfsType, metadataPool, volumesType)
})
By("Delete snapshot after deleting subvolume and snapshot from backend", func() {
err := createCephFSSnapshotClass(f)
if err != nil {

View File

@ -201,7 +201,7 @@ func listCephFSSubVolumes(f *framework.Framework, filesystem, groupname string)
return subVols, err
}
if stdErr != "" {
return subVols, fmt.Errorf("error listing subolumes %v", stdErr)
return subVols, fmt.Errorf("error listing subvolumes %v", stdErr)
}
err = json.Unmarshal([]byte(stdout), &subVols)
@ -212,6 +212,99 @@ func listCephFSSubVolumes(f *framework.Framework, filesystem, groupname string)
return subVols, nil
}
type cephfsSubvolumeMetadata struct {
PVCNameKey string `json:"csi.storage.k8s.io/pvc/name"`
PVCNamespaceKey string `json:"csi.storage.k8s.io/pvc/namespace"`
PVNameKey string `json:"csi.storage.k8s.io/pv/name"`
ClusterNameKey string `json:"csi.ceph.com/cluster/name"`
}
func listCephFSSubvolumeMetadata(
f *framework.Framework,
filesystem,
subvolume,
groupname string,
) (*cephfsSubvolumeMetadata, error) {
stdout, stdErr, err := execCommandInToolBoxPod(
f,
fmt.Sprintf("ceph fs subvolume metadata ls %s %s --group_name=%s --format=json", filesystem, subvolume, groupname),
rookNamespace)
if err != nil {
return nil, err
}
if stdErr != "" {
return nil, fmt.Errorf("error listing subvolume metadata %v", stdErr)
}
metadata := &cephfsSubvolumeMetadata{}
err = json.Unmarshal([]byte(stdout), metadata)
if err != nil {
return metadata, err
}
return metadata, nil
}
type cephfsSnapshotMetadata struct {
VolSnapNameKey string `json:"csi.storage.k8s.io/volumesnapshot/name"`
VolSnapNamespaceKey string `json:"csi.storage.k8s.io/volumesnapshot/namespace"`
VolSnapContentNameKey string `json:"csi.storage.k8s.io/volumesnapshotcontent/name"`
ClusterNameKey string `json:"csi.ceph.com/cluster/name"`
}
func listCephFSSnapshotMetadata(
f *framework.Framework,
filesystem,
subvolume,
snapname,
groupname string,
) (*cephfsSnapshotMetadata, error) {
stdout, stdErr, err := execCommandInToolBoxPod(
f,
fmt.Sprintf("ceph fs subvolume snapshot metadata ls %s %s %s --group_name=%s --format=json",
filesystem, subvolume, snapname, groupname),
rookNamespace)
if err != nil {
return nil, err
}
if stdErr != "" {
return nil, fmt.Errorf("error listing subvolume snapshots metadata %v", stdErr)
}
metadata := &cephfsSnapshotMetadata{}
err = json.Unmarshal([]byte(stdout), metadata)
if err != nil {
return metadata, err
}
return metadata, nil
}
type cephfsSnapshot struct {
Name string `json:"name"`
}
func listCephFSSnapshots(f *framework.Framework, filesystem, subvolume, groupname string) ([]cephfsSnapshot, error) {
var snaps []cephfsSnapshot
stdout, stdErr, err := execCommandInToolBoxPod(
f,
fmt.Sprintf("ceph fs subvolume snapshot ls %s %s --group_name=%s --format=json", filesystem, subvolume, groupname),
rookNamespace)
if err != nil {
return snaps, err
}
if stdErr != "" {
return snaps, fmt.Errorf("error listing subolume snapshots %v", stdErr)
}
err = json.Unmarshal([]byte(stdout), &snaps)
if err != nil {
return snaps, err
}
return snaps, nil
}
// getSubvolumepath validates whether subvolumegroup is present.
func getSubvolumePath(f *framework.Framework, filesystem, subvolgrp, subvolume string) (string, error) {
cmd := fmt.Sprintf("ceph fs subvolume getpath %s %s --group_name=%s", filesystem, subvolume, subvolgrp)

View File

@ -41,6 +41,11 @@ func isRetryableAPIError(err error) bool {
return true
}
// "unable to upgrade connection" happens occasionally when executing commands in Pods
if strings.Contains(err.Error(), "unable to upgrade connection") {
return true
}
// "transport is closing" is an internal gRPC err, we can not use ErrConnClosing
if strings.Contains(err.Error(), "transport is closing") {
return true

View File

@ -373,7 +373,7 @@ var _ = Describe("nfs", func() {
By("verify RWOP volume support", func() {
err := createNFSStorageClass(f.ClientSet, f, false, nil)
if err != nil {
e2elog.Failf("failed to create CephFS storageclass: %v", err)
e2elog.Failf("failed to create NFS storageclass: %v", err)
}
pvc, err := loadPVC(pvcRWOPPath)
if err != nil {
@ -411,40 +411,40 @@ var _ = Describe("nfs", func() {
validateSubvolumeCount(f, 0, fileSystemName, defaultSubvolumegroup)
err = deleteResource(nfsExamplePath + "storageclass.yaml")
if err != nil {
e2elog.Failf("failed to delete CephFS storageclass: %v", err)
e2elog.Failf("failed to delete NFS storageclass: %v", err)
}
})
By("create a storageclass with pool and a PVC then bind it to an app", func() {
err := createNFSStorageClass(f.ClientSet, f, false, nil)
if err != nil {
e2elog.Failf("failed to create CephFS storageclass: %v", err)
e2elog.Failf("failed to create NFS storageclass: %v", err)
}
err = validatePVCAndAppBinding(pvcPath, appPath, f)
if err != nil {
e2elog.Failf("failed to validate CephFS pvc and application binding: %v", err)
e2elog.Failf("failed to validate NFS pvc and application binding: %v", err)
}
err = deleteResource(nfsExamplePath + "storageclass.yaml")
if err != nil {
e2elog.Failf("failed to delete CephFS storageclass: %v", err)
e2elog.Failf("failed to delete NFS storageclass: %v", err)
}
})
By("create a PVC and bind it to an app", func() {
err := createNFSStorageClass(f.ClientSet, f, false, nil)
if err != nil {
e2elog.Failf("failed to create CephFS storageclass: %v", err)
e2elog.Failf("failed to create NFS storageclass: %v", err)
}
err = validatePVCAndAppBinding(pvcPath, appPath, f)
if err != nil {
e2elog.Failf("failed to validate CephFS pvc and application binding: %v", err)
e2elog.Failf("failed to validate NFS pvc and application binding: %v", err)
}
})
By("create a PVC and bind it to an app with normal user", func() {
err := validateNormalUserPVCAccess(pvcPath, f)
if err != nil {
e2elog.Failf("failed to validate normal user CephFS pvc and application binding: %v", err)
e2elog.Failf("failed to validate normal user NFS pvc and application binding: %v", err)
}
})

View File

@ -197,7 +197,7 @@ func execCommandInDaemonsetPod(
CaptureStderr: true,
}
_ /* stdout */, stderr, err := f.ExecWithOptions(podOpt)
_ /* stdout */, stderr, err := execWithRetry(f, &podOpt)
return stderr, err
}
@ -212,12 +212,35 @@ func listPods(f *framework.Framework, ns string, opt *metav1.ListOptions) ([]v1.
return podList.Items, err
}
func execWithRetry(f *framework.Framework, opts *framework.ExecOptions) (string, string, error) {
timeout := time.Duration(deployTimeout) * time.Minute
var stdOut, stdErr string
err := wait.PollImmediate(poll, timeout, func() (bool, error) {
var execErr error
stdOut, stdErr, execErr = f.ExecWithOptions(*opts)
if execErr != nil {
if isRetryableAPIError(execErr) {
return false, nil
}
e2elog.Logf("failed to execute command: %v", execErr)
return false, fmt.Errorf("failed to execute command: %w", execErr)
}
return true, nil
})
return stdOut, stdErr, err
}
func execCommandInPod(f *framework.Framework, c, ns string, opt *metav1.ListOptions) (string, string, error) {
podOpt, err := getCommandInPodOpts(f, c, ns, "", opt)
if err != nil {
return "", "", err
}
stdOut, stdErr, err := f.ExecWithOptions(podOpt)
stdOut, stdErr, err := execWithRetry(f, &podOpt)
if stdErr != "" {
e2elog.Logf("stdErr occurred: %v", stdErr)
}
@ -232,7 +255,8 @@ func execCommandInContainer(
if err != nil {
return "", "", err
}
stdOut, stdErr, err := f.ExecWithOptions(podOpt)
stdOut, stdErr, err := execWithRetry(f, &podOpt)
if stdErr != "" {
e2elog.Logf("stdErr occurred: %v", stdErr)
}
@ -255,7 +279,7 @@ func execCommandInContainerByPodName(
PreserveWhitespace: true,
}
stdOut, stdErr, err := f.ExecWithOptions(execOpts)
stdOut, stdErr, err := execWithRetry(f, &execOpts)
if stdErr != "" {
e2elog.Logf("stdErr occurred: %v", stdErr)
}
@ -271,7 +295,8 @@ func execCommandInToolBoxPod(f *framework.Framework, c, ns string) (string, stri
if err != nil {
return "", "", err
}
stdOut, stdErr, err := f.ExecWithOptions(podOpt)
stdOut, stdErr, err := execWithRetry(f, &podOpt)
if stdErr != "" {
e2elog.Logf("stdErr occurred: %v", stdErr)
}
@ -284,7 +309,8 @@ func execCommandInPodAndAllowFail(f *framework.Framework, c, ns string, opt *met
if err != nil {
return "", err.Error()
}
stdOut, stdErr, err := f.ExecWithOptions(podOpt)
stdOut, stdErr, err := execWithRetry(f, &podOpt)
if err != nil {
e2elog.Logf("command %s failed: %v", c, err)
}

77
go.mod
View File

@ -4,7 +4,7 @@ go 1.17
require (
github.com/IBM/keyprotect-go-client v0.8.0
github.com/aws/aws-sdk-go v1.44.28
github.com/aws/aws-sdk-go v1.44.62
github.com/aws/aws-sdk-go-v2/service/sts v1.16.9
github.com/ceph/ceph-csi/api v0.0.0-00010101000000-000000000000
// TODO: API for managing subvolume metadata and snapshot metadata requires `ceph_ci_untested` build-tag
@ -25,20 +25,20 @@ require (
github.com/prometheus/client_golang v1.12.2
github.com/stretchr/testify v1.8.0
golang.org/x/crypto v0.0.0-20220214200702-86341886e292
golang.org/x/sys v0.0.0-20220209214540-3681064d5158
golang.org/x/sys v0.0.0-20220319134239-a9b59b0215f8
google.golang.org/grpc v1.48.0
google.golang.org/protobuf v1.28.0
k8s.io/api v0.24.2
k8s.io/apimachinery v0.24.2
k8s.io/api v0.24.3
k8s.io/apimachinery v0.24.3
k8s.io/client-go v12.0.0+incompatible
k8s.io/cloud-provider v0.24.2
k8s.io/cloud-provider v0.24.3
k8s.io/klog/v2 v2.70.1
//
// when updating k8s.io/kubernetes, make sure to update the replace section too
//
k8s.io/kubernetes v1.24.2
k8s.io/mount-utils v0.24.2
k8s.io/utils v0.0.0-20220210201930-3a6ce19ff2f9
k8s.io/kubernetes v1.24.3
k8s.io/mount-utils v0.24.3
k8s.io/utils v0.0.0-20220728103510-ee6ede2d64ed
sigs.k8s.io/controller-runtime v0.11.0-beta.0.0.20211208212546-f236f0345ad2
)
@ -64,7 +64,7 @@ require (
github.com/felixge/httpsnoop v1.0.1 // indirect
github.com/fsnotify/fsnotify v1.5.1 // indirect
github.com/ghodss/yaml v1.0.1-0.20190212211648-25d852aebe32 // indirect
github.com/go-logr/logr v1.2.0 // indirect
github.com/go-logr/logr v1.2.3 // indirect
github.com/go-openapi/jsonpointer v0.19.5 // indirect
github.com/go-openapi/jsonreference v0.19.5 // indirect
github.com/go-openapi/swag v0.19.14 // indirect
@ -111,6 +111,7 @@ require (
github.com/mitchellh/mapstructure v1.5.0 // indirect
github.com/mitchellh/reflectwalk v1.0.1 // indirect
github.com/moby/spdystream v0.2.0 // indirect
github.com/moby/sys/mountinfo v0.6.0 // indirect
github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd // indirect
github.com/modern-go/reflect2 v1.0.2 // indirect
github.com/munnerz/goautoneg v0.0.0-20191010083416-a7dc8b61c822 // indirect
@ -152,10 +153,10 @@ require (
gopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7 // indirect
gopkg.in/yaml.v2 v2.4.0 // indirect
gopkg.in/yaml.v3 v3.0.1 // indirect
k8s.io/apiextensions-apiserver v0.23.0 // indirect
k8s.io/apiserver v0.24.2 // indirect
k8s.io/component-base v0.24.2 // indirect
k8s.io/component-helpers v0.24.2 // indirect
k8s.io/apiextensions-apiserver v0.24.3 // indirect
k8s.io/apiserver v0.24.3 // indirect
k8s.io/component-base v0.24.3 // indirect
k8s.io/component-helpers v0.24.3 // indirect
k8s.io/kube-openapi v0.0.0-20220328201542-3ee0da9b0b42 // indirect
k8s.io/kubectl v0.0.0 // indirect
k8s.io/kubelet v0.0.0 // indirect
@ -175,31 +176,31 @@ replace (
//
// k8s.io/kubernetes depends on these k8s.io packages, but unversioned
//
k8s.io/api => k8s.io/api v0.24.2
k8s.io/apiextensions-apiserver => k8s.io/apiextensions-apiserver v0.24.2
k8s.io/apimachinery => k8s.io/apimachinery v0.24.2
k8s.io/apiserver => k8s.io/apiserver v0.24.2
k8s.io/cli-runtime => k8s.io/cli-runtime v0.24.2
k8s.io/client-go => k8s.io/client-go v0.24.2
k8s.io/cloud-provider => k8s.io/cloud-provider v0.24.2
k8s.io/cluster-bootstrap => k8s.io/cluster-bootstrap v0.24.2
k8s.io/code-generator => k8s.io/code-generator v0.24.2
k8s.io/component-base => k8s.io/component-base v0.24.2
k8s.io/component-helpers => k8s.io/component-helpers v0.24.2
k8s.io/controller-manager => k8s.io/controller-manager v0.24.2
k8s.io/cri-api => k8s.io/cri-api v0.24.2
k8s.io/csi-translation-lib => k8s.io/csi-translation-lib v0.24.2
k8s.io/kube-aggregator => k8s.io/kube-aggregator v0.24.2
k8s.io/kube-controller-manager => k8s.io/kube-controller-manager v0.24.2
k8s.io/kube-proxy => k8s.io/kube-proxy v0.24.2
k8s.io/kube-scheduler => k8s.io/kube-scheduler v0.24.2
k8s.io/kubectl => k8s.io/kubectl v0.24.2
k8s.io/kubelet => k8s.io/kubelet v0.24.2
k8s.io/legacy-cloud-providers => k8s.io/legacy-cloud-providers v0.24.2
k8s.io/metrics => k8s.io/metrics v0.24.2
k8s.io/mount-utils => k8s.io/mount-utils v0.24.2
k8s.io/pod-security-admission => k8s.io/pod-security-admission v0.24.2
k8s.io/sample-apiserver => k8s.io/sample-apiserver v0.24.2
k8s.io/api => k8s.io/api v0.24.3
k8s.io/apiextensions-apiserver => k8s.io/apiextensions-apiserver v0.24.3
k8s.io/apimachinery => k8s.io/apimachinery v0.24.3
k8s.io/apiserver => k8s.io/apiserver v0.24.3
k8s.io/cli-runtime => k8s.io/cli-runtime v0.24.3
k8s.io/client-go => k8s.io/client-go v0.24.3
k8s.io/cloud-provider => k8s.io/cloud-provider v0.24.3
k8s.io/cluster-bootstrap => k8s.io/cluster-bootstrap v0.24.3
k8s.io/code-generator => k8s.io/code-generator v0.24.3
k8s.io/component-base => k8s.io/component-base v0.24.3
k8s.io/component-helpers => k8s.io/component-helpers v0.24.3
k8s.io/controller-manager => k8s.io/controller-manager v0.24.3
k8s.io/cri-api => k8s.io/cri-api v0.24.3
k8s.io/csi-translation-lib => k8s.io/csi-translation-lib v0.24.3
k8s.io/kube-aggregator => k8s.io/kube-aggregator v0.24.3
k8s.io/kube-controller-manager => k8s.io/kube-controller-manager v0.24.3
k8s.io/kube-proxy => k8s.io/kube-proxy v0.24.3
k8s.io/kube-scheduler => k8s.io/kube-scheduler v0.24.3
k8s.io/kubectl => k8s.io/kubectl v0.24.3
k8s.io/kubelet => k8s.io/kubelet v0.24.3
k8s.io/legacy-cloud-providers => k8s.io/legacy-cloud-providers v0.24.3
k8s.io/metrics => k8s.io/metrics v0.24.3
k8s.io/mount-utils => k8s.io/mount-utils v0.25.0-alpha.3.0.20220801203918-ff562e546084
k8s.io/pod-security-admission => k8s.io/pod-security-admission v0.24.3
k8s.io/sample-apiserver => k8s.io/sample-apiserver v0.24.3
// layeh.com seems to be misbehaving
layeh.com/radius => github.com/layeh/radius v0.0.0-20190322222518-890bc1058917
)

91
go.sum
View File

@ -141,8 +141,9 @@ github.com/aws/aws-sdk-go v1.25.37/go.mod h1:KmX6BPdI08NWTb3/sm4ZGu5ShLoqVDhKgpi
github.com/aws/aws-sdk-go v1.25.41/go.mod h1:KmX6BPdI08NWTb3/sm4ZGu5ShLoqVDhKgpiN924inxo=
github.com/aws/aws-sdk-go v1.35.24/go.mod h1:tlPOdRjfxPBpNIwqDj61rmsnA85v9jc0Ps9+muhnW+k=
github.com/aws/aws-sdk-go v1.38.49/go.mod h1:hcU610XS61/+aQV88ixoOzUoG7v3b31pl2zKMmprdro=
github.com/aws/aws-sdk-go v1.44.28 h1:h/OAqEqY18wq//v6h4GNPMmCkxuzSDrWuGyrvSiRqf4=
github.com/aws/aws-sdk-go v1.44.28/go.mod h1:y4AeaBuwd2Lk+GepC1E9v0qOiTws0MIWAX4oIKwKHZo=
github.com/aws/aws-sdk-go v1.44.62 h1:N8qOPnBhl2ZCIFiqyB640Xt5CeX9D8CEVhG/Vj7jGJU=
github.com/aws/aws-sdk-go v1.44.62/go.mod h1:y4AeaBuwd2Lk+GepC1E9v0qOiTws0MIWAX4oIKwKHZo=
github.com/aws/aws-sdk-go-v2 v1.16.7 h1:zfBwXus3u14OszRxGcqCDS4MfMCv10e8SMJ2r8Xm0Ns=
github.com/aws/aws-sdk-go-v2 v1.16.7/go.mod h1:6CpKuLXg2w7If3ABZCl/qZ6rEgwtjZTn4eAf4RcEyuw=
github.com/aws/aws-sdk-go-v2/internal/configsources v1.1.14 h1:2C0pYHcUBmdzPj+EKNC4qj97oK6yjrUhc1KoSodglvk=
@ -372,8 +373,9 @@ github.com/go-logfmt/logfmt v0.5.0/go.mod h1:wCYkCAKZfumFQihp8CzCvQ3paCTfi41vtzG
github.com/go-logr/logr v0.1.0/go.mod h1:ixOQHD9gLJUVQQ2ZOR7zLEifBX6tGkNJF4QyIY7sIas=
github.com/go-logr/logr v0.2.0/go.mod h1:z6/tIYblkpsD+a4lm/fGIIU9mZ+XfAiaFtq7xTgseGU=
github.com/go-logr/logr v0.4.0/go.mod h1:z6/tIYblkpsD+a4lm/fGIIU9mZ+XfAiaFtq7xTgseGU=
github.com/go-logr/logr v1.2.0 h1:QK40JKJyMdUDz+h+xvCsru/bJhvG0UxvePV0ufL/AcE=
github.com/go-logr/logr v1.2.0/go.mod h1:jdQByPbusPIv2/zmleS9BjJVeZ6kBagPoEUsqbVz/1A=
github.com/go-logr/logr v1.2.3 h1:2DntVwHkVopvECVRSlL5PSo9eG+cAkDCuckLubN+rq0=
github.com/go-logr/logr v1.2.3/go.mod h1:jdQByPbusPIv2/zmleS9BjJVeZ6kBagPoEUsqbVz/1A=
github.com/go-logr/zapr v0.1.0/go.mod h1:tabnROwaDl0UNxkVeFRbY8bwB37GwRv0P8lg6aAiEnk=
github.com/go-logr/zapr v1.2.0 h1:n4JnPI1T3Qq1SFEi/F8rwLrZERp2bso19PJZDB9dayk=
github.com/go-logr/zapr v1.2.0/go.mod h1:Qa4Bsj2Vb+FAVeAKsLD8RLQ+YRJB8YDmOAKxaBQf7Ro=
@ -839,6 +841,7 @@ github.com/moby/ipvs v1.0.1/go.mod h1:2pngiyseZbIKXNv7hsKj3O9UEz30c53MT9005gt2hx
github.com/moby/spdystream v0.2.0 h1:cjW1zVyyoiM0T7b6UoySUFqzXMoqRckQtXwGPiBhOM8=
github.com/moby/spdystream v0.2.0/go.mod h1:f7i0iNDQJ059oMTcWxx8MA/zKFIuD/lY+0GqbN2Wy8c=
github.com/moby/sys/mountinfo v0.5.0/go.mod h1:3bMD3Rg+zkqx8MRYPi7Pyb0Ie97QEBmdxbhnCLlSvSU=
github.com/moby/sys/mountinfo v0.6.0 h1:gUDhXQx58YNrpHlK4nSL+7y2pxFZkUcXqzFDKWdC0Oo=
github.com/moby/sys/mountinfo v0.6.0/go.mod h1:3bMD3Rg+zkqx8MRYPi7Pyb0Ie97QEBmdxbhnCLlSvSU=
github.com/moby/term v0.0.0-20210619224110-3f7ff695adc6/go.mod h1:E2VnQOmVuvZB6UYnnDB0qG5Nq/1tD9acaOpo6xmt0Kw=
github.com/modern-go/concurrent v0.0.0-20180228061459-e0a39a4cb421/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q=
@ -1443,8 +1446,9 @@ golang.org/x/sys v0.0.0-20211029165221-6e7872819dc8/go.mod h1:oPkhp1MJrh7nUepCBc
golang.org/x/sys v0.0.0-20211116061358-0a5406a5449c/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.0.0-20211216021012-1d35b9e2eb4e/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.0.0-20220114195835-da31bd327af9/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.0.0-20220209214540-3681064d5158 h1:rm+CHSpPEEW2IsXUib1ThaHIjuBVZjxNgSKmBLFfD4c=
golang.org/x/sys v0.0.0-20220209214540-3681064d5158/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.0.0-20220319134239-a9b59b0215f8 h1:OH54vjqzRWmbJ62fjuhxy7AxFFgoHN0/DPc/UrL8cAs=
golang.org/x/sys v0.0.0-20220319134239-a9b59b0215f8/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/term v0.0.0-20201117132131-f5c789dd3221/go.mod h1:Nr5EML6q2oocZ2LXRh80K7BxOlk5/8JxuGnuhpl+muw=
golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo=
golang.org/x/term v0.0.0-20210615171337-6886f2dfbf5b/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8=
@ -1748,28 +1752,28 @@ honnef.co/go/tools v0.0.0-20190523083050-ea95bdfd59fc/go.mod h1:rf3lG4BRIbNafJWh
honnef.co/go/tools v0.0.1-2019.2.3/go.mod h1:a3bituU0lyd329TUQxRnasdCoJDkEUEAqEt0JzvZhAg=
honnef.co/go/tools v0.0.1-2020.1.3/go.mod h1:X/FiERA/W4tHapMX5mGpAtMSVEeEUOyHaw9vFzvIQ3k=
honnef.co/go/tools v0.0.1-2020.1.4/go.mod h1:X/FiERA/W4tHapMX5mGpAtMSVEeEUOyHaw9vFzvIQ3k=
k8s.io/api v0.24.2 h1:g518dPU/L7VRLxWfcadQn2OnsiGWVOadTLpdnqgY2OI=
k8s.io/api v0.24.2/go.mod h1:AHqbSkTm6YrQ0ObxjO3Pmp/ubFF/KuM7jU+3khoBsOg=
k8s.io/apiextensions-apiserver v0.24.2 h1:/4NEQHKlEz1MlaK/wHT5KMKC9UKYz6NZz6JE6ov4G6k=
k8s.io/apiextensions-apiserver v0.24.2/go.mod h1:e5t2GMFVngUEHUd0wuCJzw8YDwZoqZfJiGOW6mm2hLQ=
k8s.io/apimachinery v0.24.2 h1:5QlH9SL2C8KMcrNJPor+LbXVTaZRReml7svPEh4OKDM=
k8s.io/apimachinery v0.24.2/go.mod h1:82Bi4sCzVBdpYjyI4jY6aHX+YCUchUIrZrXKedjd2UM=
k8s.io/apiserver v0.24.2 h1:orxipm5elPJSkkFNlwH9ClqaKEDJJA3yR2cAAlCnyj4=
k8s.io/apiserver v0.24.2/go.mod h1:pSuKzr3zV+L+MWqsEo0kHHYwCo77AT5qXbFXP2jbvFI=
k8s.io/cli-runtime v0.24.2/go.mod h1:1LIhKL2RblkhfG4v5lZEt7FtgFG5mVb8wqv5lE9m5qY=
k8s.io/client-go v0.24.2 h1:CoXFSf8if+bLEbinDqN9ePIDGzcLtqhfd6jpfnwGOFA=
k8s.io/client-go v0.24.2/go.mod h1:zg4Xaoo+umDsfCWr4fCnmLEtQXyCNXCvJuSsglNcV30=
k8s.io/cloud-provider v0.24.2 h1:DYNf90zS/GAQbEHsTfJsH4Oas7vim4U+WU9GftMQlfs=
k8s.io/cloud-provider v0.24.2/go.mod h1:a7jyWjizk+IKbcIf8+mX2cj3NvpRv9ZyGdXDyb8UEkI=
k8s.io/cluster-bootstrap v0.24.2/go.mod h1:eIHV338K03vBm3u/ROZiNXxWJ4AJRoTR9PEUhcTvYkg=
k8s.io/code-generator v0.24.2/go.mod h1:dpVhs00hTuTdTY6jvVxvTFCk6gSMrtfRydbhZwHI15w=
k8s.io/component-base v0.24.2 h1:kwpQdoSfbcH+8MPN4tALtajLDfSfYxBDYlXobNWI6OU=
k8s.io/component-base v0.24.2/go.mod h1:ucHwW76dajvQ9B7+zecZAP3BVqvrHoOxm8olHEg0nmM=
k8s.io/component-helpers v0.24.2 h1:gtXmI/TjVINtkAdZn7m5p8+Vd0Mk4d1q8kwJMMLBdwY=
k8s.io/component-helpers v0.24.2/go.mod h1:TRQPBQKfmqkmV6c0HAmUs8cXVNYYYLsXy4zu8eODi9g=
k8s.io/controller-manager v0.24.2/go.mod h1:hpwCof4KxP4vrw/M5QiVxU6Zmmggmr1keGXtjGHF+vc=
k8s.io/cri-api v0.24.2/go.mod h1:t3tImFtGeStN+ES69bQUX9sFg67ek38BM9YIJhMmuig=
k8s.io/csi-translation-lib v0.24.2/go.mod h1:pdHc2CYLViQYYsOqOp79hjKYi8J4NZ7vpiVzn1SqBrg=
k8s.io/api v0.24.3 h1:tt55QEmKd6L2k5DP6G/ZzdMQKvG5ro4H4teClqm0sTY=
k8s.io/api v0.24.3/go.mod h1:elGR/XSZrS7z7cSZPzVWaycpJuGIw57j9b95/1PdJNI=
k8s.io/apiextensions-apiserver v0.24.3 h1:kyx+Tmro1qEsTUr07ZGQOfvTsF61yn+AxnxytBWq8As=
k8s.io/apiextensions-apiserver v0.24.3/go.mod h1:cL0xkmUefpYM4f6IuOau+6NMFEIh6/7wXe/O4vPVJ8A=
k8s.io/apimachinery v0.24.3 h1:hrFiNSA2cBZqllakVYyH/VyEh4B581bQRmqATJSeQTg=
k8s.io/apimachinery v0.24.3/go.mod h1:82Bi4sCzVBdpYjyI4jY6aHX+YCUchUIrZrXKedjd2UM=
k8s.io/apiserver v0.24.3 h1:J8CKjUaZopT0hSgxjzUyp3T1GK78iixxOuFpEC0MI3k=
k8s.io/apiserver v0.24.3/go.mod h1:aXfwtIn4U27B7lYs5f2BKgz6DRbgWy+HJeYReN1jLJ8=
k8s.io/cli-runtime v0.24.3/go.mod h1:In84wauoMOqa7JDvDSXGbf8lTNlr70fOGpYlYfJtSqA=
k8s.io/client-go v0.24.3 h1:Nl1840+6p4JqkFWEW2LnMKU667BUxw03REfLAVhuKQY=
k8s.io/client-go v0.24.3/go.mod h1:AAovolf5Z9bY1wIg2FZ8LPQlEdKHjLI7ZD4rw920BJw=
k8s.io/cloud-provider v0.24.3 h1:Z4O3AiuFxGRPn1ilzaeWS2uBnW8LsH5MbniCTf1xAgs=
k8s.io/cloud-provider v0.24.3/go.mod h1:CRIMwnR4e6FpGO5g81nofNuKGQcpJx8El2JEU+BsH9M=
k8s.io/cluster-bootstrap v0.24.3/go.mod h1:plud10KCFfNjsf2FNalENFGvJWVtcKa0KbKie5wQAvA=
k8s.io/code-generator v0.24.3/go.mod h1:dpVhs00hTuTdTY6jvVxvTFCk6gSMrtfRydbhZwHI15w=
k8s.io/component-base v0.24.3 h1:u99WjuHYCRJjS1xeLOx72DdRaghuDnuMgueiGMFy1ec=
k8s.io/component-base v0.24.3/go.mod h1:bqom2IWN9Lj+vwAkPNOv2TflsP1PeVDIwIN0lRthxYY=
k8s.io/component-helpers v0.24.3 h1:HKZTNf77K96StY2+FAgKvsXvHwoLvexeGDJatyuWlyI=
k8s.io/component-helpers v0.24.3/go.mod h1:/1WNW8TfBOijQ1ED2uCHb4wtXYWDVNMqUll8h36iNVo=
k8s.io/controller-manager v0.24.3/go.mod h1:qU/ZC8qmKxiVlRwLUfqXAzgsBi3q44E8Xn8qHs/MiVY=
k8s.io/cri-api v0.24.3/go.mod h1:t3tImFtGeStN+ES69bQUX9sFg67ek38BM9YIJhMmuig=
k8s.io/csi-translation-lib v0.24.3/go.mod h1:PfajTaauPYSL4hWKDRBVbUfO611Uv+h3w1YA9Twmzjk=
k8s.io/gengo v0.0.0-20200413195148-3a45101e95ac/go.mod h1:ezvh/TsK7cY6rbqRK0oQQ8IAqLxYwwyPxAX1Pzy0ii0=
k8s.io/gengo v0.0.0-20201214224949-b6c5ce23f027/go.mod h1:FiNAH4ZV3gBg2Kwh89tzAEV2be7d5xI0vBa/VySYy3E=
k8s.io/gengo v0.0.0-20210813121822-485abfe95c7c/go.mod h1:FiNAH4ZV3gBg2Kwh89tzAEV2be7d5xI0vBa/VySYy3E=
@ -1784,35 +1788,36 @@ k8s.io/klog/v2 v2.30.0/go.mod h1:y1WjHnz7Dj687irZUWR/WLkLc5N1YHtjLdmgWjndZn0=
k8s.io/klog/v2 v2.60.1/go.mod h1:y1WjHnz7Dj687irZUWR/WLkLc5N1YHtjLdmgWjndZn0=
k8s.io/klog/v2 v2.70.1 h1:7aaoSdahviPmR+XkS7FyxlkkXs6tHISSG03RxleQAVQ=
k8s.io/klog/v2 v2.70.1/go.mod h1:y1WjHnz7Dj687irZUWR/WLkLc5N1YHtjLdmgWjndZn0=
k8s.io/kube-aggregator v0.24.2/go.mod h1:Ju2jNDixn+vqeeKEBfjfpc204bO1pbdXX0N9knCxeMQ=
k8s.io/kube-controller-manager v0.24.2/go.mod h1:KDE0yqiEvxYiO0WRpPA4rVx8AcK1vsWydUF37AJ9lTI=
k8s.io/kube-aggregator v0.24.3/go.mod h1:oMjdwraZtb0CtIxrzrAt/4GJxbivAM8AesZhYVmXZ54=
k8s.io/kube-controller-manager v0.24.3/go.mod h1:c7YN1XesvesxKM5uO5JqmcecnUsitFos1sIyt0eOprE=
k8s.io/kube-openapi v0.0.0-20180731170545-e3762e86a74c/go.mod h1:BXM9ceUBTj2QnfH2MK1odQs778ajze1RxcmP6S8RVVc=
k8s.io/kube-openapi v0.0.0-20210421082810-95288971da7e/go.mod h1:vHXdDvt9+2spS2Rx9ql3I8tycm3H9FDfdUoIuKCefvw=
k8s.io/kube-openapi v0.0.0-20211115234752-e816edb12b65/go.mod h1:sX9MT8g7NVZM5lVL/j8QyCCJe8YSMW30QvGZWaCIDIk=
k8s.io/kube-openapi v0.0.0-20220328201542-3ee0da9b0b42 h1:Gii5eqf+GmIEwGNKQYQClCayuJCe2/4fZUvF7VG99sU=
k8s.io/kube-openapi v0.0.0-20220328201542-3ee0da9b0b42/go.mod h1:Z/45zLw8lUo4wdiUkI+v/ImEGAvu3WatcZl3lPMR4Rk=
k8s.io/kube-proxy v0.24.2/go.mod h1:bozS2ufl/Ns6s40Ue34eV7rqyLVygi5usSmCgW7rFU8=
k8s.io/kube-scheduler v0.24.2/go.mod h1:DRa+aeXKSYUUOHHIc/9EcaO9+FW5FydaOfPSvaSW5Ko=
k8s.io/kubectl v0.24.2 h1:+RfQVhth8akUmIc2Ge8krMl/pt66V7210ka3RE/p0J4=
k8s.io/kubectl v0.24.2/go.mod h1:+HIFJc0bA6Tzu5O/YcuUt45APAxnNL8LeMuXwoiGsPg=
k8s.io/kubelet v0.24.2 h1:VAvULig8RiylCtyxudgHV7nhKsLnNIrdVBCRD4bXQ3Y=
k8s.io/kubelet v0.24.2/go.mod h1:Xm9DkWQjwOs+uGOUIIGIPMvvmenvj0lDVOErvIKOOt0=
k8s.io/kubernetes v1.24.2 h1:AyjtHzSysliKR04Km91njmk2yaKmOa3ZISQZCIGUnVI=
k8s.io/kubernetes v1.24.2/go.mod h1:8e8maMiZzBR2/8Po5Uulx+MXZUYJuN3vtKwD4Ct1Xi0=
k8s.io/legacy-cloud-providers v0.24.2/go.mod h1:sgkasgIP2ZOew8fzoOq0mQLVXJ4AmB57IUbFUjzPWEo=
k8s.io/metrics v0.24.2/go.mod h1:5NWURxZ6Lz5gj8TFU83+vdWIVASx7W8lwPpHYCqopMo=
k8s.io/mount-utils v0.24.2 h1:UTHxyMz2LGBgapLcyl2y2hxWwJHotdmKLqV7CEf0fys=
k8s.io/mount-utils v0.24.2/go.mod h1:XrSqB3a2e8sq+aU+rlbcBtQ3EgcuDk5RP9ZsGxjoDrI=
k8s.io/pod-security-admission v0.24.2 h1:Wl92TCvxsqba+kDK59Dnf/qIsSoP1ekRlj5qT1XEmNk=
k8s.io/pod-security-admission v0.24.2/go.mod h1:znnuDHWWWvh/tpbYYPwTsd4y//qHi3cOX+wGxET/mMI=
k8s.io/sample-apiserver v0.24.2/go.mod h1:mf8qgDdu450wqpCJOkSAmoTgU4PIMAcfa5uTBwmJekE=
k8s.io/kube-proxy v0.24.3/go.mod h1:zJ+koqfBkRUAzUfXlBtFfyfH3InqM38t5ELGlTlPwO0=
k8s.io/kube-scheduler v0.24.3/go.mod h1:myFLGrPy8rcwPz6qg9L3rMRDT2eNIpizq+MXOzMjX/8=
k8s.io/kubectl v0.24.3 h1:PqY8ho/S/KuE2/hCC3Iee7X+lOtARYo0LQsNzvV/edE=
k8s.io/kubectl v0.24.3/go.mod h1:PYLcvw96sC1NLbxZEDbdlOEd6/C76VIWjGmWV5QjSk0=
k8s.io/kubelet v0.24.3 h1:6fqhHuUWkMpsGulIticCLUlDIhc30sypVVJjGVVKYzw=
k8s.io/kubelet v0.24.3/go.mod h1:vIdQ8bybBvLeMysTyj37QZNKNnCGVfWqpbsLaMT7wTE=
k8s.io/kubernetes v1.24.3 h1:RVuivOFTujzUDYZV8UFXCeD05US8DowBbxV+97JWEFg=
k8s.io/kubernetes v1.24.3/go.mod h1:8e8maMiZzBR2/8Po5Uulx+MXZUYJuN3vtKwD4Ct1Xi0=
k8s.io/legacy-cloud-providers v0.24.3/go.mod h1:G548jzl58czqsrebwY1XXFKEkCEcJhX8tnPUCFv/uMo=
k8s.io/metrics v0.24.3/go.mod h1:p1M0lhMySWfhISkSd3HEj8xIgrVnJTK3PPhFq2rA3To=
k8s.io/mount-utils v0.25.0-alpha.3.0.20220801203918-ff562e546084 h1:MBVsRiLUuVn8PX7je4jjBfHfRs65QwEtgM//Te1mFpQ=
k8s.io/mount-utils v0.25.0-alpha.3.0.20220801203918-ff562e546084/go.mod h1:dHX0bJ3b1Mvh/OHsBV9r559Mdrf5Lcjxyoc7FHUtnBg=
k8s.io/pod-security-admission v0.24.3 h1:Uy9jh3rp0T6WK68WSgnGhBoSLQUOB//G09TYTeJtAfo=
k8s.io/pod-security-admission v0.24.3/go.mod h1:l862a6t98GO7IIIGIe/lh01TTq9fWu6ylTb7CLDrXkY=
k8s.io/sample-apiserver v0.24.3/go.mod h1:ZDr71tBj39HgTEFPugVn5v32aZ5z7XCu2kLWoygiBp0=
k8s.io/system-validators v1.7.0/go.mod h1:gP1Ky+R9wtrSiFbrpEPwWMeYz9yqyy1S/KOh0Vci7WI=
k8s.io/utils v0.0.0-20190506122338-8fab8cb257d5/go.mod h1:sZAwmy6armz5eXlNoLmJcl4F1QuKu7sr+mFQ0byX7Ew=
k8s.io/utils v0.0.0-20210802155522-efc7438f0176/go.mod h1:jPW/WVKK9YHAvNhRxK0md/EJ228hCsBRufyofKtW8HA=
k8s.io/utils v0.0.0-20210930125809-cb0fa318a74b/go.mod h1:jPW/WVKK9YHAvNhRxK0md/EJ228hCsBRufyofKtW8HA=
k8s.io/utils v0.0.0-20211116205334-6203023598ed/go.mod h1:jPW/WVKK9YHAvNhRxK0md/EJ228hCsBRufyofKtW8HA=
k8s.io/utils v0.0.0-20220210201930-3a6ce19ff2f9 h1:HNSDgDCrr/6Ly3WEGKZftiE7IY19Vz2GdbOCyI4qqhc=
k8s.io/utils v0.0.0-20220210201930-3a6ce19ff2f9/go.mod h1:jPW/WVKK9YHAvNhRxK0md/EJ228hCsBRufyofKtW8HA=
k8s.io/utils v0.0.0-20220728103510-ee6ede2d64ed h1:jAne/RjBTyawwAy0utX5eqigAwz/lQhTmy+Hr/Cpue4=
k8s.io/utils v0.0.0-20220728103510-ee6ede2d64ed/go.mod h1:jPW/WVKK9YHAvNhRxK0md/EJ228hCsBRufyofKtW8HA=
modernc.org/cc v1.0.0/go.mod h1:1Sk4//wdnYJiUIxnW8ddKpaOJCF37yAdqYnkxUpaYxw=
modernc.org/golex v1.0.0/go.mod h1:b/QX9oBD/LhixY6NDh+IdGv17hgB+51fET1i2kPSmvk=
modernc.org/mathutil v1.0.0/go.mod h1:wU0vUrJsVWBZ4P6e7xtFJEhFSNsfRLJ8H458uRjg03k=

View File

@ -52,6 +52,12 @@ type ControllerServer struct {
// A map storing all volumes/snapshots with ongoing operations.
OperationLocks *util.OperationLock
// Cluster name
ClusterName string
// Set metadata on volume
SetMetadata bool
}
// createBackingVolume creates the backing subvolume and on any error cleans up any created entities.
@ -63,7 +69,8 @@ func (cs *ControllerServer) createBackingVolume(
sID *store.SnapshotIdentifier,
) error {
var err error
volClient := core.NewSubVolume(volOptions.GetConnection(), &volOptions.SubVolume, volOptions.ClusterID)
volClient := core.NewSubVolume(volOptions.GetConnection(),
&volOptions.SubVolume, volOptions.ClusterID, cs.ClusterName, cs.SetMetadata)
if sID != nil {
return cs.createBackingVolumeFromSnapshotSource(ctx, volOptions, parentVolOpt, volClient, sID)
@ -97,7 +104,7 @@ func (cs *ControllerServer) createBackingVolumeFromSnapshotSource(
defer cs.OperationLocks.ReleaseRestoreLock(sID.SnapshotID)
if volOptions.BackingSnapshot {
if err := store.AddSnapshotBackedVolumeRef(ctx, volOptions); err != nil {
if err := store.AddSnapshotBackedVolumeRef(ctx, volOptions, cs.ClusterName, cs.SetMetadata); err != nil {
log.ErrorLog(ctx, "failed to create snapshot-backed volume from snapshot %s: %v",
sID.FsSnapshotName, err)
@ -142,7 +149,7 @@ func (cs *ControllerServer) createBackingVolumeFromVolumeSource(
return nil
}
func checkContentSource(
func (cs *ControllerServer) checkContentSource(
ctx context.Context,
req *csi.CreateVolumeRequest,
cr *util.Credentials,
@ -154,7 +161,7 @@ func checkContentSource(
switch volumeSource.Type.(type) {
case *csi.VolumeContentSource_Snapshot:
snapshotID := req.VolumeContentSource.GetSnapshot().GetSnapshotId()
volOpt, _, sid, err := store.NewSnapshotOptionsFromID(ctx, snapshotID, cr)
volOpt, _, sid, err := store.NewSnapshotOptionsFromID(ctx, snapshotID, cr, cs.ClusterName, cs.SetMetadata)
if err != nil {
if errors.Is(err, cerrors.ErrSnapNotFound) {
return nil, nil, nil, status.Error(codes.NotFound, err.Error())
@ -167,7 +174,8 @@ func checkContentSource(
case *csi.VolumeContentSource_Volume:
// Find the volume using the provided VolumeID
volID := req.VolumeContentSource.GetVolume().GetVolumeId()
parentVol, pvID, err := store.NewVolumeOptionsFromVolID(ctx, volID, nil, req.Secrets)
parentVol, pvID, err := store.NewVolumeOptionsFromVolID(ctx,
volID, nil, req.Secrets, cs.ClusterName, cs.SetMetadata)
if err != nil {
if !errors.Is(err, cerrors.ErrVolumeNotFound) {
return nil, nil, nil, status.Error(codes.NotFound, err.Error())
@ -252,7 +260,7 @@ func (cs *ControllerServer) CreateVolume(
}
defer cs.VolumeLocks.Release(requestName)
volOptions, err := store.NewVolumeOptions(ctx, requestName, req, cr)
volOptions, err := store.NewVolumeOptions(ctx, requestName, cs.ClusterName, cs.SetMetadata, req, cr)
if err != nil {
log.ErrorLog(ctx, "validation and extraction of volume options failed: %v", err)
@ -264,7 +272,7 @@ func (cs *ControllerServer) CreateVolume(
volOptions.Size = util.RoundOffCephFSVolSize(req.GetCapacityRange().GetRequiredBytes())
}
parentVol, pvID, sID, err := checkContentSource(ctx, req, cr)
parentVol, pvID, sID, err := cs.checkContentSource(ctx, req, cr)
if err != nil {
return nil, err
}
@ -277,7 +285,7 @@ func (cs *ControllerServer) CreateVolume(
return nil, status.Error(codes.InvalidArgument, err.Error())
}
vID, err := store.CheckVolExists(ctx, volOptions, parentVol, pvID, sID, cr)
vID, err := store.CheckVolExists(ctx, volOptions, parentVol, pvID, sID, cr, cs.ClusterName, cs.SetMetadata)
if err != nil {
if cerrors.IsCloneRetryError(err) {
return nil, status.Error(codes.Aborted, err.Error())
@ -287,9 +295,11 @@ func (cs *ControllerServer) CreateVolume(
}
// TODO return error message if requested vol size greater than found volume return error
metadata := k8s.GetVolumeMetadata(req.GetParameters())
if vID != nil {
volClient := core.NewSubVolume(volOptions.GetConnection(), &volOptions.SubVolume,
volOptions.ClusterID, cs.ClusterName, cs.SetMetadata)
if sID != nil || pvID != nil && !volOptions.BackingSnapshot {
volClient := core.NewSubVolume(volOptions.GetConnection(), &volOptions.SubVolume, volOptions.ClusterID)
err = volClient.ExpandVolume(ctx, volOptions.Size)
if err != nil {
purgeErr := volClient.PurgeVolume(ctx, false)
@ -311,6 +321,14 @@ func (cs *ControllerServer) CreateVolume(
}
}
if !volOptions.BackingSnapshot {
// Set metadata on restart of provisioner pod when subvolume exist
err = volClient.SetAllMetadata(metadata)
if err != nil {
return nil, status.Error(codes.Internal, err.Error())
}
}
// remove kubernetes csi prefixed parameters.
volumeContext := k8s.RemoveCSIPrefixedParameters(req.GetParameters())
volumeContext["subvolumeName"] = vID.FsSubvolName
@ -360,12 +378,13 @@ func (cs *ControllerServer) CreateVolume(
return nil, err
}
volClient := core.NewSubVolume(volOptions.GetConnection(),
&volOptions.SubVolume, volOptions.ClusterID, cs.ClusterName, cs.SetMetadata)
if !volOptions.BackingSnapshot {
// Get root path for the created subvolume.
// Note that root path for snapshot-backed volumes has been already set when
// building VolumeOptions.
volClient := core.NewSubVolume(volOptions.GetConnection(), &volOptions.SubVolume, volOptions.ClusterID)
volOptions.RootPath, err = volClient.GetVolumeRootPathCeph(ctx)
if err != nil {
purgeErr := volClient.PurgeVolume(ctx, true)
@ -386,6 +405,12 @@ func (cs *ControllerServer) CreateVolume(
return nil, status.Error(codes.Internal, err.Error())
}
// Set Metadata on PV Create
err = volClient.SetAllMetadata(metadata)
if err != nil {
return nil, status.Error(codes.Internal, err.Error())
}
}
log.DebugLog(ctx, "cephfs: successfully created backing volume named %s for request name %s",
@ -442,7 +467,8 @@ func (cs *ControllerServer) DeleteVolume(
defer cs.OperationLocks.ReleaseDeleteLock(req.GetVolumeId())
// Find the volume using the provided VolumeID
volOptions, vID, err := store.NewVolumeOptionsFromVolID(ctx, string(volID), nil, secrets)
volOptions, vID, err := store.NewVolumeOptionsFromVolID(ctx, string(volID), nil, secrets,
cs.ClusterName, cs.SetMetadata)
if err != nil {
// if error is ErrPoolNotFound, the pool is already deleted we dont
// need to worry about deleting subvolume or omap data, return success
@ -497,7 +523,7 @@ func (cs *ControllerServer) DeleteVolume(
}
defer cr.DeleteCredentials()
if err := cleanUpBackingVolume(ctx, volOptions, vID, cr); err != nil {
if err := cs.cleanUpBackingVolume(ctx, volOptions, vID, cr); err != nil {
return nil, err
}
@ -510,7 +536,7 @@ func (cs *ControllerServer) DeleteVolume(
return &csi.DeleteVolumeResponse{}, nil
}
func cleanUpBackingVolume(
func (cs *ControllerServer) cleanUpBackingVolume(
ctx context.Context,
volOptions *store.VolumeOptions,
volID *store.VolumeIdentifier,
@ -519,7 +545,8 @@ func cleanUpBackingVolume(
if !volOptions.BackingSnapshot {
// Regular volumes need to be purged.
volClient := core.NewSubVolume(volOptions.GetConnection(), &volOptions.SubVolume, volOptions.ClusterID)
volClient := core.NewSubVolume(volOptions.GetConnection(),
&volOptions.SubVolume, volOptions.ClusterID, cs.ClusterName, cs.SetMetadata)
if err := volClient.PurgeVolume(ctx, false); err != nil {
log.ErrorLog(ctx, "failed to delete volume %s: %v", volID, err)
if errors.Is(err, cerrors.ErrVolumeHasSnapshots) {
@ -551,7 +578,8 @@ func cleanUpBackingVolume(
return nil
}
snapParentVolOptions, _, snapID, err := store.NewSnapshotOptionsFromID(ctx, volOptions.BackingSnapshotID, cr)
snapParentVolOptions, _, snapID, err := store.NewSnapshotOptionsFromID(ctx,
volOptions.BackingSnapshotID, cr, cs.ClusterName, cs.SetMetadata)
if err != nil {
absorbErrs := []error{
util.ErrPoolNotFound,
@ -573,11 +601,8 @@ func cleanUpBackingVolume(
return status.Error(codes.Internal, err.Error())
}
} else {
snapClient := core.NewSnapshot(
snapParentVolOptions.GetConnection(),
snapID.FsSnapshotName,
&snapParentVolOptions.SubVolume,
)
snapClient := core.NewSnapshot(snapParentVolOptions.GetConnection(), snapID.FsSnapshotName,
volOptions.ClusterID, cs.ClusterName, cs.SetMetadata, &snapParentVolOptions.SubVolume)
err = deleteSnapshotAndUndoReservation(ctx, snapClient, snapParentVolOptions, snapID, cr)
if err != nil {
@ -644,7 +669,8 @@ func (cs *ControllerServer) ControllerExpandVolume(
}
defer cr.DeleteCredentials()
volOptions, volIdentifier, err := store.NewVolumeOptionsFromVolID(ctx, volID, nil, secret)
volOptions, volIdentifier, err := store.NewVolumeOptionsFromVolID(ctx, volID, nil, secret,
cs.ClusterName, cs.SetMetadata)
if err != nil {
log.ErrorLog(ctx, "validation and extraction of volume options failed: %v", err)
@ -658,7 +684,8 @@ func (cs *ControllerServer) ControllerExpandVolume(
RoundOffSize := util.RoundOffCephFSVolSize(req.GetCapacityRange().GetRequiredBytes())
volClient := core.NewSubVolume(volOptions.GetConnection(), &volOptions.SubVolume, volOptions.ClusterID)
volClient := core.NewSubVolume(volOptions.GetConnection(),
&volOptions.SubVolume, volOptions.ClusterID, cs.ClusterName, cs.SetMetadata)
if err = volClient.ResizeVolume(ctx, RoundOffSize); err != nil {
log.ErrorLog(ctx, "failed to expand volume %s: %v", fsutil.VolumeID(volIdentifier.FsSubvolName), err)
@ -673,7 +700,7 @@ func (cs *ControllerServer) ControllerExpandVolume(
// CreateSnapshot creates the snapshot in backend and stores metadata
// in store
// nolint:gocyclo,cyclop // golangci-lint did not catch this earlier, needs to get fixed late
// nolint:gocognit,gocyclo,cyclop // golangci-lint did not catch this earlier, needs to get fixed late
func (cs *ControllerServer) CreateSnapshot(
ctx context.Context,
req *csi.CreateSnapshotRequest,
@ -711,7 +738,8 @@ func (cs *ControllerServer) CreateSnapshot(
defer cs.OperationLocks.ReleaseSnapshotCreateLock(sourceVolID)
// Find the volume using the provided VolumeID
parentVolOptions, vid, err := store.NewVolumeOptionsFromVolID(ctx, sourceVolID, nil, req.GetSecrets())
parentVolOptions, vid, err := store.NewVolumeOptionsFromVolID(ctx,
sourceVolID, nil, req.GetSecrets(), cs.ClusterName, cs.SetMetadata)
if err != nil {
if errors.Is(err, util.ErrPoolNotFound) {
log.WarningLog(ctx, "failed to get backend volume for %s: %v", sourceVolID, err)
@ -752,7 +780,7 @@ func (cs *ControllerServer) CreateSnapshot(
}
defer cs.VolumeLocks.Release(sourceVolID)
snapName := req.GetName()
sid, snapInfo, err := store.CheckSnapExists(ctx, parentVolOptions, cephfsSnap, cr)
sid, snapInfo, err := store.CheckSnapExists(ctx, parentVolOptions, cephfsSnap, cs.ClusterName, cs.SetMetadata, cr)
if err != nil {
return nil, status.Error(codes.Internal, err.Error())
}
@ -763,9 +791,8 @@ func (cs *ControllerServer) CreateSnapshot(
// request to create snapshot.
// TODO: For this purpose we could make use of cached clusterAdditionalInfo
// too.
volClient := core.NewSubVolume(parentVolOptions.GetConnection(),
&parentVolOptions.SubVolume,
parentVolOptions.ClusterID)
volClient := core.NewSubVolume(parentVolOptions.GetConnection(), &parentVolOptions.SubVolume,
parentVolOptions.ClusterID, cs.ClusterName, cs.SetMetadata)
info, err := volClient.GetSubVolumeInfo(ctx)
if err != nil {
// Check error code value against ErrInvalidCommand to understand the cluster
@ -787,11 +814,13 @@ func (cs *ControllerServer) CreateSnapshot(
return nil, status.Error(codes.Internal, err.Error())
}
metadata := k8s.GetSnapshotMetadata(req.GetParameters())
if sid != nil {
// check snapshot is protected
protected := true
snapClient := core.NewSnapshot(parentVolOptions.GetConnection(), sid.FsSnapshotName,
parentVolOptions.ClusterID, cs.ClusterName, cs.SetMetadata, &parentVolOptions.SubVolume)
if !(snapInfo.Protected == core.SnapshotIsProtected) {
snapClient := core.NewSnapshot(parentVolOptions.GetConnection(), sid.FsSnapshotName, &parentVolOptions.SubVolume)
err = snapClient.ProtectSnapshot(ctx)
if err != nil {
protected = false
@ -800,6 +829,15 @@ func (cs *ControllerServer) CreateSnapshot(
}
}
// Update snapshot-name/snapshot-namespace/snapshotcontent-name details on
// subvolume snapshot as metadata in case snapshot already exist
if len(metadata) != 0 {
err = snapClient.SetAllSnapshotMetadata(metadata)
if err != nil {
return nil, status.Error(codes.Internal, err.Error())
}
}
return &csi.CreateSnapshotResponse{
Snapshot: &csi.Snapshot{
SizeBytes: info.BytesQuota,
@ -825,7 +863,7 @@ func (cs *ControllerServer) CreateSnapshot(
}
}
}()
snap, err := doSnapshot(ctx, parentVolOptions, sID.FsSnapshotName)
snap, err := cs.doSnapshot(ctx, parentVolOptions, sID.FsSnapshotName, metadata)
if err != nil {
return nil, status.Error(codes.Internal, err.Error())
}
@ -841,14 +879,16 @@ func (cs *ControllerServer) CreateSnapshot(
}, nil
}
func doSnapshot(
func (cs *ControllerServer) doSnapshot(
ctx context.Context,
volOpt *store.VolumeOptions,
snapshotName string,
metadata map[string]string,
) (core.SnapshotInfo, error) {
snapID := fsutil.VolumeID(snapshotName)
snap := core.SnapshotInfo{}
snapClient := core.NewSnapshot(volOpt.GetConnection(), snapshotName, &volOpt.SubVolume)
snapClient := core.NewSnapshot(volOpt.GetConnection(), snapshotName,
volOpt.ClusterID, cs.ClusterName, cs.SetMetadata, &volOpt.SubVolume)
err := snapClient.CreateSnapshot(ctx)
if err != nil {
log.ErrorLog(ctx, "failed to create snapshot %s %v", snapID, err)
@ -880,6 +920,15 @@ func doSnapshot(
log.ErrorLog(ctx, "failed to protect snapshot %s %v", snapID, err)
}
// Set snapshot-name/snapshot-namespace/snapshotcontent-name details
// on subvolume snapshot as metadata on create
if len(metadata) != 0 {
err = snapClient.SetAllSnapshotMetadata(metadata)
if err != nil {
return snap, err
}
}
return snap, err
}
@ -941,7 +990,7 @@ func (cs *ControllerServer) DeleteSnapshot(
}
defer cs.OperationLocks.ReleaseDeleteLock(snapshotID)
volOpt, snapInfo, sid, err := store.NewSnapshotOptionsFromID(ctx, snapshotID, cr)
volOpt, snapInfo, sid, err := store.NewSnapshotOptionsFromID(ctx, snapshotID, cr, cs.ClusterName, cs.SetMetadata)
if err != nil {
switch {
case errors.Is(err, util.ErrPoolNotFound):
@ -996,7 +1045,8 @@ func (cs *ControllerServer) DeleteSnapshot(
if snapInfo.HasPendingClones == "yes" {
return nil, status.Errorf(codes.FailedPrecondition, "snapshot %s has pending clones", snapshotID)
}
snapClient := core.NewSnapshot(volOpt.GetConnection(), sid.FsSnapshotName, &volOpt.SubVolume)
snapClient := core.NewSnapshot(volOpt.GetConnection(), sid.FsSnapshotName,
volOpt.ClusterID, cs.ClusterName, cs.SetMetadata, &volOpt.SubVolume)
if snapInfo.Protected == core.SnapshotIsProtected {
err = snapClient.UnprotectSnapshot(ctx)
if err != nil {

View File

@ -66,7 +66,7 @@ func (s *subVolumeClient) CreateCloneFromSubvolume(
parentvolOpt *SubVolume,
) error {
snapshotID := s.VolID
snapClient := NewSnapshot(s.conn, snapshotID, parentvolOpt)
snapClient := NewSnapshot(s.conn, snapshotID, s.clusterID, s.clusterName, s.enableMetadata, parentvolOpt)
err := snapClient.CreateSnapshot(ctx)
if err != nil {
log.ErrorLog(ctx, "failed to create snapshot %s %v", snapshotID, err)
@ -165,7 +165,7 @@ func (s *subVolumeClient) CleanupSnapshotFromSubvolume(
// snapshot name is same as clone name as we need a name which can be
// identified during PVC-PVC cloning.
snapShotID := s.VolID
snapClient := NewSnapshot(s.conn, snapShotID, parentVol)
snapClient := NewSnapshot(s.conn, snapShotID, s.clusterID, s.clusterName, s.enableMetadata, parentVol)
snapInfo, err := snapClient.GetSnapshotInfo(ctx)
if err != nil {
if errors.Is(err, cerrors.ErrSnapNotFound) {
@ -198,7 +198,7 @@ func (s *subVolumeClient) CreateCloneFromSnapshot(
ctx context.Context, snap Snapshot,
) error {
snapID := snap.SnapshotID
snapClient := NewSnapshot(s.conn, snapID, snap.SubVolume)
snapClient := NewSnapshot(s.conn, snapID, s.clusterID, s.clusterName, s.enableMetadata, snap.SubVolume)
err := snapClient.CloneSnapshot(ctx, s.SubVolume)
if err != nil {
return err

View File

@ -0,0 +1,139 @@
/*
Copyright 2022 The Ceph-CSI Authors.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
package core
import (
"errors"
"fmt"
"strings"
fsAdmin "github.com/ceph/go-ceph/cephfs/admin"
)
const (
// clusterNameKey cluster Key, set on cephfs subvolume.
clusterNameKey = "csi.ceph.com/cluster/name"
)
// ErrSubVolMetadataNotSupported is returned when set/get/list/remove subvolume metadata options are not supported.
var ErrSubVolMetadataNotSupported = errors.New("subvolume metadata operations are not supported")
func (s *subVolumeClient) supportsSubVolMetadata() bool {
if _, keyPresent := clusterAdditionalInfo[s.clusterID]; !keyPresent {
clusterAdditionalInfo[s.clusterID] = &localClusterState{}
}
return clusterAdditionalInfo[s.clusterID].subVolMetadataState != unsupported
}
func (s *subVolumeClient) isUnsupportedSubVolMetadata(err error) bool {
var invalid fsAdmin.NotImplementedError
if err != nil && errors.Is(err, &invalid) {
// In case the error is other than invalid command return error to the caller.
clusterAdditionalInfo[s.clusterID].subVolMetadataState = unsupported
return false
}
clusterAdditionalInfo[s.clusterID].subVolMetadataState = supported
return true
}
// setMetadata sets custom metadata on the subvolume in a volume as a
// key-value pair.
func (s *subVolumeClient) setMetadata(key, value string) error {
var err error
if !s.supportsSubVolMetadata() {
return ErrSubVolMetadataNotSupported
}
fsa, err := s.conn.GetFSAdmin()
if err != nil {
return err
}
err = fsa.SetMetadata(s.FsName, s.SubvolumeGroup, s.VolID, key, value)
if !s.isUnsupportedSubVolMetadata(err) {
return ErrSubVolMetadataNotSupported
}
return err
}
// removeMetadata removes custom metadata set on the subvolume in a volume
// using the metadata key.
func (s *subVolumeClient) removeMetadata(key string) error {
var err error
if !s.supportsSubVolMetadata() {
return ErrSubVolMetadataNotSupported
}
fsa, err := s.conn.GetFSAdmin()
if err != nil {
return err
}
err = fsa.RemoveMetadata(s.FsName, s.SubvolumeGroup, s.VolID, key)
if !s.isUnsupportedSubVolMetadata(err) {
return ErrSubVolMetadataNotSupported
}
return err
}
// SetAllMetadata set all the metadata from arg parameters on Ssubvolume.
func (s *subVolumeClient) SetAllMetadata(parameters map[string]string) error {
if !s.enableMetadata {
return nil
}
for k, v := range parameters {
err := s.setMetadata(k, v)
if err != nil {
return fmt.Errorf("failed to set metadata key %q, value %q on subvolume %v: %w", k, v, s, err)
}
}
if s.clusterName != "" {
err := s.setMetadata(clusterNameKey, s.clusterName)
if err != nil {
return fmt.Errorf("failed to set metadata key %q, value %q on subvolume %v: %w",
clusterNameKey, s.clusterName, s, err)
}
}
return nil
}
// UnsetAllMetadata unset all the metadata from arg keys on subvolume.
func (s *subVolumeClient) UnsetAllMetadata(keys []string) error {
if !s.enableMetadata {
return nil
}
for _, key := range keys {
err := s.removeMetadata(key)
// TODO: replace string comparison with errno.
if err != nil && !strings.Contains(err.Error(), "No such file or directory") {
return fmt.Errorf("failed to unset metadata key %q on subvolume %v: %w", key, s, err)
}
}
err := s.removeMetadata(clusterNameKey)
// TODO: replace string comparison with errno.
if err != nil && !strings.Contains(err.Error(), "No such file or directory") {
return fmt.Errorf("failed to unset metadata key %q on subvolume %v: %w", clusterNameKey, s, err)
}
return nil
}

View File

@ -51,12 +51,21 @@ type SnapshotClient interface {
UnprotectSnapshot(ctx context.Context) error
// CloneSnapshot clones the snapshot of the subvolume.
CloneSnapshot(ctx context.Context, cloneVolOptions *SubVolume) error
// SetAllSnapshotMetadata set all the metadata from arg parameters on
// subvolume snapshot.
SetAllSnapshotMetadata(parameters map[string]string) error
// UnsetAllSnapshotMetadata unset all the metadata from arg keys on
// subvolume snapshot.
UnsetAllSnapshotMetadata(keys []string) error
}
// snapshotClient is the implementation of SnapshotClient interface.
type snapshotClient struct {
*Snapshot // Embedded snapshot struct.
conn *util.ClusterConnection // Cluster connection.
*Snapshot // Embedded snapshot struct.
clusterID string // Cluster ID.
clusterName string // Cluster Name.
enableMetadata bool // Set metadata on volume
conn *util.ClusterConnection // Cluster connection.
}
// Snapshot represents a subvolume snapshot and its cluster information.
@ -66,13 +75,23 @@ type Snapshot struct {
}
// NewSnapshot creates a new snapshot client.
func NewSnapshot(conn *util.ClusterConnection, snapshotID string, vol *SubVolume) SnapshotClient {
func NewSnapshot(
conn *util.ClusterConnection,
snapshotID,
clusterID,
clusterName string,
setMetadata bool,
vol *SubVolume,
) SnapshotClient {
return &snapshotClient{
Snapshot: &Snapshot{
SnapshotID: snapshotID,
SubVolume: vol,
},
conn: conn,
clusterID: clusterID,
clusterName: clusterName,
enableMetadata: setMetadata,
conn: conn,
}
}

View File

@ -0,0 +1,141 @@
/*
Copyright 2022 The Ceph-CSI Authors.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
package core
import (
"errors"
"fmt"
"strings"
fsAdmin "github.com/ceph/go-ceph/cephfs/admin"
)
// ErrSubVolSnapMetadataNotSupported is returned when set/get/list/remove
// subvolume snapshot metadata options are not supported.
var ErrSubVolSnapMetadataNotSupported = errors.New("subvolume snapshot metadata operations are not supported")
func (s *snapshotClient) supportsSubVolSnapMetadata() bool {
if _, keyPresent := clusterAdditionalInfo[s.clusterID]; !keyPresent {
clusterAdditionalInfo[s.clusterID] = &localClusterState{}
}
return clusterAdditionalInfo[s.clusterID].subVolSnapshotMetadataState != unsupported
}
func (s *snapshotClient) isUnsupportedSubVolSnapMetadata(err error) bool {
var invalid fsAdmin.NotImplementedError
if err != nil && errors.Is(err, &invalid) {
// In case the error is other than invalid command return error to
// the caller.
clusterAdditionalInfo[s.clusterID].subVolSnapshotMetadataState = unsupported
return false
}
clusterAdditionalInfo[s.clusterID].subVolSnapshotMetadataState = supported
return true
}
// setSnapshotMetadata sets custom metadata on the subvolume snapshot in a
// volume as a key-value pair.
func (s *snapshotClient) setSnapshotMetadata(key, value string) error {
if !s.supportsSubVolSnapMetadata() {
return ErrSubVolSnapMetadataNotSupported
}
fsa, err := s.conn.GetFSAdmin()
if err != nil {
return err
}
err = fsa.SetSnapshotMetadata(s.FsName, s.SubvolumeGroup, s.VolID, s.SnapshotID, key, value)
if !s.isUnsupportedSubVolSnapMetadata(err) {
return ErrSubVolSnapMetadataNotSupported
}
return err
}
// removeSnapshotMetadata removes custom metadata set on the subvolume
// snapshot in a volume using the metadata key.
func (s *snapshotClient) removeSnapshotMetadata(key string) error {
if !s.supportsSubVolSnapMetadata() {
return ErrSubVolSnapMetadataNotSupported
}
fsa, err := s.conn.GetFSAdmin()
if err != nil {
return err
}
err = fsa.RemoveSnapshotMetadata(s.FsName, s.SubvolumeGroup, s.VolID, s.SnapshotID, key)
if !s.isUnsupportedSubVolSnapMetadata(err) {
return ErrSubVolSnapMetadataNotSupported
}
return err
}
// SetAllSnapshotMetadata set all the metadata from arg parameters on
// subvolume snapshot.
func (s *snapshotClient) SetAllSnapshotMetadata(parameters map[string]string) error {
if !s.enableMetadata {
return nil
}
for k, v := range parameters {
err := s.setSnapshotMetadata(k, v)
if err != nil {
return fmt.Errorf("failed to set metadata key %q, value %q on subvolume snapshot %s %s in fs %s: %w",
k, v, s.SnapshotID, s.VolID, s.FsName, err)
}
}
if s.clusterName != "" {
err := s.setSnapshotMetadata(clusterNameKey, s.clusterName)
if err != nil {
return fmt.Errorf("failed to set metadata key %q, value %q on subvolume snapshot %s %s in fs %s: %w",
clusterNameKey, s.clusterName, s.SnapshotID, s.VolID, s.FsName, err)
}
}
return nil
}
// UnsetAllSnapshotMetadata unset all the metadata from arg keys on subvolume
// snapshot.
func (s *snapshotClient) UnsetAllSnapshotMetadata(keys []string) error {
if !s.enableMetadata {
return nil
}
for _, key := range keys {
err := s.removeSnapshotMetadata(key)
// TODO: replace string comparison with errno.
if err != nil && !strings.Contains(err.Error(), "No such file or directory") {
return fmt.Errorf("failed to unset metadata key %q on subvolume snapshot %s %s in fs %s: %w",
key, s.SnapshotID, s.VolID, s.FsName, err)
}
}
err := s.removeSnapshotMetadata(clusterNameKey)
// TODO: replace string comparison with errno.
if err != nil && !strings.Contains(err.Error(), "No such file or directory") {
return fmt.Errorf("failed to unset metadata key %q on subvolume snapshot %s %s in fs %s: %w",
clusterNameKey, s.SnapshotID, s.VolID, s.FsName, err)
}
return nil
}

View File

@ -72,13 +72,20 @@ type SubVolumeClient interface {
CreateCloneFromSnapshot(ctx context.Context, snap Snapshot) error
// CleanupSnapshotFromSubvolume removes the snapshot from the subvolume.
CleanupSnapshotFromSubvolume(ctx context.Context, parentVol *SubVolume) error
// SetAllMetadata set all the metadata from arg parameters on Ssubvolume.
SetAllMetadata(parameters map[string]string) error
// UnsetAllMetadata unset all the metadata from arg keys on subvolume.
UnsetAllMetadata(keys []string) error
}
// subVolumeClient implements SubVolumeClient interface.
type subVolumeClient struct {
*SubVolume // Embedded SubVolume struct.
clusterID string // Cluster ID to check subvolumegroup and resize functionality.
conn *util.ClusterConnection // Cluster connection.
*SubVolume // Embedded SubVolume struct.
clusterID string // Cluster ID to check subvolumegroup and resize functionality.
clusterName string // Cluster name
enableMetadata bool // Set metadata on volume
conn *util.ClusterConnection // Cluster connection.
}
// SubVolume holds the information about the subvolume.
@ -92,11 +99,19 @@ type SubVolume struct {
}
// NewSubVolume returns a new subvolume client.
func NewSubVolume(conn *util.ClusterConnection, vol *SubVolume, clusterID string) SubVolumeClient {
func NewSubVolume(
conn *util.ClusterConnection,
vol *SubVolume,
clusterID,
clusterName string,
setMetadata bool,
) SubVolumeClient {
return &subVolumeClient{
SubVolume: vol,
clusterID: clusterID,
conn: conn,
SubVolume: vol,
clusterID: clusterID,
clusterName: clusterName,
enableMetadata: setMetadata,
conn: conn,
}
}
@ -184,7 +199,9 @@ const (
type localClusterState struct {
// set the enum value i.e., unknown, supported,
// unsupported as per the state of the cluster.
resizeState operationState
resizeState operationState
subVolMetadataState operationState
subVolSnapshotMetadataState operationState
// set true once a subvolumegroup is created
// for corresponding cluster.
subVolumeGroupCreated bool

View File

@ -135,6 +135,8 @@ func (fs *Driver) Run(conf *util.Config) {
if conf.IsControllerServer {
fs.cs = NewControllerServer(fs.cd)
fs.cs.ClusterName = conf.ClusterName
fs.cs.SetMetadata = conf.SetMetadata
}
if !conf.IsControllerServer && !conf.IsNodeServer {
topology, err = util.GetTopologyFromDomainLabels(conf.DomainLabels, conf.NodeID, conf.DriverName)

View File

@ -82,7 +82,7 @@ func (ns *NodeServer) getVolumeOptions(
volContext,
volSecrets map[string]string,
) (*store.VolumeOptions, error) {
volOptions, _, err := store.NewVolumeOptionsFromVolID(ctx, string(volID), volContext, volSecrets)
volOptions, _, err := store.NewVolumeOptionsFromVolID(ctx, string(volID), volContext, volSecrets, "", false)
if err != nil {
if !errors.Is(err, cerrors.ErrInvalidVolID) {
return nil, status.Error(codes.Internal, err.Error())

View File

@ -34,6 +34,8 @@ func fmtBackingSnapshotReftrackerName(backingSnapID string) string {
func AddSnapshotBackedVolumeRef(
ctx context.Context,
volOptions *VolumeOptions,
clusterName string,
setMetadata bool,
) error {
ioctx, err := volOptions.conn.GetIoctx(volOptions.MetadataPool)
if err != nil {
@ -95,7 +97,8 @@ func AddSnapshotBackedVolumeRef(
// There may have been a race between adding a ref to the reftracker and
// deleting the backing snapshot. Make sure the snapshot still exists by
// trying to retrieve it again.
_, _, _, err = NewSnapshotOptionsFromID(ctx, volOptions.BackingSnapshotID, volOptions.conn.Creds)
_, _, _, err = NewSnapshotOptionsFromID(ctx,
volOptions.BackingSnapshotID, volOptions.conn.Creds, clusterName, setMetadata)
if err != nil {
log.ErrorLog(ctx, "failed to get backing snapshot %s: %v", volOptions.BackingSnapshotID, err)
}

View File

@ -78,6 +78,8 @@ func CheckVolExists(ctx context.Context,
pvID *VolumeIdentifier,
sID *SnapshotIdentifier,
cr *util.Credentials,
clusterName string,
setMetadata bool,
) (*VolumeIdentifier, error) {
var vid VolumeIdentifier
// Connect to cephfs' default radosNamespace (csi)
@ -99,7 +101,7 @@ func CheckVolExists(ctx context.Context,
vid.FsSubvolName = imageData.ImageAttributes.ImageName
volOptions.VolID = vid.FsSubvolName
vol := core.NewSubVolume(volOptions.conn, &volOptions.SubVolume, volOptions.ClusterID)
vol := core.NewSubVolume(volOptions.conn, &volOptions.SubVolume, volOptions.ClusterID, clusterName, setMetadata)
if (sID != nil || pvID != nil) && imageData.ImageAttributes.BackingSnapshotID == "" {
cloneState, cloneStateErr := vol.GetCloneState(ctx)
if cloneStateErr != nil {
@ -376,6 +378,8 @@ func CheckSnapExists(
ctx context.Context,
volOptions *VolumeOptions,
snap *SnapshotOption,
clusterName string,
setMetadata bool,
cr *util.Credentials,
) (*SnapshotIdentifier, *core.SnapshotInfo, error) {
// Connect to cephfs' default radosNamespace (csi)
@ -397,7 +401,8 @@ func CheckSnapExists(
snapUUID := snapData.ImageUUID
snapID := snapData.ImageAttributes.ImageName
sid.FsSnapshotName = snapData.ImageAttributes.ImageName
snapClient := core.NewSnapshot(volOptions.conn, snapID, &volOptions.SubVolume)
snapClient := core.NewSnapshot(volOptions.conn, snapID,
volOptions.ClusterID, clusterName, setMetadata, &volOptions.SubVolume)
snapInfo, err := snapClient.GetSnapshotInfo(ctx)
if err != nil {
if errors.Is(err, cerrors.ErrSnapNotFound) {

View File

@ -196,7 +196,12 @@ func fmtBackingSnapshotOptionMismatch(optName, expected, actual string) error {
// NewVolumeOptions generates a new instance of volumeOptions from the provided
// CSI request parameters.
func NewVolumeOptions(ctx context.Context, requestName string, req *csi.CreateVolumeRequest,
func NewVolumeOptions(
ctx context.Context,
requestName,
clusterName string,
setMetadata bool,
req *csi.CreateVolumeRequest,
cr *util.Credentials,
) (*VolumeOptions, error) {
var (
@ -289,7 +294,7 @@ func NewVolumeOptions(ctx context.Context, requestName string, req *csi.CreateVo
opts.BackingSnapshotID = req.GetVolumeContentSource().GetSnapshot().GetSnapshotId()
err = opts.populateVolumeOptionsFromBackingSnapshot(ctx, cr)
err = opts.populateVolumeOptionsFromBackingSnapshot(ctx, cr, clusterName, setMetadata)
if err != nil {
return nil, err
}
@ -304,6 +309,8 @@ func NewVolumeOptionsFromVolID(
ctx context.Context,
volID string,
volOpt, secrets map[string]string,
clusterName string,
setMetadata bool,
) (*VolumeOptions, *VolumeIdentifier, error) {
var (
vi util.CSIIdentifier
@ -407,16 +414,20 @@ func NewVolumeOptionsFromVolID(
volOptions.SubVolume.VolID = vid.FsSubvolName
if volOptions.BackingSnapshot {
err = volOptions.populateVolumeOptionsFromBackingSnapshot(ctx, cr)
err = volOptions.populateVolumeOptionsFromBackingSnapshot(ctx, cr, clusterName, setMetadata)
} else {
err = volOptions.populateVolumeOptionsFromSubvolume(ctx)
err = volOptions.populateVolumeOptionsFromSubvolume(ctx, clusterName, setMetadata)
}
return &volOptions, &vid, err
}
func (vo *VolumeOptions) populateVolumeOptionsFromSubvolume(ctx context.Context) error {
vol := core.NewSubVolume(vo.conn, &vo.SubVolume, vo.ClusterID)
func (vo *VolumeOptions) populateVolumeOptionsFromSubvolume(
ctx context.Context,
clusterName string,
setMetadata bool,
) error {
vol := core.NewSubVolume(vo.conn, &vo.SubVolume, vo.ClusterID, clusterName, setMetadata)
var info *core.Subvolume
info, err := vol.GetSubVolumeInfo(ctx)
@ -436,6 +447,8 @@ func (vo *VolumeOptions) populateVolumeOptionsFromSubvolume(ctx context.Context)
func (vo *VolumeOptions) populateVolumeOptionsFromBackingSnapshot(
ctx context.Context,
cr *util.Credentials,
clusterName string,
setMetadata bool,
) error {
// As of CephFS snapshot v2 API, snapshots may be found in two locations:
//
@ -457,7 +470,8 @@ func (vo *VolumeOptions) populateVolumeOptionsFromBackingSnapshot(
return nil
}
parentBackingSnapVolOpts, _, snapID, err := NewSnapshotOptionsFromID(ctx, vo.BackingSnapshotID, cr)
parentBackingSnapVolOpts, _, snapID, err := NewSnapshotOptionsFromID(ctx,
vo.BackingSnapshotID, cr, clusterName, setMetadata)
if err != nil {
return fmt.Errorf("failed to retrieve backing snapshot %s: %w", vo.BackingSnapshotID, err)
}
@ -652,6 +666,8 @@ func NewSnapshotOptionsFromID(
ctx context.Context,
snapID string,
cr *util.Credentials,
clusterName string,
setMetadata bool,
) (*VolumeOptions, *core.SnapshotInfo, *SnapshotIdentifier, error) {
var (
vi util.CSIIdentifier
@ -723,7 +739,7 @@ func NewSnapshotOptionsFromID(
sid.FsSubvolName = imageAttributes.SourceName
volOptions.SubVolume.VolID = sid.FsSubvolName
vol := core.NewSubVolume(volOptions.conn, &volOptions.SubVolume, volOptions.ClusterID)
vol := core.NewSubVolume(volOptions.conn, &volOptions.SubVolume, volOptions.ClusterID, clusterName, setMetadata)
subvolInfo, err := vol.GetSubVolumeInfo(ctx)
if err != nil {
@ -732,7 +748,8 @@ func NewSnapshotOptionsFromID(
volOptions.Features = subvolInfo.Features
volOptions.Size = subvolInfo.BytesQuota
volOptions.RootPath = subvolInfo.Path
snap := core.NewSnapshot(volOptions.conn, sid.FsSnapshotName, &volOptions.SubVolume)
snap := core.NewSnapshot(volOptions.conn, sid.FsSnapshotName,
volOptions.ClusterID, clusterName, setMetadata, &volOptions.SubVolume)
info, err := snap.GetSnapshotInfo(ctx)
if err != nil {
return &volOptions, nil, &sid, err

View File

@ -64,7 +64,7 @@ func NewDefaultNodeServer(d *CSIDriver, t string, topology map[string]string) *D
return &DefaultNodeServer{
Driver: d,
Type: t,
Mounter: mount.New(""),
Mounter: mount.NewWithoutSystemd(""),
}
}

View File

@ -18,7 +18,7 @@ package controller
import (
"context"
"strings"
"errors"
"github.com/ceph/ceph-csi/internal/cephfs"
"github.com/ceph/ceph-csi/internal/cephfs/store"
@ -147,11 +147,11 @@ func (cs *Server) DeleteVolume(
err = nfsVolume.DeleteExport()
// if the export does not exist, continue with deleting the backend volume
if err != nil && !strings.Contains(err.Error(), "Export does not exist") {
if err != nil && !errors.Is(err, ErrNotFound) {
return nil, status.Errorf(codes.InvalidArgument, "failed to delete export: %v", err)
}
log.DebugLog(ctx, "deleted NFS-export: %s", nfsVolume)
log.DebugLog(ctx, "NFS-export %q has been deleted", nfsVolume)
return cs.backendServer.DeleteVolume(ctx, req)
}

View File

@ -0,0 +1,43 @@
/*
Copyright 2022 The Ceph-CSI Authors.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
package controller
import (
"errors"
"fmt"
)
var (
// ErrNotConnected is returned when components from the NFS
// ControllerServer can not connect to the Ceph cluster or NFS-Ganesha
// service.
ErrNotConnected = errors.New("not connected")
// ErrNotFound is a generic error that is the parent of other "not
// found" failures. Callers can check if something was "not found",
// even if the actual error is more specific.
ErrNotFound = errors.New("not found")
// ErrExportNotFound is returned by components that communicate with the
// NFS-Ganesha service, and have identified that the NFS-Export does
// not exist (anymore). This error is also a ErrNotFound.
ErrExportNotFound = fmt.Errorf("NFS-export %w", ErrNotFound)
// ErrFilesystemNotFound is returned in case the filesystem
// does not exist.
ErrFilesystemNotFound = fmt.Errorf("filesystem %w", ErrNotFound)
)

View File

@ -18,6 +18,7 @@ package controller
import (
"context"
"errors"
"fmt"
"strings"
@ -124,7 +125,7 @@ func (nv *NFSVolume) GetExportPath() string {
// a new NFS-export for the volume on the Ceph managed NFS-server.
func (nv *NFSVolume) CreateExport(backend *csi.Volume) error {
if !nv.connected {
return fmt.Errorf("can not created export for %q: not connected", nv)
return fmt.Errorf("can not created export for %q: %w", nv, ErrNotConnected)
}
fs := backend.VolumeContext["fsName"]
@ -213,6 +214,8 @@ func (nv *NFSVolume) DeleteExport() error {
return nil
case strings.Contains(err.Error(), "API call not implemented"): // try with the old command
break
case strings.Contains(err.Error(), "Export does not exist"):
return ErrExportNotFound
default: // any other error
return fmt.Errorf("failed to remove %q from NFS-cluster %q: "+
"%w", nv, nfsCluster, err)
@ -251,17 +254,21 @@ func (nv *NFSVolume) deleteExportCommand(cmd, nfsCluster string) []string {
// getNFSCluster fetches the NFS-cluster name from the CephFS journal.
func (nv *NFSVolume) getNFSCluster() (string, error) {
if !nv.connected {
return "", fmt.Errorf("can not get NFS-cluster for %q: not connected", nv)
return "", fmt.Errorf("can not get NFS-cluster for %q: %w", nv, ErrNotConnected)
}
fs := fscore.NewFileSystem(nv.conn)
fsName, err := fs.GetFsName(nv.ctx, nv.fscID)
if err != nil {
if err != nil && errors.Is(err, util.ErrPoolNotFound) {
return "", fmt.Errorf("%w for ID %x: %v", ErrFilesystemNotFound, nv.fscID, err)
} else if err != nil {
return "", fmt.Errorf("failed to get filesystem name for ID %x: %w", nv.fscID, err)
}
mdPool, err := fs.GetMetadataPool(nv.ctx, fsName)
if err != nil {
if err != nil && errors.Is(err, util.ErrPoolNotFound) {
return "", fmt.Errorf("metadata pool for %q %w: %v", fsName, ErrNotFound, err)
} else if err != nil {
return "", fmt.Errorf("failed to get metadata pool for %q: %w", fsName, err)
}
@ -273,8 +280,10 @@ func (nv *NFSVolume) getNFSCluster() (string, error) {
defer j.Destroy()
clusterName, err := j.FetchAttribute(nv.ctx, mdPool, nv.objectUUID, clusterNameKey)
if err != nil {
return "", fmt.Errorf("failed to get cluster name: %w", err)
if err != nil && errors.Is(err, util.ErrPoolNotFound) || errors.Is(err, util.ErrKeyNotFound) {
return "", fmt.Errorf("cluster name for %q %w: %v", nv.objectUUID, ErrNotFound, err)
} else if err != nil {
return "", fmt.Errorf("failed to get cluster name for %q: %w", nv.objectUUID, err)
}
return clusterName, nil
@ -283,17 +292,21 @@ func (nv *NFSVolume) getNFSCluster() (string, error) {
// setNFSCluster stores the NFS-cluster name in the CephFS journal.
func (nv *NFSVolume) setNFSCluster(clusterName string) error {
if !nv.connected {
return fmt.Errorf("can not set NFS-cluster for %q: not connected", nv)
return fmt.Errorf("can not set NFS-cluster for %q: %w", nv, ErrNotConnected)
}
fs := fscore.NewFileSystem(nv.conn)
fsName, err := fs.GetFsName(nv.ctx, nv.fscID)
if err != nil {
if err != nil && errors.Is(err, util.ErrPoolNotFound) {
return fmt.Errorf("%w for ID %x: %v", ErrFilesystemNotFound, nv.fscID, err)
} else if err != nil {
return fmt.Errorf("failed to get filesystem name for ID %x: %w", nv.fscID, err)
}
mdPool, err := fs.GetMetadataPool(nv.ctx, fsName)
if err != nil {
if err != nil && errors.Is(err, util.ErrPoolNotFound) {
return fmt.Errorf("metadata pool for %q %w: %v", fsName, ErrNotFound, err)
} else if err != nil {
return fmt.Errorf("failed to get metadata pool for %q: %w", fsName, err)
}

View File

@ -1587,3 +1587,36 @@ func (cs *ControllerServer) ControllerExpandVolume(
NodeExpansionRequired: nodeExpansion,
}, nil
}
// ControllerPublishVolume is a dummy publish implementation to mimic a successful attach operation being a NOOP.
func (cs *ControllerServer) ControllerPublishVolume(
ctx context.Context,
req *csi.ControllerPublishVolumeRequest,
) (*csi.ControllerPublishVolumeResponse, error) {
if req.GetVolumeId() == "" {
return nil, status.Error(codes.InvalidArgument, "Volume ID cannot be empty")
}
if req.GetNodeId() == "" {
return nil, status.Error(codes.InvalidArgument, "Node ID cannot be empty")
}
if req.GetVolumeCapability() == nil {
return nil, status.Error(codes.InvalidArgument, "Volume Capabilities cannot be empty")
}
return &csi.ControllerPublishVolumeResponse{
// the dummy response carry an empty map in its response.
PublishContext: map[string]string{},
}, nil
}
// ControllerUnPublishVolume is a dummy unpublish implementation to mimic a successful attach operation being a NOOP.
func (cs *ControllerServer) ControllerUnpublishVolume(
ctx context.Context,
req *csi.ControllerUnpublishVolumeRequest,
) (*csi.ControllerUnpublishVolumeResponse, error) {
if req.GetVolumeId() == "" {
return nil, status.Error(codes.InvalidArgument, "Volume ID cannot be empty")
}
return &csi.ControllerUnpublishVolumeResponse{}, nil
}

View File

@ -814,7 +814,7 @@ func (ns *NodeServer) mountVolume(ctx context.Context, stagingPath string, req *
func (ns *NodeServer) createTargetMountPath(ctx context.Context, mountPath string, isBlock bool) (bool, error) {
// Check if that mount path exists properly
notMnt, err := mount.IsNotMountPoint(ns.Mounter, mountPath)
notMnt, err := ns.Mounter.IsLikelyNotMountPoint(mountPath)
if err == nil {
return notMnt, nil
}
@ -858,7 +858,7 @@ func (ns *NodeServer) NodeUnpublishVolume(
targetPath := req.GetTargetPath()
// considering kubelet make sure node operations like unpublish/unstage...etc can not be called
// at same time, an explicit locking at time of nodeunpublish is not required.
notMnt, err := mount.IsNotMountPoint(ns.Mounter, targetPath)
isMnt, err := ns.Mounter.IsMountPoint(targetPath)
if err != nil {
if os.IsNotExist(err) {
// targetPath has already been deleted
@ -869,7 +869,7 @@ func (ns *NodeServer) NodeUnpublishVolume(
return nil, status.Error(codes.NotFound, err.Error())
}
if notMnt {
if !isMnt {
if err = os.RemoveAll(targetPath); err != nil {
return nil, status.Error(codes.Internal, err.Error())
}
@ -925,15 +925,15 @@ func (ns *NodeServer) NodeUnstageVolume(
stagingParentPath := req.GetStagingTargetPath()
stagingTargetPath := getStagingTargetPath(req)
notMnt, err := mount.IsNotMountPoint(ns.Mounter, stagingTargetPath)
isMnt, err := ns.Mounter.IsMountPoint(stagingTargetPath)
if err != nil {
if !os.IsNotExist(err) {
return nil, status.Error(codes.NotFound, err.Error())
}
// Continue on ENOENT errors as we may still have the image mapped
notMnt = true
isMnt = false
}
if !notMnt {
if isMnt {
// Unmounting the image
err = ns.Mounter.Unmount(stagingTargetPath)
if err != nil {
@ -961,7 +961,7 @@ func (ns *NodeServer) NodeUnstageVolume(
log.UsefulLog(ctx, "failed to find image metadata: %v", err)
// It is an error if it was mounted, as we should have found the image metadata file with
// no errors
if !notMnt {
if isMnt {
return nil, status.Error(codes.Internal, err.Error())
}

View File

@ -554,12 +554,12 @@ func checkValidImageFeatures(imageFeatures string, ok bool) bool {
// isNotMountPoint checks whether MountPoint does not exists and
// also discards error indicating mountPoint exists.
func isNotMountPoint(mounter mount.Interface, stagingTargetPath string) (bool, error) {
isNotMnt, err := mount.IsNotMountPoint(mounter, stagingTargetPath)
isMnt, err := mounter.IsMountPoint(stagingTargetPath)
if os.IsNotExist(err) {
err = nil
}
return isNotMnt, err
return !isMnt, err
}
// isCephMgrSupported determines if the cluster has support for MGR based operation

File diff suppressed because it is too large Load Diff

View File

@ -5,4 +5,4 @@ package aws
const SDKName = "aws-sdk-go"
// SDKVersion is the version of this SDK
const SDKVersion = "1.44.28"
const SDKVersion = "1.44.62"

File diff suppressed because it is too large Load Diff

View File

@ -534,7 +534,7 @@ func (c *KMS) CreateCustomKeyStoreRequest(input *CreateCustomKeyStoreInput) (req
// that is associated with an CloudHSM cluster (https://docs.aws.amazon.com/cloudhsm/latest/userguide/clusters.html)
// that you own and manage.
//
// This operation is part of the Custom Key Store feature (https://docs.aws.amazon.com/kms/latest/developerguide/custom-key-store-overview.html)
// This operation is part of the custom key store feature (https://docs.aws.amazon.com/kms/latest/developerguide/custom-key-store-overview.html)
// feature in KMS, which combines the convenience and extensive integration
// of KMS with the isolation and control of a single-tenant key store.
//
@ -894,7 +894,8 @@ func (c *KMS) CreateKeyRequest(input *CreateKeyInput) (req *request.Request, out
// To create a symmetric encryption KMS key, you aren't required to specify
// any parameters. The default value for KeySpec, SYMMETRIC_DEFAULT, and the
// default value for KeyUsage, ENCRYPT_DECRYPT, create a symmetric encryption
// KMS key.
// KMS key. For technical details, see SYMMETRIC_DEFAULT key spec (https://docs.aws.amazon.com/kms/latest/developerguide/asymmetric-key-specs.html#key-spec-symmetric-default)
// in the Key Management Service Developer Guide.
//
// If you need a key for basic encryption and decryption or you are creating
// a KMS key to protect your resources in an Amazon Web Services service, create
@ -911,13 +912,14 @@ func (c *KMS) CreateKeyRequest(input *CreateKeyInput) (req *request.Request, out
// determine whether the KMS key will be used to encrypt and decrypt or sign
// and verify. You can't change these properties after the KMS key is created.
//
// Asymmetric KMS keys contain an RSA key pair or an Elliptic Curve (ECC) key
// pair. The private key in an asymmetric KMS key never leaves KMS unencrypted.
// However, you can use the GetPublicKey operation to download the public key
// so it can be used outside of KMS. KMS keys with RSA key pairs can be used
// to encrypt or decrypt data or sign and verify messages (but not both). KMS
// keys with ECC key pairs can be used only to sign and verify messages. For
// information about asymmetric KMS keys, see Asymmetric KMS keys (https://docs.aws.amazon.com/kms/latest/developerguide/symmetric-asymmetric.html)
// Asymmetric KMS keys contain an RSA key pair, Elliptic Curve (ECC) key pair,
// or an SM2 key pair (China Regions only). The private key in an asymmetric
// KMS key never leaves KMS unencrypted. However, you can use the GetPublicKey
// operation to download the public key so it can be used outside of KMS. KMS
// keys with RSA or SM2 key pairs can be used to encrypt or decrypt data or
// sign and verify messages (but not both). KMS keys with ECC key pairs can
// be used only to sign and verify messages. For information about asymmetric
// KMS keys, see Asymmetric KMS keys (https://docs.aws.amazon.com/kms/latest/developerguide/symmetric-asymmetric.html)
// in the Key Management Service Developer Guide.
//
// HMAC KMS key
@ -1516,7 +1518,7 @@ func (c *KMS) DeleteCustomKeyStoreRequest(input *DeleteCustomKeyStoreInput) (req
// This operation does not delete the CloudHSM cluster that is associated with
// the custom key store, or affect any users or keys in the cluster.
//
// The custom key store that you delete cannot contain any KMS KMS keys (https://docs.aws.amazon.com/kms/latest/developerguide/concepts.html#kms_keys).
// The custom key store that you delete cannot contain any KMS keys (https://docs.aws.amazon.com/kms/latest/developerguide/concepts.html#kms_keys).
// Before deleting the key store, verify that you will never need to use any
// of the KMS keys in the key store for any cryptographic operations (https://docs.aws.amazon.com/kms/latest/developerguide/concepts.html#cryptographic-operations).
// Then, use ScheduleKeyDeletion to delete the KMS keys from the key store.
@ -1536,7 +1538,7 @@ func (c *KMS) DeleteCustomKeyStoreRequest(input *DeleteCustomKeyStoreInput) (req
//
// If the operation succeeds, it returns a JSON object with no properties.
//
// This operation is part of the Custom Key Store feature (https://docs.aws.amazon.com/kms/latest/developerguide/custom-key-store-overview.html)
// This operation is part of the custom key store feature (https://docs.aws.amazon.com/kms/latest/developerguide/custom-key-store-overview.html)
// feature in KMS, which combines the convenience and extensive integration
// of KMS with the isolation and control of a single-tenant key store.
//
@ -1783,6 +1785,12 @@ func (c *KMS) DescribeCustomKeyStoresRequest(input *DescribeCustomKeyStoresInput
Name: opDescribeCustomKeyStores,
HTTPMethod: "POST",
HTTPPath: "/",
Paginator: &request.Paginator{
InputTokens: []string{"Marker"},
OutputTokens: []string{"NextMarker"},
LimitToken: "Limit",
TruncationToken: "Truncated",
},
}
if input == nil {
@ -1799,7 +1807,7 @@ func (c *KMS) DescribeCustomKeyStoresRequest(input *DescribeCustomKeyStoresInput
// Gets information about custom key stores (https://docs.aws.amazon.com/kms/latest/developerguide/custom-key-store-overview.html)
// in the account and Region.
//
// This operation is part of the Custom Key Store feature (https://docs.aws.amazon.com/kms/latest/developerguide/custom-key-store-overview.html)
// This operation is part of the custom key store feature (https://docs.aws.amazon.com/kms/latest/developerguide/custom-key-store-overview.html)
// feature in KMS, which combines the convenience and extensive integration
// of KMS with the isolation and control of a single-tenant key store.
//
@ -1884,6 +1892,58 @@ func (c *KMS) DescribeCustomKeyStoresWithContext(ctx aws.Context, input *Describ
return out, req.Send()
}
// DescribeCustomKeyStoresPages iterates over the pages of a DescribeCustomKeyStores operation,
// calling the "fn" function with the response data for each page. To stop
// iterating, return false from the fn function.
//
// See DescribeCustomKeyStores method for more information on how to use this operation.
//
// Note: This operation can generate multiple requests to a service.
//
// // Example iterating over at most 3 pages of a DescribeCustomKeyStores operation.
// pageNum := 0
// err := client.DescribeCustomKeyStoresPages(params,
// func(page *kms.DescribeCustomKeyStoresOutput, lastPage bool) bool {
// pageNum++
// fmt.Println(page)
// return pageNum <= 3
// })
//
func (c *KMS) DescribeCustomKeyStoresPages(input *DescribeCustomKeyStoresInput, fn func(*DescribeCustomKeyStoresOutput, bool) bool) error {
return c.DescribeCustomKeyStoresPagesWithContext(aws.BackgroundContext(), input, fn)
}
// DescribeCustomKeyStoresPagesWithContext same as DescribeCustomKeyStoresPages except
// it takes a Context and allows setting request options on the pages.
//
// The context must be non-nil and will be used for request cancellation. If
// the context is nil a panic will occur. In the future the SDK may create
// sub-contexts for http.Requests. See https://golang.org/pkg/context/
// for more information on using Contexts.
func (c *KMS) DescribeCustomKeyStoresPagesWithContext(ctx aws.Context, input *DescribeCustomKeyStoresInput, fn func(*DescribeCustomKeyStoresOutput, bool) bool, opts ...request.Option) error {
p := request.Pagination{
NewRequest: func() (*request.Request, error) {
var inCpy *DescribeCustomKeyStoresInput
if input != nil {
tmp := *input
inCpy = &tmp
}
req, _ := c.DescribeCustomKeyStoresRequest(inCpy)
req.SetContext(ctx)
req.ApplyOptions(opts...)
return req, nil
},
}
for p.Next() {
if !fn(p.Page().(*DescribeCustomKeyStoresOutput), !p.HasNextPage()) {
break
}
}
return p.Err()
}
const opDescribeKey = "DescribeKey"
// DescribeKeyRequest generates a "aws/request.Request" representing the
@ -1950,7 +2010,7 @@ func (c *KMS) DescribeKeyRequest(input *DescribeKeyInput) (req *request.Request,
// information, use GetKeyRotationStatus. Also, some key states prevent a
// KMS key from being automatically rotated. For details, see How Automatic
// Key Rotation Works (https://docs.aws.amazon.com/kms/latest/developerguide/rotate-keys.html#rotate-keys-how-it-works)
// in Key Management Service Developer Guide.
// in the Key Management Service Developer Guide.
//
// * Tags on the KMS key. To get this information, use ListResourceTags.
//
@ -2356,7 +2416,7 @@ func (c *KMS) DisconnectCustomKeyStoreRequest(input *DisconnectCustomKeyStoreInp
//
// If the operation succeeds, it returns a JSON object with no properties.
//
// This operation is part of the Custom Key Store feature (https://docs.aws.amazon.com/kms/latest/developerguide/custom-key-store-overview.html)
// This operation is part of the custom key store feature (https://docs.aws.amazon.com/kms/latest/developerguide/custom-key-store-overview.html)
// feature in KMS, which combines the convenience and extensive integration
// of KMS with the isolation and control of a single-tenant key store.
//
@ -2774,7 +2834,7 @@ func (c *KMS) EncryptRequest(input *EncryptInput) (req *request.Request, output
// in the Key Management Service Developer Guide.
//
// If you specify an asymmetric KMS key, you must also specify the encryption
// algorithm. The algorithm must be compatible with the KMS key type.
// algorithm. The algorithm must be compatible with the KMS key spec.
//
// When you use an asymmetric KMS key to encrypt or reencrypt data, be sure
// to record the KMS key and encryption algorithm that you choose. You will
@ -2799,6 +2859,8 @@ func (c *KMS) EncryptRequest(input *EncryptInput) (req *request.Request, output
//
// * RSA_4096 RSAES_OAEP_SHA_1: 470 bytes RSAES_OAEP_SHA_256: 446 bytes
//
// * SM2PKE: 1024 bytes (China Regions only)
//
// The KMS key that you use for this operation must be in a compatible key state.
// For details, see Key states of KMS keys (https://docs.aws.amazon.com/kms/latest/developerguide/key-state.html)
// in the Key Management Service Developer Guide.
@ -2949,10 +3011,15 @@ func (c *KMS) GenerateDataKeyRequest(input *GenerateDataKeyInput) (req *request.
// To generate a data key, specify the symmetric encryption KMS key that will
// be used to encrypt the data key. You cannot use an asymmetric KMS key to
// encrypt data keys. To get the type of your KMS key, use the DescribeKey operation.
//
// You must also specify the length of the data key. Use either the KeySpec
// or NumberOfBytes parameters (but not both). For 128-bit and 256-bit data
// keys, use the KeySpec parameter.
//
// To generate an SM4 data key (China Regions only), specify a KeySpec value
// of AES_128 or NumberOfBytes value of 128. The symmetric encryption key used
// in China Regions to encrypt your data key is an SM4 encryption key.
//
// To get only an encrypted copy of the data key, use GenerateDataKeyWithoutPlaintext.
// To generate an asymmetric data key pair, use the GenerateDataKeyPair or GenerateDataKeyPairWithoutPlaintext
// operation. To get a cryptographically secure random byte string, use GenerateRandom.
@ -3160,9 +3227,10 @@ func (c *KMS) GenerateDataKeyPairRequest(input *GenerateDataKeyPairInput) (req *
// your KMS key, use the DescribeKey operation.
//
// Use the KeyPairSpec parameter to choose an RSA or Elliptic Curve (ECC) data
// key pair. KMS recommends that your use ECC key pairs for signing, and use
// RSA key pairs for either encryption or signing, but not both. However, KMS
// cannot enforce any restrictions on the use of data key pairs outside of KMS.
// key pair. In China Regions, you can also choose an SM2 data key pair. KMS
// recommends that you use ECC key pairs for signing, and use RSA and SM2 key
// pairs for either encryption or signing, but not both. However, KMS cannot
// enforce any restrictions on the use of data key pairs outside of KMS.
//
// If you are using the data key pair to encrypt data, or for any operation
// where you don't immediately need a private key, consider using the GenerateDataKeyPairWithoutPlaintext
@ -3352,9 +3420,10 @@ func (c *KMS) GenerateDataKeyPairWithoutPlaintextRequest(input *GenerateDataKeyP
// your KMS key, use the DescribeKey operation.
//
// Use the KeyPairSpec parameter to choose an RSA or Elliptic Curve (ECC) data
// key pair. KMS recommends that your use ECC key pairs for signing, and use
// RSA key pairs for either encryption or signing, but not both. However, KMS
// cannot enforce any restrictions on the use of data key pairs outside of KMS.
// key pair. In China Regions, you can also choose an SM2 data key pair. KMS
// recommends that you use ECC key pairs for signing, and use RSA and SM2 key
// pairs for either encryption or signing, but not both. However, KMS cannot
// enforce any restrictions on the use of data key pairs outside of KMS.
//
// GenerateDataKeyPairWithoutPlaintext returns a unique data key pair for each
// request. The bytes in the key are not related to the caller or KMS key that
@ -3849,6 +3918,9 @@ func (c *KMS) GenerateRandomRequest(input *GenerateRandomInput) (req *request.Re
//
// Returns a random byte string that is cryptographically secure.
//
// You must use the NumberOfBytes parameter to specify the length of the random
// byte string. There is no default value for string length.
//
// By default, the random byte string is generated in KMS. To generate the byte
// string in the CloudHSM cluster that is associated with a custom key store
// (https://docs.aws.amazon.com/kms/latest/developerguide/custom-key-store-overview.html),
@ -3863,6 +3935,9 @@ func (c *KMS) GenerateRandomRequest(input *GenerateRandomInput) (req *request.Re
// For more information about entropy and random number generation, see Key
// Management Service Cryptographic Details (https://docs.aws.amazon.com/kms/latest/cryptographic-details/).
//
// Cross-account use: Not applicable. GenerateRandom does not use any account-specific
// resources, such as KMS keys.
//
// Required permissions: kms:GenerateRandom (https://docs.aws.amazon.com/kms/latest/developerguide/kms-api-permissions-reference.html)
// (IAM policy)
//
@ -4393,7 +4468,11 @@ func (c *KMS) GetPublicKeyRequest(input *GetPublicKeyInput) (req *request.Reques
// KMS, you benefit from the authentication, authorization, and logging that
// are part of every KMS operation. You also reduce of risk of encrypting data
// that cannot be decrypted. These features are not effective outside of KMS.
// For details, see Special Considerations for Downloading Public Keys (https://docs.aws.amazon.com/kms/latest/developerguide/download-public-key.html#download-public-key-considerations).
//
// To verify a signature outside of KMS with an SM2 public key (China Regions
// only), you must specify the distinguishing ID. By default, KMS uses 1234567812345678
// as the distinguishing ID. For more information, see Offline verification
// with SM2 key pairs (https://docs.aws.amazon.com/kms/latest/developerguide/asymmetric-key-specs.html#key-spec-sm-offline-verification).
//
// To help you use the public key safely outside of KMS, GetPublicKey returns
// important information about the public key in the response, including:
@ -5450,6 +5529,12 @@ func (c *KMS) ListResourceTagsRequest(input *ListResourceTagsInput) (req *reques
Name: opListResourceTags,
HTTPMethod: "POST",
HTTPPath: "/",
Paginator: &request.Paginator{
InputTokens: []string{"Marker"},
OutputTokens: []string{"NextMarker"},
LimitToken: "Limit",
TruncationToken: "Truncated",
},
}
if input == nil {
@ -5532,6 +5617,58 @@ func (c *KMS) ListResourceTagsWithContext(ctx aws.Context, input *ListResourceTa
return out, req.Send()
}
// ListResourceTagsPages iterates over the pages of a ListResourceTags operation,
// calling the "fn" function with the response data for each page. To stop
// iterating, return false from the fn function.
//
// See ListResourceTags method for more information on how to use this operation.
//
// Note: This operation can generate multiple requests to a service.
//
// // Example iterating over at most 3 pages of a ListResourceTags operation.
// pageNum := 0
// err := client.ListResourceTagsPages(params,
// func(page *kms.ListResourceTagsOutput, lastPage bool) bool {
// pageNum++
// fmt.Println(page)
// return pageNum <= 3
// })
//
func (c *KMS) ListResourceTagsPages(input *ListResourceTagsInput, fn func(*ListResourceTagsOutput, bool) bool) error {
return c.ListResourceTagsPagesWithContext(aws.BackgroundContext(), input, fn)
}
// ListResourceTagsPagesWithContext same as ListResourceTagsPages except
// it takes a Context and allows setting request options on the pages.
//
// The context must be non-nil and will be used for request cancellation. If
// the context is nil a panic will occur. In the future the SDK may create
// sub-contexts for http.Requests. See https://golang.org/pkg/context/
// for more information on using Contexts.
func (c *KMS) ListResourceTagsPagesWithContext(ctx aws.Context, input *ListResourceTagsInput, fn func(*ListResourceTagsOutput, bool) bool, opts ...request.Option) error {
p := request.Pagination{
NewRequest: func() (*request.Request, error) {
var inCpy *ListResourceTagsInput
if input != nil {
tmp := *input
inCpy = &tmp
}
req, _ := c.ListResourceTagsRequest(inCpy)
req.SetContext(ctx)
req.ApplyOptions(opts...)
return req, nil
},
}
for p.Next() {
if !fn(p.Page().(*ListResourceTagsOutput), !p.HasNextPage()) {
break
}
}
return p.Err()
}
const opListRetirableGrants = "ListRetirableGrants"
// ListRetirableGrantsRequest generates a "aws/request.Request" representing the
@ -5563,6 +5700,12 @@ func (c *KMS) ListRetirableGrantsRequest(input *ListRetirableGrantsInput) (req *
Name: opListRetirableGrants,
HTTPMethod: "POST",
HTTPPath: "/",
Paginator: &request.Paginator{
InputTokens: []string{"Marker"},
OutputTokens: []string{"NextMarker"},
LimitToken: "Limit",
TruncationToken: "Truncated",
},
}
if input == nil {
@ -5659,6 +5802,58 @@ func (c *KMS) ListRetirableGrantsWithContext(ctx aws.Context, input *ListRetirab
return out, req.Send()
}
// ListRetirableGrantsPages iterates over the pages of a ListRetirableGrants operation,
// calling the "fn" function with the response data for each page. To stop
// iterating, return false from the fn function.
//
// See ListRetirableGrants method for more information on how to use this operation.
//
// Note: This operation can generate multiple requests to a service.
//
// // Example iterating over at most 3 pages of a ListRetirableGrants operation.
// pageNum := 0
// err := client.ListRetirableGrantsPages(params,
// func(page *kms.ListGrantsResponse, lastPage bool) bool {
// pageNum++
// fmt.Println(page)
// return pageNum <= 3
// })
//
func (c *KMS) ListRetirableGrantsPages(input *ListRetirableGrantsInput, fn func(*ListGrantsResponse, bool) bool) error {
return c.ListRetirableGrantsPagesWithContext(aws.BackgroundContext(), input, fn)
}
// ListRetirableGrantsPagesWithContext same as ListRetirableGrantsPages except
// it takes a Context and allows setting request options on the pages.
//
// The context must be non-nil and will be used for request cancellation. If
// the context is nil a panic will occur. In the future the SDK may create
// sub-contexts for http.Requests. See https://golang.org/pkg/context/
// for more information on using Contexts.
func (c *KMS) ListRetirableGrantsPagesWithContext(ctx aws.Context, input *ListRetirableGrantsInput, fn func(*ListGrantsResponse, bool) bool, opts ...request.Option) error {
p := request.Pagination{
NewRequest: func() (*request.Request, error) {
var inCpy *ListRetirableGrantsInput
if input != nil {
tmp := *input
inCpy = &tmp
}
req, _ := c.ListRetirableGrantsRequest(inCpy)
req.SetContext(ctx)
req.ApplyOptions(opts...)
return req, nil
},
}
for p.Next() {
if !fn(p.Page().(*ListGrantsResponse), !p.HasNextPage()) {
break
}
}
return p.Err()
}
const opPutKeyPolicy = "PutKeyPolicy"
// PutKeyPolicyRequest generates a "aws/request.Request" representing the
@ -7321,7 +7516,7 @@ func (c *KMS) UpdateCustomKeyStoreRequest(input *UpdateCustomKeyStoreInput) (req
//
// If the operation succeeds, it returns a JSON object with no properties.
//
// This operation is part of the Custom Key Store feature (https://docs.aws.amazon.com/kms/latest/developerguide/custom-key-store-overview.html)
// This operation is part of the custom key store feature (https://docs.aws.amazon.com/kms/latest/developerguide/custom-key-store-overview.html)
// feature in KMS, which combines the convenience and extensive integration
// of KMS with the isolation and control of a single-tenant key store.
//
@ -7817,11 +8012,15 @@ func (c *KMS) VerifyRequest(input *VerifyInput) (req *request.Request, output *V
// You can also verify the digital signature by using the public key of the
// KMS key outside of KMS. Use the GetPublicKey operation to download the public
// key in the asymmetric KMS key and then use the public key to verify the signature
// outside of KMS. The advantage of using the Verify operation is that it is
// performed within KMS. As a result, it's easy to call, the operation is performed
// within the FIPS boundary, it is logged in CloudTrail, and you can use key
// policy and IAM policy to determine who is authorized to use the KMS key to
// verify signatures.
// outside of KMS. To verify a signature outside of KMS with an SM2 public key,
// you must specify the distinguishing ID. By default, KMS uses 1234567812345678
// as the distinguishing ID. For more information, see Offline verification
// with SM2 key pairs (https://docs.aws.amazon.com/kms/latest/developerguide/asymmetric-key-specs.html#key-spec-sm-offline-verification)
// in Key Management Service Developer Guide. The advantage of using the Verify
// operation is that it is performed within KMS. As a result, it's easy to call,
// the operation is performed within the FIPS boundary, it is logged in CloudTrail,
// and you can use key policy and IAM policy to determine who is authorized
// to use the KMS key to verify signatures.
//
// The KMS key that you use for this operation must be in a compatible key state.
// For details, see Key states of KMS keys (https://docs.aws.amazon.com/kms/latest/developerguide/key-state.html)
@ -8854,9 +9053,7 @@ type CreateCustomKeyStoreInput struct {
// ID of any active CloudHSM cluster that is not already associated with a custom
// key store. To find the cluster ID, use the DescribeClusters (https://docs.aws.amazon.com/cloudhsm/latest/APIReference/API_DescribeClusters.html)
// operation.
//
// CloudHsmClusterId is a required field
CloudHsmClusterId *string `min:"19" type:"string" required:"true"`
CloudHsmClusterId *string `min:"19" type:"string"`
// Specifies a friendly name for the custom key store. The name must be unique
// in your Amazon Web Services account.
@ -8876,16 +9073,12 @@ type CreateCustomKeyStoreInput struct {
// KeyStorePassword is a sensitive parameter and its value will be
// replaced with "sensitive" in string returned by CreateCustomKeyStoreInput's
// String and GoString methods.
//
// KeyStorePassword is a required field
KeyStorePassword *string `min:"7" type:"string" required:"true" sensitive:"true"`
KeyStorePassword *string `min:"7" type:"string" sensitive:"true"`
// Enter the content of the trust anchor certificate for the cluster. This is
// the content of the customerCA.crt file that you created when you initialized
// the cluster (https://docs.aws.amazon.com/cloudhsm/latest/userguide/initialize-cluster.html).
//
// TrustAnchorCertificate is a required field
TrustAnchorCertificate *string `min:"1" type:"string" required:"true"`
TrustAnchorCertificate *string `min:"1" type:"string"`
}
// String returns the string representation.
@ -8909,9 +9102,6 @@ func (s CreateCustomKeyStoreInput) GoString() string {
// Validate inspects the fields of the type to determine if they are valid.
func (s *CreateCustomKeyStoreInput) Validate() error {
invalidParams := request.ErrInvalidParams{Context: "CreateCustomKeyStoreInput"}
if s.CloudHsmClusterId == nil {
invalidParams.Add(request.NewErrParamRequired("CloudHsmClusterId"))
}
if s.CloudHsmClusterId != nil && len(*s.CloudHsmClusterId) < 19 {
invalidParams.Add(request.NewErrParamMinLen("CloudHsmClusterId", 19))
}
@ -8921,15 +9111,9 @@ func (s *CreateCustomKeyStoreInput) Validate() error {
if s.CustomKeyStoreName != nil && len(*s.CustomKeyStoreName) < 1 {
invalidParams.Add(request.NewErrParamMinLen("CustomKeyStoreName", 1))
}
if s.KeyStorePassword == nil {
invalidParams.Add(request.NewErrParamRequired("KeyStorePassword"))
}
if s.KeyStorePassword != nil && len(*s.KeyStorePassword) < 7 {
invalidParams.Add(request.NewErrParamMinLen("KeyStorePassword", 7))
}
if s.TrustAnchorCertificate == nil {
invalidParams.Add(request.NewErrParamRequired("TrustAnchorCertificate"))
}
if s.TrustAnchorCertificate != nil && len(*s.TrustAnchorCertificate) < 1 {
invalidParams.Add(request.NewErrParamMinLen("TrustAnchorCertificate", 1))
}
@ -9284,7 +9468,7 @@ type CreateKeyInput struct {
// The response includes the custom key store ID and the ID of the CloudHSM
// cluster.
//
// This operation is part of the Custom Key Store feature (https://docs.aws.amazon.com/kms/latest/developerguide/custom-key-store-overview.html)
// This operation is part of the custom key store feature (https://docs.aws.amazon.com/kms/latest/developerguide/custom-key-store-overview.html)
// feature in KMS, which combines the convenience and extensive integration
// of KMS with the isolation and control of a single-tenant key store.
CustomKeyStoreId *string `min:"1" type:"string"`
@ -9307,9 +9491,10 @@ type CreateKeyInput struct {
Description *string `type:"string"`
// Specifies the type of KMS key to create. The default value, SYMMETRIC_DEFAULT,
// creates a KMS key with a 256-bit symmetric key for encryption and decryption.
// For help choosing a key spec for your KMS key, see Choosing a KMS key type
// (https://docs.aws.amazon.com/kms/latest/developerguide/key-types.html#symm-asymm-choose)
// creates a KMS key with a 256-bit AES-GCM key that is used for encryption
// and decryption, except in China Regions, where it creates a 128-bit symmetric
// key that uses SM4 encryption. For help choosing a key spec for your KMS key,
// see Choosing a KMS key type (https://docs.aws.amazon.com/kms/latest/developerguide/key-types.html#symm-asymm-choose)
// in the Key Management Service Developer Guide .
//
// The KeySpec determines whether the KMS key contains a symmetric key or an
@ -9328,7 +9513,7 @@ type CreateKeyInput struct {
//
// KMS supports the following key specs for KMS keys:
//
// * Symmetric encryption key (default) SYMMETRIC_DEFAULT (AES-256-GCM)
// * Symmetric encryption key (default) SYMMETRIC_DEFAULT
//
// * HMAC keys (symmetric) HMAC_224 HMAC_256 HMAC_384 HMAC_512
//
@ -9339,6 +9524,8 @@ type CreateKeyInput struct {
//
// * Other asymmetric elliptic curve key pairs ECC_SECG_P256K1 (secp256k1),
// commonly used for cryptocurrencies.
//
// * SM2 key pairs (China Regions only) SM2
KeySpec *string `type:"string" enum:"KeySpec"`
// Determines the cryptographic operations (https://docs.aws.amazon.com/kms/latest/developerguide/concepts.html#cryptographic-operations)
@ -9357,6 +9544,9 @@ type CreateKeyInput struct {
// or SIGN_VERIFY.
//
// * For asymmetric KMS keys with ECC key material, specify SIGN_VERIFY.
//
// * For asymmetric KMS keys with SM2 key material (China Regions only),
// specify ENCRYPT_DECRYPT or SIGN_VERIFY.
KeyUsage *string `type:"string" enum:"KeyUsageType"`
// Creates a multi-Region primary key that you can replicate into other Amazon
@ -9423,21 +9613,20 @@ type CreateKeyInput struct {
// visible (https://docs.aws.amazon.com/IAM/latest/UserGuide/troubleshoot_general.html#troubleshoot_general_eventual-consistency)
// in the Amazon Web Services Identity and Access Management User Guide.
//
// A key policy document must conform to the following rules.
// A key policy document can include only the following characters:
//
// * Up to 32 kilobytes (32768 bytes)
// * Printable ASCII characters from the space character (\u0020) through
// the end of the ASCII character range.
//
// * Must be UTF-8 encoded
// * Printable characters in the Basic Latin and Latin-1 Supplement character
// set (through \u00FF).
//
// * The only Unicode characters that are permitted in a key policy document
// are the horizontal tab (U+0009), linefeed (U+000A), carriage return (U+000D),
// and characters in the range U+0020 to U+00FF.
// * The tab (\u0009), line feed (\u000A), and carriage return (\u000D) special
// characters
//
// * The Sid element in a key policy statement can include spaces. (Spaces
// are prohibited in the Sid element of an IAM policy document.)
//
// For help writing and formatting a JSON policy document, see the IAM JSON
// Policy Reference (https://docs.aws.amazon.com/IAM/latest/UserGuide/reference_policies.html)
// For information about key policies, see Key policies in KMS (https://docs.aws.amazon.com/kms/latest/developerguide/key-policies.html)
// in the Key Management Service Developer Guide. For help writing and formatting
// a JSON policy document, see the IAM JSON Policy Reference (https://docs.aws.amazon.com/IAM/latest/UserGuide/reference_policies.html)
// in the Identity and Access Management User Guide .
Policy *string `min:"1" type:"string"`
@ -11777,10 +11966,12 @@ type GenerateDataKeyPairInput struct {
// Determines the type of data key pair that is generated.
//
// The KMS rule that restricts the use of asymmetric RSA KMS keys to encrypt
// and decrypt or to sign and verify (but not both), and the rule that permits
// you to use ECC KMS keys only to sign and verify, are not effective on data
// key pairs, which are used outside of KMS.
// The KMS rule that restricts the use of asymmetric RSA and SM2 KMS keys to
// encrypt and decrypt or to sign and verify (but not both), and the rule that
// permits you to use ECC KMS keys only to sign and verify, are not effective
// on data key pairs, which are used outside of KMS. The SM2 key spec is only
// available in China Regions. RSA and ECC asymmetric key pairs are also available
// in China Regions.
//
// KeyPairSpec is a required field
KeyPairSpec *string `type:"string" required:"true" enum:"DataKeyPairSpec"`
@ -11981,10 +12172,12 @@ type GenerateDataKeyPairWithoutPlaintextInput struct {
// Determines the type of data key pair that is generated.
//
// The KMS rule that restricts the use of asymmetric RSA KMS keys to encrypt
// and decrypt or to sign and verify (but not both), and the rule that permits
// you to use ECC KMS keys only to sign and verify, are not effective on data
// key pairs, which are used outside of KMS.
// The KMS rule that restricts the use of asymmetric RSA and SM2 KMS keys to
// encrypt and decrypt or to sign and verify (but not both), and the rule that
// permits you to use ECC KMS keys only to sign and verify, are not effective
// on data key pairs, which are used outside of KMS. The SM2 key spec is only
// available in China Regions. RSA and ECC asymmetric key pairs are also available
// in China Regions.
//
// KeyPairSpec is a required field
KeyPairSpec *string `type:"string" required:"true" enum:"DataKeyPairSpec"`
@ -12459,7 +12652,7 @@ type GenerateRandomInput struct {
// To find the ID of a custom key store, use the DescribeCustomKeyStores operation.
CustomKeyStoreId *string `min:"1" type:"string"`
// The length of the byte string.
// The length of the random byte string. This parameter is required.
NumberOfBytes *int64 `min:"1" type:"integer"`
}
@ -16010,18 +16203,21 @@ type PutKeyPolicyInput struct {
// visible (https://docs.aws.amazon.com/IAM/latest/UserGuide/troubleshoot_general.html#troubleshoot_general_eventual-consistency)
// in the Amazon Web Services Identity and Access Management User Guide.
//
// A key policy document must conform to the following rules.
// A key policy document can include only the following characters:
//
// * Up to 32 kilobytes (32768 bytes)
// * Printable ASCII characters from the space character (\u0020) through
// the end of the ASCII character range.
//
// * Must be UTF-8 encoded
// * Printable characters in the Basic Latin and Latin-1 Supplement character
// set (through \u00FF).
//
// * The only Unicode characters that are permitted in a key policy document
// are the horizontal tab (U+0009), linefeed (U+000A), carriage return (U+000D),
// and characters in the range U+0020 to U+00FF.
// * The tab (\u0009), line feed (\u000A), and carriage return (\u000D) special
// characters
//
// * The Sid element in a key policy statement can include spaces. (Spaces
// are prohibited in the Sid element of an IAM policy document.)
// For information about key policies, see Key policies in KMS (https://docs.aws.amazon.com/kms/latest/developerguide/key-policies.html)
// in the Key Management Service Developer Guide. For help writing and formatting
// a JSON policy document, see the IAM JSON Policy Reference (https://docs.aws.amazon.com/IAM/latest/UserGuide/reference_policies.html)
// in the Identity and Access Management User Guide .
//
// Policy is a required field
Policy *string `min:"1" type:"string" required:"true"`
@ -16481,18 +16677,21 @@ type ReplicateKeyInput struct {
// visible (https://docs.aws.amazon.com/IAM/latest/UserGuide/troubleshoot_general.html#troubleshoot_general_eventual-consistency)
// in the Identity and Access Management User Guide .
//
// A key policy document must conform to the following rules.
// A key policy document can include only the following characters:
//
// * Up to 32 kilobytes (32768 bytes)
// * Printable ASCII characters from the space character (\u0020) through
// the end of the ASCII character range.
//
// * Must be UTF-8 encoded
// * Printable characters in the Basic Latin and Latin-1 Supplement character
// set (through \u00FF).
//
// * The only Unicode characters that are permitted in a key policy document
// are the horizontal tab (U+0009), linefeed (U+000A), carriage return (U+000D),
// and characters in the range U+0020 to U+00FF.
// * The tab (\u0009), line feed (\u000A), and carriage return (\u000D) special
// characters
//
// * The Sid element in a key policy statement can include spaces. (Spaces
// are prohibited in the Sid element of an IAM policy document.)
// For information about key policies, see Key policies in KMS (https://docs.aws.amazon.com/kms/latest/developerguide/key-policies.html)
// in the Key Management Service Developer Guide. For help writing and formatting
// a JSON policy document, see the IAM JSON Policy Reference (https://docs.aws.amazon.com/IAM/latest/UserGuide/reference_policies.html)
// in the Identity and Access Management User Guide .
Policy *string `min:"1" type:"string"`
// The Region ID of the Amazon Web Services Region for this replica key.
@ -18538,6 +18737,9 @@ const (
// ConnectionErrorCodeTypeSubnetNotFound is a ConnectionErrorCodeType enum value
ConnectionErrorCodeTypeSubnetNotFound = "SUBNET_NOT_FOUND"
// ConnectionErrorCodeTypeInsufficientFreeAddressesInSubnet is a ConnectionErrorCodeType enum value
ConnectionErrorCodeTypeInsufficientFreeAddressesInSubnet = "INSUFFICIENT_FREE_ADDRESSES_IN_SUBNET"
)
// ConnectionErrorCodeType_Values returns all elements of the ConnectionErrorCodeType enum
@ -18552,6 +18754,7 @@ func ConnectionErrorCodeType_Values() []string {
ConnectionErrorCodeTypeUserNotFound,
ConnectionErrorCodeTypeUserLoggedIn,
ConnectionErrorCodeTypeSubnetNotFound,
ConnectionErrorCodeTypeInsufficientFreeAddressesInSubnet,
}
}
@ -18619,6 +18822,9 @@ const (
// CustomerMasterKeySpecHmac512 is a CustomerMasterKeySpec enum value
CustomerMasterKeySpecHmac512 = "HMAC_512"
// CustomerMasterKeySpecSm2 is a CustomerMasterKeySpec enum value
CustomerMasterKeySpecSm2 = "SM2"
)
// CustomerMasterKeySpec_Values returns all elements of the CustomerMasterKeySpec enum
@ -18636,6 +18842,7 @@ func CustomerMasterKeySpec_Values() []string {
CustomerMasterKeySpecHmac256,
CustomerMasterKeySpecHmac384,
CustomerMasterKeySpecHmac512,
CustomerMasterKeySpecSm2,
}
}
@ -18660,6 +18867,9 @@ const (
// DataKeyPairSpecEccSecgP256k1 is a DataKeyPairSpec enum value
DataKeyPairSpecEccSecgP256k1 = "ECC_SECG_P256K1"
// DataKeyPairSpecSm2 is a DataKeyPairSpec enum value
DataKeyPairSpecSm2 = "SM2"
)
// DataKeyPairSpec_Values returns all elements of the DataKeyPairSpec enum
@ -18672,6 +18882,7 @@ func DataKeyPairSpec_Values() []string {
DataKeyPairSpecEccNistP384,
DataKeyPairSpecEccNistP521,
DataKeyPairSpecEccSecgP256k1,
DataKeyPairSpecSm2,
}
}
@ -18700,6 +18911,9 @@ const (
// EncryptionAlgorithmSpecRsaesOaepSha256 is a EncryptionAlgorithmSpec enum value
EncryptionAlgorithmSpecRsaesOaepSha256 = "RSAES_OAEP_SHA_256"
// EncryptionAlgorithmSpecSm2pke is a EncryptionAlgorithmSpec enum value
EncryptionAlgorithmSpecSm2pke = "SM2PKE"
)
// EncryptionAlgorithmSpec_Values returns all elements of the EncryptionAlgorithmSpec enum
@ -18708,6 +18922,7 @@ func EncryptionAlgorithmSpec_Values() []string {
EncryptionAlgorithmSpecSymmetricDefault,
EncryptionAlgorithmSpecRsaesOaepSha1,
EncryptionAlgorithmSpecRsaesOaepSha256,
EncryptionAlgorithmSpecSm2pke,
}
}
@ -18851,6 +19066,9 @@ const (
// KeySpecHmac512 is a KeySpec enum value
KeySpecHmac512 = "HMAC_512"
// KeySpecSm2 is a KeySpec enum value
KeySpecSm2 = "SM2"
)
// KeySpec_Values returns all elements of the KeySpec enum
@ -18868,6 +19086,7 @@ func KeySpec_Values() []string {
KeySpecHmac256,
KeySpecHmac384,
KeySpecHmac512,
KeySpecSm2,
}
}
@ -19034,6 +19253,9 @@ const (
// SigningAlgorithmSpecEcdsaSha512 is a SigningAlgorithmSpec enum value
SigningAlgorithmSpecEcdsaSha512 = "ECDSA_SHA_512"
// SigningAlgorithmSpecSm2dsa is a SigningAlgorithmSpec enum value
SigningAlgorithmSpecSm2dsa = "SM2DSA"
)
// SigningAlgorithmSpec_Values returns all elements of the SigningAlgorithmSpec enum
@ -19048,6 +19270,7 @@ func SigningAlgorithmSpec_Values() []string {
SigningAlgorithmSpecEcdsaSha256,
SigningAlgorithmSpecEcdsaSha384,
SigningAlgorithmSpecEcdsaSha512,
SigningAlgorithmSpecSm2dsa,
}
}

View File

@ -105,14 +105,18 @@ with higher verbosity means more (and less important) logs will be generated.
There are implementations for the following logging libraries:
- **a function** (can bridge to non-structured libraries): [funcr](https://github.com/go-logr/logr/tree/master/funcr)
- **a testing.T** (for use in Go tests, with JSON-like output): [testr](https://github.com/go-logr/logr/tree/master/testr)
- **github.com/google/glog**: [glogr](https://github.com/go-logr/glogr)
- **k8s.io/klog** (for Kubernetes): [klogr](https://git.k8s.io/klog/klogr)
- **a testing.T** (with klog-like text output): [ktesting](https://git.k8s.io/klog/ktesting)
- **go.uber.org/zap**: [zapr](https://github.com/go-logr/zapr)
- **log** (the Go standard library logger): [stdr](https://github.com/go-logr/stdr)
- **github.com/sirupsen/logrus**: [logrusr](https://github.com/bombsimon/logrusr)
- **github.com/wojas/genericr**: [genericr](https://github.com/wojas/genericr) (makes it easy to implement your own backend)
- **logfmt** (Heroku style [logging](https://www.brandur.org/logfmt)): [logfmtr](https://github.com/iand/logfmtr)
- **github.com/rs/zerolog**: [zerologr](https://github.com/go-logr/zerologr)
- **github.com/go-kit/log**: [gokitlogr](https://github.com/tonglil/gokitlogr) (also compatible with github.com/go-kit/kit/log since v0.12.0)
- **bytes.Buffer** (writing to a buffer): [bufrlogr](https://github.com/tonglil/buflogr) (useful for ensuring values were logged, like during testing)
## FAQ

View File

@ -43,7 +43,9 @@ limitations under the License.
//
// Info() and Error() are very similar, but they are separate methods so that
// LogSink implementations can choose to do things like attach additional
// information (such as stack traces) on calls to Error().
// information (such as stack traces) on calls to Error(). Error() messages are
// always logged, regardless of the current verbosity. If there is no error
// instance available, passing nil is valid.
//
// Verbosity
//
@ -53,6 +55,7 @@ limitations under the License.
// Log-lines with V-levels that are not enabled (as per the LogSink) will not
// be written. Level V(0) is the default, and logger.V(0).Info() has the same
// meaning as logger.Info(). Negative V-levels have the same meaning as V(0).
// Error messages do not have a verbosity level and are always logged.
//
// Where we might have written:
// if flVerbose >= 2 {
@ -112,6 +115,15 @@ limitations under the License.
// may be any Go value, but how the value is formatted is determined by the
// LogSink implementation.
//
// Logger instances are meant to be passed around by value. Code that receives
// such a value can call its methods without having to check whether the
// instance is ready for use.
//
// Calling methods with the null logger (Logger{}) as instance will crash
// because it has no LogSink. Therefore this null logger should never be passed
// around. For cases where passing a logger is optional, a pointer to Logger
// should be used.
//
// Key Naming Conventions
//
// Keys are not strictly required to conform to any specification or regex, but
@ -253,11 +265,13 @@ func (l Logger) Info(msg string, keysAndValues ...interface{}) {
// Error logs an error, with the given message and key/value pairs as context.
// It functions similarly to Info, but may have unique behavior, and should be
// preferred for logging errors (see the package documentations for more
// information).
// information). The log message will always be emitted, regardless of
// verbosity level.
//
// The msg argument should be used to add context to any underlying error,
// while the err argument should be used to attach the actual error that
// triggered this log line, if present.
// triggered this log line, if present. The err parameter is optional
// and nil may be passed instead of an error instance.
func (l Logger) Error(err error, msg string, keysAndValues ...interface{}) {
if withHelper, ok := l.sink.(CallStackHelperLogSink); ok {
withHelper.GetCallStackHelper()()

202
vendor/github.com/moby/sys/mountinfo/LICENSE generated vendored Normal file
View File

@ -0,0 +1,202 @@
Apache License
Version 2.0, January 2004
http://www.apache.org/licenses/
TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
1. Definitions.
"License" shall mean the terms and conditions for use, reproduction,
and distribution as defined by Sections 1 through 9 of this document.
"Licensor" shall mean the copyright owner or entity authorized by
the copyright owner that is granting the License.
"Legal Entity" shall mean the union of the acting entity and all
other entities that control, are controlled by, or are under common
control with that entity. For the purposes of this definition,
"control" means (i) the power, direct or indirect, to cause the
direction or management of such entity, whether by contract or
otherwise, or (ii) ownership of fifty percent (50%) or more of the
outstanding shares, or (iii) beneficial ownership of such entity.
"You" (or "Your") shall mean an individual or Legal Entity
exercising permissions granted by this License.
"Source" form shall mean the preferred form for making modifications,
including but not limited to software source code, documentation
source, and configuration files.
"Object" form shall mean any form resulting from mechanical
transformation or translation of a Source form, including but
not limited to compiled object code, generated documentation,
and conversions to other media types.
"Work" shall mean the work of authorship, whether in Source or
Object form, made available under the License, as indicated by a
copyright notice that is included in or attached to the work
(an example is provided in the Appendix below).
"Derivative Works" shall mean any work, whether in Source or Object
form, that is based on (or derived from) the Work and for which the
editorial revisions, annotations, elaborations, or other modifications
represent, as a whole, an original work of authorship. For the purposes
of this License, Derivative Works shall not include works that remain
separable from, or merely link (or bind by name) to the interfaces of,
the Work and Derivative Works thereof.
"Contribution" shall mean any work of authorship, including
the original version of the Work and any modifications or additions
to that Work or Derivative Works thereof, that is intentionally
submitted to Licensor for inclusion in the Work by the copyright owner
or by an individual or Legal Entity authorized to submit on behalf of
the copyright owner. For the purposes of this definition, "submitted"
means any form of electronic, verbal, or written communication sent
to the Licensor or its representatives, including but not limited to
communication on electronic mailing lists, source code control systems,
and issue tracking systems that are managed by, or on behalf of, the
Licensor for the purpose of discussing and improving the Work, but
excluding communication that is conspicuously marked or otherwise
designated in writing by the copyright owner as "Not a Contribution."
"Contributor" shall mean Licensor and any individual or Legal Entity
on behalf of whom a Contribution has been received by Licensor and
subsequently incorporated within the Work.
2. Grant of Copyright License. Subject to the terms and conditions of
this License, each Contributor hereby grants to You a perpetual,
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
copyright license to reproduce, prepare Derivative Works of,
publicly display, publicly perform, sublicense, and distribute the
Work and such Derivative Works in Source or Object form.
3. Grant of Patent License. Subject to the terms and conditions of
this License, each Contributor hereby grants to You a perpetual,
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
(except as stated in this section) patent license to make, have made,
use, offer to sell, sell, import, and otherwise transfer the Work,
where such license applies only to those patent claims licensable
by such Contributor that are necessarily infringed by their
Contribution(s) alone or by combination of their Contribution(s)
with the Work to which such Contribution(s) was submitted. If You
institute patent litigation against any entity (including a
cross-claim or counterclaim in a lawsuit) alleging that the Work
or a Contribution incorporated within the Work constitutes direct
or contributory patent infringement, then any patent licenses
granted to You under this License for that Work shall terminate
as of the date such litigation is filed.
4. Redistribution. You may reproduce and distribute copies of the
Work or Derivative Works thereof in any medium, with or without
modifications, and in Source or Object form, provided that You
meet the following conditions:
(a) You must give any other recipients of the Work or
Derivative Works a copy of this License; and
(b) You must cause any modified files to carry prominent notices
stating that You changed the files; and
(c) You must retain, in the Source form of any Derivative Works
that You distribute, all copyright, patent, trademark, and
attribution notices from the Source form of the Work,
excluding those notices that do not pertain to any part of
the Derivative Works; and
(d) If the Work includes a "NOTICE" text file as part of its
distribution, then any Derivative Works that You distribute must
include a readable copy of the attribution notices contained
within such NOTICE file, excluding those notices that do not
pertain to any part of the Derivative Works, in at least one
of the following places: within a NOTICE text file distributed
as part of the Derivative Works; within the Source form or
documentation, if provided along with the Derivative Works; or,
within a display generated by the Derivative Works, if and
wherever such third-party notices normally appear. The contents
of the NOTICE file are for informational purposes only and
do not modify the License. You may add Your own attribution
notices within Derivative Works that You distribute, alongside
or as an addendum to the NOTICE text from the Work, provided
that such additional attribution notices cannot be construed
as modifying the License.
You may add Your own copyright statement to Your modifications and
may provide additional or different license terms and conditions
for use, reproduction, or distribution of Your modifications, or
for any such Derivative Works as a whole, provided Your use,
reproduction, and distribution of the Work otherwise complies with
the conditions stated in this License.
5. Submission of Contributions. Unless You explicitly state otherwise,
any Contribution intentionally submitted for inclusion in the Work
by You to the Licensor shall be under the terms and conditions of
this License, without any additional terms or conditions.
Notwithstanding the above, nothing herein shall supersede or modify
the terms of any separate license agreement you may have executed
with Licensor regarding such Contributions.
6. Trademarks. This License does not grant permission to use the trade
names, trademarks, service marks, or product names of the Licensor,
except as required for reasonable and customary use in describing the
origin of the Work and reproducing the content of the NOTICE file.
7. Disclaimer of Warranty. Unless required by applicable law or
agreed to in writing, Licensor provides the Work (and each
Contributor provides its Contributions) on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
implied, including, without limitation, any warranties or conditions
of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
PARTICULAR PURPOSE. You are solely responsible for determining the
appropriateness of using or redistributing the Work and assume any
risks associated with Your exercise of permissions under this License.
8. Limitation of Liability. In no event and under no legal theory,
whether in tort (including negligence), contract, or otherwise,
unless required by applicable law (such as deliberate and grossly
negligent acts) or agreed to in writing, shall any Contributor be
liable to You for damages, including any direct, indirect, special,
incidental, or consequential damages of any character arising as a
result of this License or out of the use or inability to use the
Work (including but not limited to damages for loss of goodwill,
work stoppage, computer failure or malfunction, or any and all
other commercial damages or losses), even if such Contributor
has been advised of the possibility of such damages.
9. Accepting Warranty or Additional Liability. While redistributing
the Work or Derivative Works thereof, You may choose to offer,
and charge a fee for, acceptance of support, warranty, indemnity,
or other liability obligations and/or rights consistent with this
License. However, in accepting such obligations, You may act only
on Your own behalf and on Your sole responsibility, not on behalf
of any other Contributor, and only if You agree to indemnify,
defend, and hold each Contributor harmless for any liability
incurred by, or claims asserted against, such Contributor by reason
of your accepting any such warranty or additional liability.
END OF TERMS AND CONDITIONS
APPENDIX: How to apply the Apache License to your work.
To apply the Apache License to your work, attach the following
boilerplate notice, with the fields enclosed by brackets "[]"
replaced with your own identifying information. (Don't include
the brackets!) The text should be enclosed in the appropriate
comment syntax for the file format. We also recommend that a
file or class name and description of purpose be included on the
same "printed page" as the copyright notice for easier
identification within third-party archives.
Copyright [yyyy] [name of copyright owner]
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.

44
vendor/github.com/moby/sys/mountinfo/doc.go generated vendored Normal file
View File

@ -0,0 +1,44 @@
// Package mountinfo provides a set of functions to retrieve information about OS mounts.
//
// Currently it supports Linux. For historical reasons, there is also some support for FreeBSD and OpenBSD,
// and a shallow implementation for Windows, but in general this is Linux-only package, so
// the rest of the document only applies to Linux, unless explicitly specified otherwise.
//
// In Linux, information about mounts seen by the current process is available from
// /proc/self/mountinfo. Note that due to mount namespaces, different processes can
// see different mounts. A per-process mountinfo table is available from /proc/<PID>/mountinfo,
// where <PID> is a numerical process identifier.
//
// In general, /proc is not a very efficient interface, and mountinfo is not an exception.
// For example, there is no way to get information about a specific mount point (i.e. it
// is all-or-nothing). This package tries to hide the /proc ineffectiveness by using
// parse filters while reading mountinfo. A filter can skip some entries, or stop
// processing the rest of the file once the needed information is found.
//
// For mountinfo filters that accept path as an argument, the path must be absolute,
// having all symlinks resolved, and being cleaned (i.e. no extra slashes or dots).
// One way to achieve all of the above is to employ filepath.Abs followed by
// filepath.EvalSymlinks (the latter calls filepath.Clean on the result so
// there is no need to explicitly call filepath.Clean).
//
// NOTE that in many cases there is no need to consult mountinfo at all. Here are some
// of the cases where mountinfo should not be parsed:
//
// 1. Before performing a mount. Usually, this is not needed, but if required (say to
// prevent over-mounts), to check whether a directory is mounted, call os.Lstat
// on it and its parent directory, and compare their st.Sys().(*syscall.Stat_t).Dev
// fields -- if they differ, then the directory is the mount point. NOTE this does
// not work for bind mounts. Optionally, the filesystem type can also be checked
// by calling unix.Statfs and checking the Type field (i.e. filesystem type).
//
// 2. After performing a mount. If there is no error returned, the mount succeeded;
// checking the mount table for a new mount is redundant and expensive.
//
// 3. Before performing an unmount. It is more efficient to do an unmount and ignore
// a specific error (EINVAL) which tells the directory is not mounted.
//
// 4. After performing an unmount. If there is no error returned, the unmount succeeded.
//
// 5. To find the mount point root of a specific directory. You can perform os.Stat()
// on the directory and traverse up until the Dev field of a parent directory differs.
package mountinfo

101
vendor/github.com/moby/sys/mountinfo/mounted_linux.go generated vendored Normal file
View File

@ -0,0 +1,101 @@
package mountinfo
import (
"os"
"path/filepath"
"golang.org/x/sys/unix"
)
// MountedFast is a method of detecting a mount point without reading
// mountinfo from procfs. A caller can only trust the result if no error
// and sure == true are returned. Otherwise, other methods (e.g. parsing
// /proc/mounts) have to be used. If unsure, use Mounted instead (which
// uses MountedFast, but falls back to parsing mountinfo if needed).
//
// If a non-existent path is specified, an appropriate error is returned.
// In case the caller is not interested in this particular error, it should
// be handled separately using e.g. errors.Is(err, os.ErrNotExist).
//
// This function is only available on Linux. When available (since kernel
// v5.6), openat2(2) syscall is used to reliably detect all mounts. Otherwise,
// the implementation falls back to using stat(2), which can reliably detect
// normal (but not bind) mounts.
func MountedFast(path string) (mounted, sure bool, err error) {
// Root is always mounted.
if path == string(os.PathSeparator) {
return true, true, nil
}
path, err = normalizePath(path)
if err != nil {
return false, false, err
}
mounted, sure, err = mountedFast(path)
return
}
// mountedByOpenat2 is a method of detecting a mount that works for all kinds
// of mounts (incl. bind mounts), but requires a recent (v5.6+) linux kernel.
func mountedByOpenat2(path string) (bool, error) {
dir, last := filepath.Split(path)
dirfd, err := unix.Openat2(unix.AT_FDCWD, dir, &unix.OpenHow{
Flags: unix.O_PATH | unix.O_CLOEXEC,
})
if err != nil {
return false, &os.PathError{Op: "openat2", Path: dir, Err: err}
}
fd, err := unix.Openat2(dirfd, last, &unix.OpenHow{
Flags: unix.O_PATH | unix.O_CLOEXEC | unix.O_NOFOLLOW,
Resolve: unix.RESOLVE_NO_XDEV,
})
_ = unix.Close(dirfd)
switch err { //nolint:errorlint // unix errors are bare
case nil: // definitely not a mount
_ = unix.Close(fd)
return false, nil
case unix.EXDEV: // definitely a mount
return true, nil
}
// not sure
return false, &os.PathError{Op: "openat2", Path: path, Err: err}
}
// mountedFast is similar to MountedFast, except it expects a normalized path.
func mountedFast(path string) (mounted, sure bool, err error) {
// Root is always mounted.
if path == string(os.PathSeparator) {
return true, true, nil
}
// Try a fast path, using openat2() with RESOLVE_NO_XDEV.
mounted, err = mountedByOpenat2(path)
if err == nil {
return mounted, true, nil
}
// Another fast path: compare st.st_dev fields.
mounted, err = mountedByStat(path)
// This does not work for bind mounts, so false negative
// is possible, therefore only trust if return is true.
if mounted && err == nil {
return true, true, nil
}
return
}
func mounted(path string) (bool, error) {
path, err := normalizePath(path)
if err != nil {
return false, err
}
mounted, sure, err := mountedFast(path)
if sure && err == nil {
return mounted, nil
}
// Fallback to parsing mountinfo.
return mountedByMountinfo(path)
}

54
vendor/github.com/moby/sys/mountinfo/mounted_unix.go generated vendored Normal file
View File

@ -0,0 +1,54 @@
//go:build linux || (freebsd && cgo) || (openbsd && cgo) || (darwin && cgo)
// +build linux freebsd,cgo openbsd,cgo darwin,cgo
package mountinfo
import (
"fmt"
"os"
"path/filepath"
"golang.org/x/sys/unix"
)
func mountedByStat(path string) (bool, error) {
var st unix.Stat_t
if err := unix.Lstat(path, &st); err != nil {
return false, &os.PathError{Op: "stat", Path: path, Err: err}
}
dev := st.Dev
parent := filepath.Dir(path)
if err := unix.Lstat(parent, &st); err != nil {
return false, &os.PathError{Op: "stat", Path: parent, Err: err}
}
if dev != st.Dev {
// Device differs from that of parent,
// so definitely a mount point.
return true, nil
}
// NB: this does not detect bind mounts on Linux.
return false, nil
}
func normalizePath(path string) (realPath string, err error) {
if realPath, err = filepath.Abs(path); err != nil {
return "", fmt.Errorf("unable to get absolute path for %q: %w", path, err)
}
if realPath, err = filepath.EvalSymlinks(realPath); err != nil {
return "", fmt.Errorf("failed to canonicalise path for %q: %w", path, err)
}
if _, err := os.Stat(realPath); err != nil {
return "", fmt.Errorf("failed to stat target of %q: %w", path, err)
}
return realPath, nil
}
func mountedByMountinfo(path string) (bool, error) {
entries, err := GetMounts(SingleEntryFilter(path))
if err != nil {
return false, err
}
return len(entries) > 0, nil
}

67
vendor/github.com/moby/sys/mountinfo/mountinfo.go generated vendored Normal file
View File

@ -0,0 +1,67 @@
package mountinfo
import (
"os"
)
// GetMounts retrieves a list of mounts for the current running process,
// with an optional filter applied (use nil for no filter).
func GetMounts(f FilterFunc) ([]*Info, error) {
return parseMountTable(f)
}
// Mounted determines if a specified path is a mount point. In case of any
// error, false (and an error) is returned.
//
// If a non-existent path is specified, an appropriate error is returned.
// In case the caller is not interested in this particular error, it should
// be handled separately using e.g. errors.Is(err, os.ErrNotExist).
func Mounted(path string) (bool, error) {
// root is always mounted
if path == string(os.PathSeparator) {
return true, nil
}
return mounted(path)
}
// Info reveals information about a particular mounted filesystem. This
// struct is populated from the content in the /proc/<pid>/mountinfo file.
type Info struct {
// ID is a unique identifier of the mount (may be reused after umount).
ID int
// Parent is the ID of the parent mount (or of self for the root
// of this mount namespace's mount tree).
Parent int
// Major and Minor are the major and the minor components of the Dev
// field of unix.Stat_t structure returned by unix.*Stat calls for
// files on this filesystem.
Major, Minor int
// Root is the pathname of the directory in the filesystem which forms
// the root of this mount.
Root string
// Mountpoint is the pathname of the mount point relative to the
// process's root directory.
Mountpoint string
// Options is a comma-separated list of mount options.
Options string
// Optional are zero or more fields of the form "tag[:value]",
// separated by a space. Currently, the possible optional fields are
// "shared", "master", "propagate_from", and "unbindable". For more
// information, see mount_namespaces(7) Linux man page.
Optional string
// FSType is the filesystem type in the form "type[.subtype]".
FSType string
// Source is filesystem-specific information, or "none".
Source string
// VFSOptions is a comma-separated list of superblock options.
VFSOptions string
}

72
vendor/github.com/moby/sys/mountinfo/mountinfo_bsd.go generated vendored Normal file
View File

@ -0,0 +1,72 @@
//go:build (freebsd && cgo) || (openbsd && cgo) || (darwin && cgo)
// +build freebsd,cgo openbsd,cgo darwin,cgo
package mountinfo
/*
#include <sys/param.h>
#include <sys/ucred.h>
#include <sys/mount.h>
*/
import "C"
import (
"fmt"
"reflect"
"unsafe"
)
// parseMountTable returns information about mounted filesystems
func parseMountTable(filter FilterFunc) ([]*Info, error) {
var rawEntries *C.struct_statfs
count := int(C.getmntinfo(&rawEntries, C.MNT_WAIT))
if count == 0 {
return nil, fmt.Errorf("failed to call getmntinfo")
}
var entries []C.struct_statfs
header := (*reflect.SliceHeader)(unsafe.Pointer(&entries))
header.Cap = count
header.Len = count
header.Data = uintptr(unsafe.Pointer(rawEntries))
var out []*Info
for _, entry := range entries {
var mountinfo Info
var skip, stop bool
mountinfo.Mountpoint = C.GoString(&entry.f_mntonname[0])
mountinfo.FSType = C.GoString(&entry.f_fstypename[0])
mountinfo.Source = C.GoString(&entry.f_mntfromname[0])
if filter != nil {
// filter out entries we're not interested in
skip, stop = filter(&mountinfo)
if skip {
continue
}
}
out = append(out, &mountinfo)
if stop {
break
}
}
return out, nil
}
func mounted(path string) (bool, error) {
path, err := normalizePath(path)
if err != nil {
return false, err
}
// Fast path: compare st.st_dev fields.
// This should always work for FreeBSD and OpenBSD.
mounted, err := mountedByStat(path)
if err == nil {
return mounted, nil
}
// Fallback to parsing mountinfo
return mountedByMountinfo(path)
}

View File

@ -0,0 +1,63 @@
package mountinfo
import "strings"
// FilterFunc is a type defining a callback function for GetMount(),
// used to filter out mountinfo entries we're not interested in,
// and/or stop further processing if we found what we wanted.
//
// It takes a pointer to the Info struct (fully populated with all available
// fields on the GOOS platform), and returns two booleans:
//
// skip: true if the entry should be skipped;
//
// stop: true if parsing should be stopped after the entry.
type FilterFunc func(*Info) (skip, stop bool)
// PrefixFilter discards all entries whose mount points do not start with, or
// are equal to the path specified in prefix. The prefix path must be absolute,
// have all symlinks resolved, and cleaned (i.e. no extra slashes or dots).
//
// PrefixFilter treats prefix as a path, not a partial prefix, which means that
// given "/foo", "/foo/bar" and "/foobar" entries, PrefixFilter("/foo") returns
// "/foo" and "/foo/bar", and discards "/foobar".
func PrefixFilter(prefix string) FilterFunc {
return func(m *Info) (bool, bool) {
skip := !strings.HasPrefix(m.Mountpoint+"/", prefix+"/")
return skip, false
}
}
// SingleEntryFilter looks for a specific entry.
func SingleEntryFilter(mp string) FilterFunc {
return func(m *Info) (bool, bool) {
if m.Mountpoint == mp {
return false, true // don't skip, stop now
}
return true, false // skip, keep going
}
}
// ParentsFilter returns all entries whose mount points
// can be parents of a path specified, discarding others.
//
// For example, given /var/lib/docker/something, entries
// like /var/lib/docker, /var and / are returned.
func ParentsFilter(path string) FilterFunc {
return func(m *Info) (bool, bool) {
skip := !strings.HasPrefix(path, m.Mountpoint)
return skip, false
}
}
// FSTypeFilter returns all entries that match provided fstype(s).
func FSTypeFilter(fstype ...string) FilterFunc {
return func(m *Info) (bool, bool) {
for _, t := range fstype {
if m.FSType == t {
return false, false // don't skip, keep going
}
}
return true, false // skip, keep going
}
}

214
vendor/github.com/moby/sys/mountinfo/mountinfo_linux.go generated vendored Normal file
View File

@ -0,0 +1,214 @@
package mountinfo
import (
"bufio"
"fmt"
"io"
"os"
"strconv"
"strings"
)
// GetMountsFromReader retrieves a list of mounts from the
// reader provided, with an optional filter applied (use nil
// for no filter). This can be useful in tests or benchmarks
// that provide fake mountinfo data, or when a source other
// than /proc/self/mountinfo needs to be read from.
//
// This function is Linux-specific.
func GetMountsFromReader(r io.Reader, filter FilterFunc) ([]*Info, error) {
s := bufio.NewScanner(r)
out := []*Info{}
for s.Scan() {
var err error
/*
See http://man7.org/linux/man-pages/man5/proc.5.html
36 35 98:0 /mnt1 /mnt2 rw,noatime master:1 - ext3 /dev/root rw,errors=continue
(1)(2)(3) (4) (5) (6) (7) (8) (9) (10) (11)
(1) mount ID: unique identifier of the mount (may be reused after umount)
(2) parent ID: ID of parent (or of self for the top of the mount tree)
(3) major:minor: value of st_dev for files on filesystem
(4) root: root of the mount within the filesystem
(5) mount point: mount point relative to the process's root
(6) mount options: per mount options
(7) optional fields: zero or more fields of the form "tag[:value]"
(8) separator: marks the end of the optional fields
(9) filesystem type: name of filesystem of the form "type[.subtype]"
(10) mount source: filesystem specific information or "none"
(11) super options: per super block options
In other words, we have:
* 6 mandatory fields (1)..(6)
* 0 or more optional fields (7)
* a separator field (8)
* 3 mandatory fields (9)..(11)
*/
text := s.Text()
fields := strings.Split(text, " ")
numFields := len(fields)
if numFields < 10 {
// should be at least 10 fields
return nil, fmt.Errorf("parsing '%s' failed: not enough fields (%d)", text, numFields)
}
// separator field
sepIdx := numFields - 4
// In Linux <= 3.9 mounting a cifs with spaces in a share
// name (like "//srv/My Docs") _may_ end up having a space
// in the last field of mountinfo (like "unc=//serv/My Docs").
// Since kernel 3.10-rc1, cifs option "unc=" is ignored,
// so spaces should not appear.
//
// Check for a separator, and work around the spaces bug
for fields[sepIdx] != "-" {
sepIdx--
if sepIdx == 5 {
return nil, fmt.Errorf("parsing '%s' failed: missing - separator", text)
}
}
p := &Info{}
p.Mountpoint, err = unescape(fields[4])
if err != nil {
return nil, fmt.Errorf("parsing '%s' failed: mount point: %w", fields[4], err)
}
p.FSType, err = unescape(fields[sepIdx+1])
if err != nil {
return nil, fmt.Errorf("parsing '%s' failed: fstype: %w", fields[sepIdx+1], err)
}
p.Source, err = unescape(fields[sepIdx+2])
if err != nil {
return nil, fmt.Errorf("parsing '%s' failed: source: %w", fields[sepIdx+2], err)
}
p.VFSOptions = fields[sepIdx+3]
// ignore any numbers parsing errors, as there should not be any
p.ID, _ = strconv.Atoi(fields[0])
p.Parent, _ = strconv.Atoi(fields[1])
mm := strings.SplitN(fields[2], ":", 3)
if len(mm) != 2 {
return nil, fmt.Errorf("parsing '%s' failed: unexpected major:minor pair %s", text, mm)
}
p.Major, _ = strconv.Atoi(mm[0])
p.Minor, _ = strconv.Atoi(mm[1])
p.Root, err = unescape(fields[3])
if err != nil {
return nil, fmt.Errorf("parsing '%s' failed: root: %w", fields[3], err)
}
p.Options = fields[5]
// zero or more optional fields
p.Optional = strings.Join(fields[6:sepIdx], " ")
// Run the filter after parsing all fields.
var skip, stop bool
if filter != nil {
skip, stop = filter(p)
if skip {
continue
}
}
out = append(out, p)
if stop {
break
}
}
if err := s.Err(); err != nil {
return nil, err
}
return out, nil
}
func parseMountTable(filter FilterFunc) ([]*Info, error) {
f, err := os.Open("/proc/self/mountinfo")
if err != nil {
return nil, err
}
defer f.Close()
return GetMountsFromReader(f, filter)
}
// PidMountInfo retrieves the list of mounts from a given process' mount
// namespace. Unless there is a need to get mounts from a mount namespace
// different from that of a calling process, use GetMounts.
//
// This function is Linux-specific.
//
// Deprecated: this will be removed before v1; use GetMountsFromReader with
// opened /proc/<pid>/mountinfo as an argument instead.
func PidMountInfo(pid int) ([]*Info, error) {
f, err := os.Open(fmt.Sprintf("/proc/%d/mountinfo", pid))
if err != nil {
return nil, err
}
defer f.Close()
return GetMountsFromReader(f, nil)
}
// A few specific characters in mountinfo path entries (root and mountpoint)
// are escaped using a backslash followed by a character's ascii code in octal.
//
// space -- as \040
// tab (aka \t) -- as \011
// newline (aka \n) -- as \012
// backslash (aka \\) -- as \134
//
// This function converts path from mountinfo back, i.e. it unescapes the above sequences.
func unescape(path string) (string, error) {
// try to avoid copying
if strings.IndexByte(path, '\\') == -1 {
return path, nil
}
// The following code is UTF-8 transparent as it only looks for some
// specific characters (backslash and 0..7) with values < utf8.RuneSelf,
// and everything else is passed through as is.
buf := make([]byte, len(path))
bufLen := 0
for i := 0; i < len(path); i++ {
if path[i] != '\\' {
buf[bufLen] = path[i]
bufLen++
continue
}
s := path[i:]
if len(s) < 4 {
// too short
return "", fmt.Errorf("bad escape sequence %q: too short", s)
}
c := s[1]
switch c {
case '0', '1', '2', '3', '4', '5', '6', '7':
v := c - '0'
for j := 2; j < 4; j++ { // one digit already; two more
if s[j] < '0' || s[j] > '7' {
return "", fmt.Errorf("bad escape sequence %q: not a digit", s[:3])
}
x := s[j] - '0'
v = (v << 3) | x
}
if v > 255 {
return "", fmt.Errorf("bad escape sequence %q: out of range" + s[:3])
}
buf[bufLen] = v
bufLen++
i += 3
continue
default:
return "", fmt.Errorf("bad escape sequence %q: not a digit" + s[:3])
}
}
return string(buf[:bufLen]), nil
}

View File

@ -0,0 +1,19 @@
//go:build (!windows && !linux && !freebsd && !openbsd && !darwin) || (freebsd && !cgo) || (openbsd && !cgo) || (darwin && !cgo)
// +build !windows,!linux,!freebsd,!openbsd,!darwin freebsd,!cgo openbsd,!cgo darwin,!cgo
package mountinfo
import (
"fmt"
"runtime"
)
var errNotImplemented = fmt.Errorf("not implemented on %s/%s", runtime.GOOS, runtime.GOARCH)
func parseMountTable(_ FilterFunc) ([]*Info, error) {
return nil, errNotImplemented
}
func mounted(path string) (bool, error) {
return false, errNotImplemented
}

View File

@ -0,0 +1,10 @@
package mountinfo
func parseMountTable(_ FilterFunc) ([]*Info, error) {
// Do NOT return an error!
return nil, nil
}
func mounted(_ string) (bool, error) {
return false, nil
}

View File

@ -5,7 +5,7 @@
// Recreate a getsystemcfg syscall handler instead of
// using the one provided by x/sys/unix to avoid having
// the dependency between them. (See golang.org/issue/32102)
// Morever, this file will be used during the building of
// Moreover, this file will be used during the building of
// gccgo's libgo and thus must not used a CGo method.
//go:build aix && gccgo

View File

@ -194,3 +194,26 @@ func ioctlIfreqData(fd int, req uint, value *ifreqData) error {
// identical so pass *IfreqData directly.
return ioctlPtr(fd, req, unsafe.Pointer(value))
}
// IoctlKCMClone attaches a new file descriptor to a multiplexor by cloning an
// existing KCM socket, returning a structure containing the file descriptor of
// the new socket.
func IoctlKCMClone(fd int) (*KCMClone, error) {
var info KCMClone
if err := ioctlPtr(fd, SIOCKCMCLONE, unsafe.Pointer(&info)); err != nil {
return nil, err
}
return &info, nil
}
// IoctlKCMAttach attaches a TCP socket and associated BPF program file
// descriptor to a multiplexor.
func IoctlKCMAttach(fd int, info KCMAttach) error {
return ioctlPtr(fd, SIOCKCMATTACH, unsafe.Pointer(&info))
}
// IoctlKCMUnattach unattaches a TCP socket file descriptor from a multiplexor.
func IoctlKCMUnattach(fd int, info KCMUnattach) error {
return ioctlPtr(fd, SIOCKCMUNATTACH, unsafe.Pointer(&info))
}

View File

@ -205,6 +205,7 @@ struct ltchars {
#include <linux/bpf.h>
#include <linux/can.h>
#include <linux/can/error.h>
#include <linux/can/netlink.h>
#include <linux/can/raw.h>
#include <linux/capability.h>
#include <linux/cryptouser.h>
@ -231,6 +232,7 @@ struct ltchars {
#include <linux/if_packet.h>
#include <linux/if_xdp.h>
#include <linux/input.h>
#include <linux/kcm.h>
#include <linux/kexec.h>
#include <linux/keyctl.h>
#include <linux/landlock.h>
@ -503,6 +505,7 @@ ccflags="$@"
$2 ~ /^O?XTABS$/ ||
$2 ~ /^TC[IO](ON|OFF)$/ ||
$2 ~ /^IN_/ ||
$2 ~ /^KCM/ ||
$2 ~ /^LANDLOCK_/ ||
$2 ~ /^LOCK_(SH|EX|NB|UN)$/ ||
$2 ~ /^LO_(KEY|NAME)_SIZE$/ ||

View File

@ -215,18 +215,12 @@ func Accept(fd int) (nfd int, sa Sockaddr, err error) {
return
}
func Recvmsg(fd int, p, oob []byte, flags int) (n, oobn int, recvflags int, from Sockaddr, err error) {
func recvmsgRaw(fd int, p, oob []byte, flags int, rsa *RawSockaddrAny) (n, oobn int, recvflags int, err error) {
// Recvmsg not implemented on AIX
sa := new(SockaddrUnix)
return -1, -1, -1, sa, ENOSYS
return -1, -1, -1, ENOSYS
}
func Sendmsg(fd int, p, oob []byte, to Sockaddr, flags int) (err error) {
_, err = SendmsgN(fd, p, oob, to, flags)
return
}
func SendmsgN(fd int, p, oob []byte, to Sockaddr, flags int) (n int, err error) {
func sendmsgN(fd int, p, oob []byte, ptr unsafe.Pointer, salen _Socklen, flags int) (n int, err error) {
// SendmsgN not implemented on AIX
return -1, ENOSYS
}
@ -458,8 +452,8 @@ func Fsync(fd int) error {
//sys Listen(s int, n int) (err error)
//sys lstat(path string, stat *Stat_t) (err error)
//sys Pause() (err error)
//sys Pread(fd int, p []byte, offset int64) (n int, err error) = pread64
//sys Pwrite(fd int, p []byte, offset int64) (n int, err error) = pwrite64
//sys pread(fd int, p []byte, offset int64) (n int, err error) = pread64
//sys pwrite(fd int, p []byte, offset int64) (n int, err error) = pwrite64
//sys Select(nfd int, r *FdSet, w *FdSet, e *FdSet, timeout *Timeval) (n int, err error)
//sys Pselect(nfd int, r *FdSet, w *FdSet, e *FdSet, timeout *Timespec, sigmask *Sigset_t) (n int, err error)
//sysnb Setregid(rgid int, egid int) (err error)

View File

@ -325,10 +325,9 @@ func GetsockoptString(fd, level, opt int) (string, error) {
//sys sendto(s int, buf []byte, flags int, to unsafe.Pointer, addrlen _Socklen) (err error)
//sys recvmsg(s int, msg *Msghdr, flags int) (n int, err error)
func Recvmsg(fd int, p, oob []byte, flags int) (n, oobn int, recvflags int, from Sockaddr, err error) {
func recvmsgRaw(fd int, p, oob []byte, flags int, rsa *RawSockaddrAny) (n, oobn int, recvflags int, err error) {
var msg Msghdr
var rsa RawSockaddrAny
msg.Name = (*byte)(unsafe.Pointer(&rsa))
msg.Name = (*byte)(unsafe.Pointer(rsa))
msg.Namelen = uint32(SizeofSockaddrAny)
var iov Iovec
if len(p) > 0 {
@ -352,29 +351,12 @@ func Recvmsg(fd int, p, oob []byte, flags int) (n, oobn int, recvflags int, from
}
oobn = int(msg.Controllen)
recvflags = int(msg.Flags)
// source address is only specified if the socket is unconnected
if rsa.Addr.Family != AF_UNSPEC {
from, err = anyToSockaddr(fd, &rsa)
}
return
}
//sys sendmsg(s int, msg *Msghdr, flags int) (n int, err error)
func Sendmsg(fd int, p, oob []byte, to Sockaddr, flags int) (err error) {
_, err = SendmsgN(fd, p, oob, to, flags)
return
}
func SendmsgN(fd int, p, oob []byte, to Sockaddr, flags int) (n int, err error) {
var ptr unsafe.Pointer
var salen _Socklen
if to != nil {
ptr, salen, err = to.sockaddr()
if err != nil {
return 0, err
}
}
func sendmsgN(fd int, p, oob []byte, ptr unsafe.Pointer, salen _Socklen, flags int) (n int, err error) {
var msg Msghdr
msg.Name = (*byte)(unsafe.Pointer(ptr))
msg.Namelen = uint32(salen)

View File

@ -546,8 +546,8 @@ func SysctlKinfoProcSlice(name string, args ...int) ([]KinfoProc, error) {
//sys Open(path string, mode int, perm uint32) (fd int, err error)
//sys Openat(dirfd int, path string, mode int, perm uint32) (fd int, err error)
//sys Pathconf(path string, name int) (val int, err error)
//sys Pread(fd int, p []byte, offset int64) (n int, err error)
//sys Pwrite(fd int, p []byte, offset int64) (n int, err error)
//sys pread(fd int, p []byte, offset int64) (n int, err error)
//sys pwrite(fd int, p []byte, offset int64) (n int, err error)
//sys read(fd int, p []byte) (n int, err error)
//sys Readlink(path string, buf []byte) (n int, err error)
//sys Readlinkat(dirfd int, path string, buf []byte) (n int, err error)

View File

@ -125,12 +125,12 @@ func Pipe2(p []int, flags int) (err error) {
}
//sys extpread(fd int, p []byte, flags int, offset int64) (n int, err error)
func Pread(fd int, p []byte, offset int64) (n int, err error) {
func pread(fd int, p []byte, offset int64) (n int, err error) {
return extpread(fd, p, 0, offset)
}
//sys extpwrite(fd int, p []byte, flags int, offset int64) (n int, err error)
func Pwrite(fd int, p []byte, offset int64) (n int, err error) {
func pwrite(fd int, p []byte, offset int64) (n int, err error) {
return extpwrite(fd, p, 0, offset)
}

View File

@ -638,8 +638,8 @@ func PtraceSingleStep(pid int) (err error) {
//sys Open(path string, mode int, perm uint32) (fd int, err error)
//sys Openat(fdat int, path string, mode int, perm uint32) (fd int, err error)
//sys Pathconf(path string, name int) (val int, err error)
//sys Pread(fd int, p []byte, offset int64) (n int, err error)
//sys Pwrite(fd int, p []byte, offset int64) (n int, err error)
//sys pread(fd int, p []byte, offset int64) (n int, err error)
//sys pwrite(fd int, p []byte, offset int64) (n int, err error)
//sys read(fd int, p []byte) (n int, err error)
//sys Readlink(path string, buf []byte) (n int, err error)
//sys Readlinkat(dirfd int, path string, buf []byte) (n int, err error)

View File

@ -250,6 +250,13 @@ func Getwd() (wd string, err error) {
if n < 1 || n > len(buf) || buf[n-1] != 0 {
return "", EINVAL
}
// In some cases, Linux can return a path that starts with the
// "(unreachable)" prefix, which can potentially be a valid relative
// path. To work around that, return ENOENT if path is not absolute.
if buf[0] != '/' {
return "", ENOENT
}
return string(buf[0 : n-1]), nil
}
@ -1490,10 +1497,9 @@ func KeyctlRestrictKeyring(ringid int, keyType string, restriction string) error
//sys keyctlRestrictKeyringByType(cmd int, arg2 int, keyType string, restriction string) (err error) = SYS_KEYCTL
//sys keyctlRestrictKeyring(cmd int, arg2 int) (err error) = SYS_KEYCTL
func Recvmsg(fd int, p, oob []byte, flags int) (n, oobn int, recvflags int, from Sockaddr, err error) {
func recvmsgRaw(fd int, p, oob []byte, flags int, rsa *RawSockaddrAny) (n, oobn int, recvflags int, err error) {
var msg Msghdr
var rsa RawSockaddrAny
msg.Name = (*byte)(unsafe.Pointer(&rsa))
msg.Name = (*byte)(unsafe.Pointer(rsa))
msg.Namelen = uint32(SizeofSockaddrAny)
var iov Iovec
if len(p) > 0 {
@ -1524,28 +1530,10 @@ func Recvmsg(fd int, p, oob []byte, flags int) (n, oobn int, recvflags int, from
}
oobn = int(msg.Controllen)
recvflags = int(msg.Flags)
// source address is only specified if the socket is unconnected
if rsa.Addr.Family != AF_UNSPEC {
from, err = anyToSockaddr(fd, &rsa)
}
return
}
func Sendmsg(fd int, p, oob []byte, to Sockaddr, flags int) (err error) {
_, err = SendmsgN(fd, p, oob, to, flags)
return
}
func SendmsgN(fd int, p, oob []byte, to Sockaddr, flags int) (n int, err error) {
var ptr unsafe.Pointer
var salen _Socklen
if to != nil {
var err error
ptr, salen, err = to.sockaddr()
if err != nil {
return 0, err
}
}
func sendmsgN(fd int, p, oob []byte, ptr unsafe.Pointer, salen _Socklen, flags int) (n int, err error) {
var msg Msghdr
msg.Name = (*byte)(ptr)
msg.Namelen = uint32(salen)
@ -2309,6 +2297,7 @@ type RemoteIovec struct {
//sys PidfdOpen(pid int, flags int) (fd int, err error) = SYS_PIDFD_OPEN
//sys PidfdGetfd(pidfd int, targetfd int, flags int) (fd int, err error) = SYS_PIDFD_GETFD
//sys PidfdSendSignal(pidfd int, sig Signal, info *Siginfo, flags int) (err error) = SYS_PIDFD_SEND_SIGNAL
//sys shmat(id int, addr uintptr, flag int) (ret uintptr, err error)
//sys shmctl(id int, cmd int, buf *SysvShmDesc) (result int, err error)

View File

@ -35,8 +35,8 @@ func setTimeval(sec, usec int64) Timeval {
//sys Iopl(level int) (err error)
//sys Lchown(path string, uid int, gid int) (err error) = SYS_LCHOWN32
//sys Lstat(path string, stat *Stat_t) (err error) = SYS_LSTAT64
//sys Pread(fd int, p []byte, offset int64) (n int, err error) = SYS_PREAD64
//sys Pwrite(fd int, p []byte, offset int64) (n int, err error) = SYS_PWRITE64
//sys pread(fd int, p []byte, offset int64) (n int, err error) = SYS_PREAD64
//sys pwrite(fd int, p []byte, offset int64) (n int, err error) = SYS_PWRITE64
//sys Renameat(olddirfd int, oldpath string, newdirfd int, newpath string) (err error)
//sys sendfile(outfd int, infd int, offset *int64, count int) (written int, err error) = SYS_SENDFILE64
//sys setfsgid(gid int) (prev int, err error) = SYS_SETFSGID32
@ -173,14 +173,6 @@ const (
_SENDMMSG = 20
)
func accept(s int, rsa *RawSockaddrAny, addrlen *_Socklen) (fd int, err error) {
fd, e := socketcall(_ACCEPT, uintptr(s), uintptr(unsafe.Pointer(rsa)), uintptr(unsafe.Pointer(addrlen)), 0, 0, 0)
if e != 0 {
err = e
}
return
}
func accept4(s int, rsa *RawSockaddrAny, addrlen *_Socklen, flags int) (fd int, err error) {
fd, e := socketcall(_ACCEPT4, uintptr(s), uintptr(unsafe.Pointer(rsa)), uintptr(unsafe.Pointer(addrlen)), uintptr(flags), 0, 0)
if e != 0 {

View File

@ -29,8 +29,8 @@ func Lstat(path string, stat *Stat_t) (err error) {
}
//sys Pause() (err error)
//sys Pread(fd int, p []byte, offset int64) (n int, err error) = SYS_PREAD64
//sys Pwrite(fd int, p []byte, offset int64) (n int, err error) = SYS_PWRITE64
//sys pread(fd int, p []byte, offset int64) (n int, err error) = SYS_PREAD64
//sys pwrite(fd int, p []byte, offset int64) (n int, err error) = SYS_PWRITE64
//sys Renameat(olddirfd int, oldpath string, newdirfd int, newpath string) (err error)
//sys Seek(fd int, offset int64, whence int) (off int64, err error) = SYS_LSEEK
@ -62,7 +62,6 @@ func Stat(path string, stat *Stat_t) (err error) {
//sys SyncFileRange(fd int, off int64, n int64, flags int) (err error)
//sys Truncate(path string, length int64) (err error)
//sys Ustat(dev int, ubuf *Ustat_t) (err error)
//sys accept(s int, rsa *RawSockaddrAny, addrlen *_Socklen) (fd int, err error)
//sys accept4(s int, rsa *RawSockaddrAny, addrlen *_Socklen, flags int) (fd int, err error)
//sys bind(s int, addr unsafe.Pointer, addrlen _Socklen) (err error)
//sys connect(s int, addr unsafe.Pointer, addrlen _Socklen) (err error)

View File

@ -27,7 +27,6 @@ func Seek(fd int, offset int64, whence int) (newoffset int64, err error) {
return newoffset, nil
}
//sys accept(s int, rsa *RawSockaddrAny, addrlen *_Socklen) (fd int, err error)
//sys accept4(s int, rsa *RawSockaddrAny, addrlen *_Socklen, flags int) (fd int, err error)
//sys bind(s int, addr unsafe.Pointer, addrlen _Socklen) (err error)
//sys connect(s int, addr unsafe.Pointer, addrlen _Socklen) (err error)
@ -97,8 +96,8 @@ func Utime(path string, buf *Utimbuf) error {
//sys utimes(path string, times *[2]Timeval) (err error)
//sys Pread(fd int, p []byte, offset int64) (n int, err error) = SYS_PREAD64
//sys Pwrite(fd int, p []byte, offset int64) (n int, err error) = SYS_PWRITE64
//sys pread(fd int, p []byte, offset int64) (n int, err error) = SYS_PREAD64
//sys pwrite(fd int, p []byte, offset int64) (n int, err error) = SYS_PWRITE64
//sys Truncate(path string, length int64) (err error) = SYS_TRUNCATE64
//sys Ftruncate(fd int, length int64) (err error) = SYS_FTRUNCATE64

View File

@ -22,8 +22,8 @@ import "unsafe"
//sysnb getrlimit(resource int, rlim *Rlimit) (err error)
//sysnb Getuid() (uid int)
//sys Listen(s int, n int) (err error)
//sys Pread(fd int, p []byte, offset int64) (n int, err error) = SYS_PREAD64
//sys Pwrite(fd int, p []byte, offset int64) (n int, err error) = SYS_PWRITE64
//sys pread(fd int, p []byte, offset int64) (n int, err error) = SYS_PREAD64
//sys pwrite(fd int, p []byte, offset int64) (n int, err error) = SYS_PWRITE64
//sys Renameat(olddirfd int, oldpath string, newdirfd int, newpath string) (err error)
//sys Seek(fd int, offset int64, whence int) (off int64, err error) = SYS_LSEEK
@ -66,7 +66,6 @@ func Ustat(dev int, ubuf *Ustat_t) (err error) {
return ENOSYS
}
//sys accept(s int, rsa *RawSockaddrAny, addrlen *_Socklen) (fd int, err error)
//sys accept4(s int, rsa *RawSockaddrAny, addrlen *_Socklen, flags int) (fd int, err error)
//sys bind(s int, addr unsafe.Pointer, addrlen _Socklen) (err error)
//sys connect(s int, addr unsafe.Pointer, addrlen _Socklen) (err error)

View File

@ -21,8 +21,8 @@ package unix
//sys Lchown(path string, uid int, gid int) (err error)
//sys Listen(s int, n int) (err error)
//sys Pause() (err error)
//sys Pread(fd int, p []byte, offset int64) (n int, err error) = SYS_PREAD64
//sys Pwrite(fd int, p []byte, offset int64) (n int, err error) = SYS_PWRITE64
//sys pread(fd int, p []byte, offset int64) (n int, err error) = SYS_PREAD64
//sys pwrite(fd int, p []byte, offset int64) (n int, err error) = SYS_PWRITE64
//sys Renameat(olddirfd int, oldpath string, newdirfd int, newpath string) (err error)
//sys Seek(fd int, offset int64, whence int) (off int64, err error) = SYS_LSEEK
@ -48,7 +48,6 @@ func Select(nfd int, r *FdSet, w *FdSet, e *FdSet, timeout *Timeval) (n int, err
//sys SyncFileRange(fd int, off int64, n int64, flags int) (err error)
//sys Truncate(path string, length int64) (err error)
//sys Ustat(dev int, ubuf *Ustat_t) (err error)
//sys accept(s int, rsa *RawSockaddrAny, addrlen *_Socklen) (fd int, err error)
//sys accept4(s int, rsa *RawSockaddrAny, addrlen *_Socklen, flags int) (fd int, err error)
//sys bind(s int, addr unsafe.Pointer, addrlen _Socklen) (err error)
//sys connect(s int, addr unsafe.Pointer, addrlen _Socklen) (err error)

View File

@ -25,8 +25,8 @@ func Syscall9(trap, a1, a2, a3, a4, a5, a6, a7, a8, a9 uintptr) (r1, r2 uintptr,
//sysnb Getuid() (uid int)
//sys Lchown(path string, uid int, gid int) (err error)
//sys Listen(s int, n int) (err error)
//sys Pread(fd int, p []byte, offset int64) (n int, err error) = SYS_PREAD64
//sys Pwrite(fd int, p []byte, offset int64) (n int, err error) = SYS_PWRITE64
//sys pread(fd int, p []byte, offset int64) (n int, err error) = SYS_PREAD64
//sys pwrite(fd int, p []byte, offset int64) (n int, err error) = SYS_PWRITE64
//sys Renameat(olddirfd int, oldpath string, newdirfd int, newpath string) (err error)
//sys Select(nfd int, r *FdSet, w *FdSet, e *FdSet, timeout *Timeval) (n int, err error) = SYS__NEWSELECT
//sys sendfile(outfd int, infd int, offset *int64, count int) (written int, err error) = SYS_SENDFILE64
@ -41,7 +41,6 @@ func Syscall9(trap, a1, a2, a3, a4, a5, a6, a7, a8, a9 uintptr) (r1, r2 uintptr,
//sys SyncFileRange(fd int, off int64, n int64, flags int) (err error)
//sys Truncate(path string, length int64) (err error) = SYS_TRUNCATE64
//sys Ustat(dev int, ubuf *Ustat_t) (err error)
//sys accept(s int, rsa *RawSockaddrAny, addrlen *_Socklen) (fd int, err error)
//sys accept4(s int, rsa *RawSockaddrAny, addrlen *_Socklen, flags int) (fd int, err error)
//sys bind(s int, addr unsafe.Pointer, addrlen _Socklen) (err error)
//sys connect(s int, addr unsafe.Pointer, addrlen _Socklen) (err error)

View File

@ -27,8 +27,8 @@ import (
//sys Listen(s int, n int) (err error)
//sys Lstat(path string, stat *Stat_t) (err error) = SYS_LSTAT64
//sys Pause() (err error)
//sys Pread(fd int, p []byte, offset int64) (n int, err error) = SYS_PREAD64
//sys Pwrite(fd int, p []byte, offset int64) (n int, err error) = SYS_PWRITE64
//sys pread(fd int, p []byte, offset int64) (n int, err error) = SYS_PREAD64
//sys pwrite(fd int, p []byte, offset int64) (n int, err error) = SYS_PWRITE64
//sys Renameat(olddirfd int, oldpath string, newdirfd int, newpath string) (err error)
//sys Select(nfd int, r *FdSet, w *FdSet, e *FdSet, timeout *Timeval) (n int, err error) = SYS__NEWSELECT
//sys sendfile(outfd int, infd int, offset *int64, count int) (written int, err error) = SYS_SENDFILE64
@ -43,7 +43,6 @@ import (
//sys Stat(path string, stat *Stat_t) (err error) = SYS_STAT64
//sys Truncate(path string, length int64) (err error) = SYS_TRUNCATE64
//sys Ustat(dev int, ubuf *Ustat_t) (err error)
//sys accept(s int, rsa *RawSockaddrAny, addrlen *_Socklen) (fd int, err error)
//sys accept4(s int, rsa *RawSockaddrAny, addrlen *_Socklen, flags int) (fd int, err error)
//sys bind(s int, addr unsafe.Pointer, addrlen _Socklen) (err error)
//sys connect(s int, addr unsafe.Pointer, addrlen _Socklen) (err error)

View File

@ -26,8 +26,8 @@ package unix
//sys Listen(s int, n int) (err error)
//sys Lstat(path string, stat *Stat_t) (err error)
//sys Pause() (err error)
//sys Pread(fd int, p []byte, offset int64) (n int, err error) = SYS_PREAD64
//sys Pwrite(fd int, p []byte, offset int64) (n int, err error) = SYS_PWRITE64
//sys pread(fd int, p []byte, offset int64) (n int, err error) = SYS_PREAD64
//sys pwrite(fd int, p []byte, offset int64) (n int, err error) = SYS_PWRITE64
//sys Renameat(olddirfd int, oldpath string, newdirfd int, newpath string) (err error)
//sys Seek(fd int, offset int64, whence int) (off int64, err error) = SYS_LSEEK
//sys Select(nfd int, r *FdSet, w *FdSet, e *FdSet, timeout *Timeval) (n int, err error) = SYS__NEWSELECT
@ -45,7 +45,6 @@ package unix
//sys Statfs(path string, buf *Statfs_t) (err error)
//sys Truncate(path string, length int64) (err error)
//sys Ustat(dev int, ubuf *Ustat_t) (err error)
//sys accept(s int, rsa *RawSockaddrAny, addrlen *_Socklen) (fd int, err error)
//sys accept4(s int, rsa *RawSockaddrAny, addrlen *_Socklen, flags int) (fd int, err error)
//sys bind(s int, addr unsafe.Pointer, addrlen _Socklen) (err error)
//sys connect(s int, addr unsafe.Pointer, addrlen _Socklen) (err error)

View File

@ -22,8 +22,8 @@ import "unsafe"
//sysnb Getrlimit(resource int, rlim *Rlimit) (err error)
//sysnb Getuid() (uid int)
//sys Listen(s int, n int) (err error)
//sys Pread(fd int, p []byte, offset int64) (n int, err error) = SYS_PREAD64
//sys Pwrite(fd int, p []byte, offset int64) (n int, err error) = SYS_PWRITE64
//sys pread(fd int, p []byte, offset int64) (n int, err error) = SYS_PREAD64
//sys pwrite(fd int, p []byte, offset int64) (n int, err error) = SYS_PWRITE64
//sys Seek(fd int, offset int64, whence int) (off int64, err error) = SYS_LSEEK
func Select(nfd int, r *FdSet, w *FdSet, e *FdSet, timeout *Timeval) (n int, err error) {
@ -65,7 +65,6 @@ func Ustat(dev int, ubuf *Ustat_t) (err error) {
return ENOSYS
}
//sys accept(s int, rsa *RawSockaddrAny, addrlen *_Socklen) (fd int, err error)
//sys accept4(s int, rsa *RawSockaddrAny, addrlen *_Socklen, flags int) (fd int, err error)
//sys bind(s int, addr unsafe.Pointer, addrlen _Socklen) (err error)
//sys connect(s int, addr unsafe.Pointer, addrlen _Socklen) (err error)

View File

@ -26,8 +26,8 @@ import (
//sys Lchown(path string, uid int, gid int) (err error)
//sys Lstat(path string, stat *Stat_t) (err error)
//sys Pause() (err error)
//sys Pread(fd int, p []byte, offset int64) (n int, err error) = SYS_PREAD64
//sys Pwrite(fd int, p []byte, offset int64) (n int, err error) = SYS_PWRITE64
//sys pread(fd int, p []byte, offset int64) (n int, err error) = SYS_PREAD64
//sys pwrite(fd int, p []byte, offset int64) (n int, err error) = SYS_PWRITE64
//sys Renameat(olddirfd int, oldpath string, newdirfd int, newpath string) (err error)
//sys Seek(fd int, offset int64, whence int) (off int64, err error) = SYS_LSEEK
//sys Select(nfd int, r *FdSet, w *FdSet, e *FdSet, timeout *Timeval) (n int, err error)
@ -145,15 +145,6 @@ const (
netSendMMsg = 20
)
func accept(s int, rsa *RawSockaddrAny, addrlen *_Socklen) (int, error) {
args := [3]uintptr{uintptr(s), uintptr(unsafe.Pointer(rsa)), uintptr(unsafe.Pointer(addrlen))}
fd, _, err := Syscall(SYS_SOCKETCALL, netAccept, uintptr(unsafe.Pointer(&args)), 0)
if err != 0 {
return 0, err
}
return int(fd), nil
}
func accept4(s int, rsa *RawSockaddrAny, addrlen *_Socklen, flags int) (int, error) {
args := [4]uintptr{uintptr(s), uintptr(unsafe.Pointer(rsa)), uintptr(unsafe.Pointer(addrlen)), uintptr(flags)}
fd, _, err := Syscall(SYS_SOCKETCALL, netAccept4, uintptr(unsafe.Pointer(&args)), 0)

View File

@ -23,8 +23,8 @@ package unix
//sys Listen(s int, n int) (err error)
//sys Lstat(path string, stat *Stat_t) (err error)
//sys Pause() (err error)
//sys Pread(fd int, p []byte, offset int64) (n int, err error) = SYS_PREAD64
//sys Pwrite(fd int, p []byte, offset int64) (n int, err error) = SYS_PWRITE64
//sys pread(fd int, p []byte, offset int64) (n int, err error) = SYS_PREAD64
//sys pwrite(fd int, p []byte, offset int64) (n int, err error) = SYS_PWRITE64
//sys Renameat(olddirfd int, oldpath string, newdirfd int, newpath string) (err error)
//sys Seek(fd int, offset int64, whence int) (off int64, err error) = SYS_LSEEK
//sys Select(nfd int, r *FdSet, w *FdSet, e *FdSet, timeout *Timeval) (n int, err error)
@ -42,7 +42,6 @@ package unix
//sys Statfs(path string, buf *Statfs_t) (err error)
//sys SyncFileRange(fd int, off int64, n int64, flags int) (err error)
//sys Truncate(path string, length int64) (err error)
//sys accept(s int, rsa *RawSockaddrAny, addrlen *_Socklen) (fd int, err error)
//sys accept4(s int, rsa *RawSockaddrAny, addrlen *_Socklen, flags int) (fd int, err error)
//sys bind(s int, addr unsafe.Pointer, addrlen _Socklen) (err error)
//sys connect(s int, addr unsafe.Pointer, addrlen _Socklen) (err error)

View File

@ -313,8 +313,8 @@ func Statvfs(path string, buf *Statvfs_t) (err error) {
//sys Open(path string, mode int, perm uint32) (fd int, err error)
//sys Openat(dirfd int, path string, mode int, perm uint32) (fd int, err error)
//sys Pathconf(path string, name int) (val int, err error)
//sys Pread(fd int, p []byte, offset int64) (n int, err error)
//sys Pwrite(fd int, p []byte, offset int64) (n int, err error)
//sys pread(fd int, p []byte, offset int64) (n int, err error)
//sys pwrite(fd int, p []byte, offset int64) (n int, err error)
//sys read(fd int, p []byte) (n int, err error)
//sys Readlink(path string, buf []byte) (n int, err error)
//sys Readlinkat(dirfd int, path string, buf []byte) (n int, err error)

View File

@ -274,8 +274,8 @@ func Uname(uname *Utsname) error {
//sys Open(path string, mode int, perm uint32) (fd int, err error)
//sys Openat(dirfd int, path string, mode int, perm uint32) (fd int, err error)
//sys Pathconf(path string, name int) (val int, err error)
//sys Pread(fd int, p []byte, offset int64) (n int, err error)
//sys Pwrite(fd int, p []byte, offset int64) (n int, err error)
//sys pread(fd int, p []byte, offset int64) (n int, err error)
//sys pwrite(fd int, p []byte, offset int64) (n int, err error)
//sys read(fd int, p []byte) (n int, err error)
//sys Readlink(path string, buf []byte) (n int, err error)
//sys Readlinkat(dirfd int, path string, buf []byte) (n int, err error)

View File

@ -451,10 +451,9 @@ func Accept(fd int) (nfd int, sa Sockaddr, err error) {
//sys recvmsg(s int, msg *Msghdr, flags int) (n int, err error) = libsocket.__xnet_recvmsg
func Recvmsg(fd int, p, oob []byte, flags int) (n, oobn int, recvflags int, from Sockaddr, err error) {
func recvmsgRaw(fd int, p, oob []byte, flags int, rsa *RawSockaddrAny) (n, oobn int, recvflags int, err error) {
var msg Msghdr
var rsa RawSockaddrAny
msg.Name = (*byte)(unsafe.Pointer(&rsa))
msg.Name = (*byte)(unsafe.Pointer(rsa))
msg.Namelen = uint32(SizeofSockaddrAny)
var iov Iovec
if len(p) > 0 {
@ -476,29 +475,12 @@ func Recvmsg(fd int, p, oob []byte, flags int) (n, oobn int, recvflags int, from
return
}
oobn = int(msg.Accrightslen)
// source address is only specified if the socket is unconnected
if rsa.Addr.Family != AF_UNSPEC {
from, err = anyToSockaddr(fd, &rsa)
}
return
}
func Sendmsg(fd int, p, oob []byte, to Sockaddr, flags int) (err error) {
_, err = SendmsgN(fd, p, oob, to, flags)
return
}
//sys sendmsg(s int, msg *Msghdr, flags int) (n int, err error) = libsocket.__xnet_sendmsg
func SendmsgN(fd int, p, oob []byte, to Sockaddr, flags int) (n int, err error) {
var ptr unsafe.Pointer
var salen _Socklen
if to != nil {
ptr, salen, err = to.sockaddr()
if err != nil {
return 0, err
}
}
func sendmsgN(fd int, p, oob []byte, ptr unsafe.Pointer, salen _Socklen, flags int) (n int, err error) {
var msg Msghdr
msg.Name = (*byte)(unsafe.Pointer(ptr))
msg.Namelen = uint32(salen)
@ -661,8 +643,8 @@ func Sendfile(outfd int, infd int, offset *int64, count int) (written int, err e
//sys Openat(dirfd int, path string, flags int, mode uint32) (fd int, err error)
//sys Pathconf(path string, name int) (val int, err error)
//sys Pause() (err error)
//sys Pread(fd int, p []byte, offset int64) (n int, err error)
//sys Pwrite(fd int, p []byte, offset int64) (n int, err error)
//sys pread(fd int, p []byte, offset int64) (n int, err error)
//sys pwrite(fd int, p []byte, offset int64) (n int, err error)
//sys read(fd int, p []byte) (n int, err error)
//sys Readlink(path string, buf []byte) (n int, err error)
//sys Rename(from string, to string) (err error)

View File

@ -177,6 +177,30 @@ func Write(fd int, p []byte) (n int, err error) {
return
}
func Pread(fd int, p []byte, offset int64) (n int, err error) {
n, err = pread(fd, p, offset)
if raceenabled {
if n > 0 {
raceWriteRange(unsafe.Pointer(&p[0]), n)
}
if err == nil {
raceAcquire(unsafe.Pointer(&ioSync))
}
}
return
}
func Pwrite(fd int, p []byte, offset int64) (n int, err error) {
if raceenabled {
raceReleaseMerge(unsafe.Pointer(&ioSync))
}
n, err = pwrite(fd, p, offset)
if raceenabled && n > 0 {
raceReadRange(unsafe.Pointer(&p[0]), n)
}
return
}
// For testing: clients can set this flag to force
// creation of IPv6 sockets to return EAFNOSUPPORT.
var SocketDisableIPv6 bool
@ -313,6 +337,33 @@ func Recvfrom(fd int, p []byte, flags int) (n int, from Sockaddr, err error) {
return
}
func Recvmsg(fd int, p, oob []byte, flags int) (n, oobn int, recvflags int, from Sockaddr, err error) {
var rsa RawSockaddrAny
n, oobn, recvflags, err = recvmsgRaw(fd, p, oob, flags, &rsa)
// source address is only specified if the socket is unconnected
if rsa.Addr.Family != AF_UNSPEC {
from, err = anyToSockaddr(fd, &rsa)
}
return
}
func Sendmsg(fd int, p, oob []byte, to Sockaddr, flags int) (err error) {
_, err = SendmsgN(fd, p, oob, to, flags)
return
}
func SendmsgN(fd int, p, oob []byte, to Sockaddr, flags int) (n int, err error) {
var ptr unsafe.Pointer
var salen _Socklen
if to != nil {
ptr, salen, err = to.sockaddr()
if err != nil {
return 0, err
}
}
return sendmsgN(fd, p, oob, ptr, salen, flags)
}
func Send(s int, buf []byte, flags int) (err error) {
return sendto(s, buf, flags, nil, 0)
}

View File

@ -260,6 +260,17 @@ const (
BUS_USB = 0x3
BUS_VIRTUAL = 0x6
CAN_BCM = 0x2
CAN_CTRLMODE_3_SAMPLES = 0x4
CAN_CTRLMODE_BERR_REPORTING = 0x10
CAN_CTRLMODE_CC_LEN8_DLC = 0x100
CAN_CTRLMODE_FD = 0x20
CAN_CTRLMODE_FD_NON_ISO = 0x80
CAN_CTRLMODE_LISTENONLY = 0x2
CAN_CTRLMODE_LOOPBACK = 0x1
CAN_CTRLMODE_ONE_SHOT = 0x8
CAN_CTRLMODE_PRESUME_ACK = 0x40
CAN_CTRLMODE_TDC_AUTO = 0x200
CAN_CTRLMODE_TDC_MANUAL = 0x400
CAN_EFF_FLAG = 0x80000000
CAN_EFF_ID_BITS = 0x1d
CAN_EFF_MASK = 0x1fffffff
@ -337,6 +348,7 @@ const (
CAN_RTR_FLAG = 0x40000000
CAN_SFF_ID_BITS = 0xb
CAN_SFF_MASK = 0x7ff
CAN_TERMINATION_DISABLED = 0x0
CAN_TP16 = 0x3
CAN_TP20 = 0x4
CAP_AUDIT_CONTROL = 0x1e
@ -1274,6 +1286,8 @@ const (
IUTF8 = 0x4000
IXANY = 0x800
JFFS2_SUPER_MAGIC = 0x72b6
KCMPROTO_CONNECTED = 0x0
KCM_RECV_DISABLE = 0x1
KEXEC_ARCH_386 = 0x30000
KEXEC_ARCH_68K = 0x40000
KEXEC_ARCH_AARCH64 = 0xb70000
@ -2446,6 +2460,9 @@ const (
SIOCGSTAMPNS = 0x8907
SIOCGSTAMPNS_OLD = 0x8907
SIOCGSTAMP_OLD = 0x8906
SIOCKCMATTACH = 0x89e0
SIOCKCMCLONE = 0x89e2
SIOCKCMUNATTACH = 0x89e1
SIOCOUTQNSD = 0x894b
SIOCPROTOPRIVATE = 0x89e0
SIOCRTMSG = 0x890d

View File

@ -975,7 +975,7 @@ func Pause() (err error) {
// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
func Pread(fd int, p []byte, offset int64) (n int, err error) {
func pread(fd int, p []byte, offset int64) (n int, err error) {
var _p0 *byte
if len(p) > 0 {
_p0 = &p[0]
@ -992,7 +992,7 @@ func Pread(fd int, p []byte, offset int64) (n int, err error) {
// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
func Pwrite(fd int, p []byte, offset int64) (n int, err error) {
func pwrite(fd int, p []byte, offset int64) (n int, err error) {
var _p0 *byte
if len(p) > 0 {
_p0 = &p[0]

View File

@ -931,7 +931,7 @@ func Pause() (err error) {
// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
func Pread(fd int, p []byte, offset int64) (n int, err error) {
func pread(fd int, p []byte, offset int64) (n int, err error) {
var _p0 *byte
if len(p) > 0 {
_p0 = &p[0]
@ -946,7 +946,7 @@ func Pread(fd int, p []byte, offset int64) (n int, err error) {
// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
func Pwrite(fd int, p []byte, offset int64) (n int, err error) {
func pwrite(fd int, p []byte, offset int64) (n int, err error) {
var _p0 *byte
if len(p) > 0 {
_p0 = &p[0]

View File

@ -1698,7 +1698,7 @@ var libc_pathconf_trampoline_addr uintptr
// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
func Pread(fd int, p []byte, offset int64) (n int, err error) {
func pread(fd int, p []byte, offset int64) (n int, err error) {
var _p0 unsafe.Pointer
if len(p) > 0 {
_p0 = unsafe.Pointer(&p[0])
@ -1719,7 +1719,7 @@ var libc_pread_trampoline_addr uintptr
// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
func Pwrite(fd int, p []byte, offset int64) (n int, err error) {
func pwrite(fd int, p []byte, offset int64) (n int, err error) {
var _p0 unsafe.Pointer
if len(p) > 0 {
_p0 = unsafe.Pointer(&p[0])

View File

@ -1698,7 +1698,7 @@ var libc_pathconf_trampoline_addr uintptr
// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
func Pread(fd int, p []byte, offset int64) (n int, err error) {
func pread(fd int, p []byte, offset int64) (n int, err error) {
var _p0 unsafe.Pointer
if len(p) > 0 {
_p0 = unsafe.Pointer(&p[0])
@ -1719,7 +1719,7 @@ var libc_pread_trampoline_addr uintptr
// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
func Pwrite(fd int, p []byte, offset int64) (n int, err error) {
func pwrite(fd int, p []byte, offset int64) (n int, err error) {
var _p0 unsafe.Pointer
if len(p) > 0 {
_p0 = unsafe.Pointer(&p[0])

View File

@ -1420,7 +1420,7 @@ func Pathconf(path string, name int) (val int, err error) {
// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
func Pread(fd int, p []byte, offset int64) (n int, err error) {
func pread(fd int, p []byte, offset int64) (n int, err error) {
var _p0 unsafe.Pointer
if len(p) > 0 {
_p0 = unsafe.Pointer(&p[0])
@ -1437,7 +1437,7 @@ func Pread(fd int, p []byte, offset int64) (n int, err error) {
// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
func Pwrite(fd int, p []byte, offset int64) (n int, err error) {
func pwrite(fd int, p []byte, offset int64) (n int, err error) {
var _p0 unsafe.Pointer
if len(p) > 0 {
_p0 = unsafe.Pointer(&p[0])

View File

@ -1420,7 +1420,7 @@ func Pathconf(path string, name int) (val int, err error) {
// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
func Pread(fd int, p []byte, offset int64) (n int, err error) {
func pread(fd int, p []byte, offset int64) (n int, err error) {
var _p0 unsafe.Pointer
if len(p) > 0 {
_p0 = unsafe.Pointer(&p[0])
@ -1437,7 +1437,7 @@ func Pread(fd int, p []byte, offset int64) (n int, err error) {
// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
func Pwrite(fd int, p []byte, offset int64) (n int, err error) {
func pwrite(fd int, p []byte, offset int64) (n int, err error) {
var _p0 unsafe.Pointer
if len(p) > 0 {
_p0 = unsafe.Pointer(&p[0])

View File

@ -1420,7 +1420,7 @@ func Pathconf(path string, name int) (val int, err error) {
// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
func Pread(fd int, p []byte, offset int64) (n int, err error) {
func pread(fd int, p []byte, offset int64) (n int, err error) {
var _p0 unsafe.Pointer
if len(p) > 0 {
_p0 = unsafe.Pointer(&p[0])
@ -1437,7 +1437,7 @@ func Pread(fd int, p []byte, offset int64) (n int, err error) {
// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
func Pwrite(fd int, p []byte, offset int64) (n int, err error) {
func pwrite(fd int, p []byte, offset int64) (n int, err error) {
var _p0 unsafe.Pointer
if len(p) > 0 {
_p0 = unsafe.Pointer(&p[0])

View File

@ -1420,7 +1420,7 @@ func Pathconf(path string, name int) (val int, err error) {
// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
func Pread(fd int, p []byte, offset int64) (n int, err error) {
func pread(fd int, p []byte, offset int64) (n int, err error) {
var _p0 unsafe.Pointer
if len(p) > 0 {
_p0 = unsafe.Pointer(&p[0])
@ -1437,7 +1437,7 @@ func Pread(fd int, p []byte, offset int64) (n int, err error) {
// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
func Pwrite(fd int, p []byte, offset int64) (n int, err error) {
func pwrite(fd int, p []byte, offset int64) (n int, err error) {
var _p0 unsafe.Pointer
if len(p) > 0 {
_p0 = unsafe.Pointer(&p[0])

View File

@ -1992,6 +1992,16 @@ func PidfdGetfd(pidfd int, targetfd int, flags int) (fd int, err error) {
// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
func PidfdSendSignal(pidfd int, sig Signal, info *Siginfo, flags int) (err error) {
_, _, e1 := Syscall6(SYS_PIDFD_SEND_SIGNAL, uintptr(pidfd), uintptr(sig), uintptr(unsafe.Pointer(info)), uintptr(flags), 0, 0)
if e1 != 0 {
err = errnoErr(e1)
}
return
}
// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
func shmat(id int, addr uintptr, flag int) (ret uintptr, err error) {
r0, _, e1 := Syscall(SYS_SHMAT, uintptr(id), uintptr(addr), uintptr(flag))
ret = uintptr(r0)

View File

@ -200,7 +200,7 @@ func Lstat(path string, stat *Stat_t) (err error) {
// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
func Pread(fd int, p []byte, offset int64) (n int, err error) {
func pread(fd int, p []byte, offset int64) (n int, err error) {
var _p0 unsafe.Pointer
if len(p) > 0 {
_p0 = unsafe.Pointer(&p[0])
@ -217,7 +217,7 @@ func Pread(fd int, p []byte, offset int64) (n int, err error) {
// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
func Pwrite(fd int, p []byte, offset int64) (n int, err error) {
func pwrite(fd int, p []byte, offset int64) (n int, err error) {
var _p0 unsafe.Pointer
if len(p) > 0 {
_p0 = unsafe.Pointer(&p[0])

View File

@ -225,7 +225,7 @@ func Pause() (err error) {
// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
func Pread(fd int, p []byte, offset int64) (n int, err error) {
func pread(fd int, p []byte, offset int64) (n int, err error) {
var _p0 unsafe.Pointer
if len(p) > 0 {
_p0 = unsafe.Pointer(&p[0])
@ -242,7 +242,7 @@ func Pread(fd int, p []byte, offset int64) (n int, err error) {
// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
func Pwrite(fd int, p []byte, offset int64) (n int, err error) {
func pwrite(fd int, p []byte, offset int64) (n int, err error) {
var _p0 unsafe.Pointer
if len(p) > 0 {
_p0 = unsafe.Pointer(&p[0])
@ -444,17 +444,6 @@ func Ustat(dev int, ubuf *Ustat_t) (err error) {
// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
func accept(s int, rsa *RawSockaddrAny, addrlen *_Socklen) (fd int, err error) {
r0, _, e1 := Syscall(SYS_ACCEPT, uintptr(s), uintptr(unsafe.Pointer(rsa)), uintptr(unsafe.Pointer(addrlen)))
fd = int(r0)
if e1 != 0 {
err = errnoErr(e1)
}
return
}
// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
func accept4(s int, rsa *RawSockaddrAny, addrlen *_Socklen, flags int) (fd int, err error) {
r0, _, e1 := Syscall6(SYS_ACCEPT4, uintptr(s), uintptr(unsafe.Pointer(rsa)), uintptr(unsafe.Pointer(addrlen)), uintptr(flags), 0, 0)
fd = int(r0)

View File

@ -46,17 +46,6 @@ func Tee(rfd int, wfd int, len int, flags int) (n int64, err error) {
// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
func accept(s int, rsa *RawSockaddrAny, addrlen *_Socklen) (fd int, err error) {
r0, _, e1 := Syscall(SYS_ACCEPT, uintptr(s), uintptr(unsafe.Pointer(rsa)), uintptr(unsafe.Pointer(addrlen)))
fd = int(r0)
if e1 != 0 {
err = errnoErr(e1)
}
return
}
// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
func accept4(s int, rsa *RawSockaddrAny, addrlen *_Socklen, flags int) (fd int, err error) {
r0, _, e1 := Syscall6(SYS_ACCEPT4, uintptr(s), uintptr(unsafe.Pointer(rsa)), uintptr(unsafe.Pointer(addrlen)), uintptr(flags), 0, 0)
fd = int(r0)
@ -549,7 +538,7 @@ func utimes(path string, times *[2]Timeval) (err error) {
// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
func Pread(fd int, p []byte, offset int64) (n int, err error) {
func pread(fd int, p []byte, offset int64) (n int, err error) {
var _p0 unsafe.Pointer
if len(p) > 0 {
_p0 = unsafe.Pointer(&p[0])
@ -566,7 +555,7 @@ func Pread(fd int, p []byte, offset int64) (n int, err error) {
// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
func Pwrite(fd int, p []byte, offset int64) (n int, err error) {
func pwrite(fd int, p []byte, offset int64) (n int, err error) {
var _p0 unsafe.Pointer
if len(p) > 0 {
_p0 = unsafe.Pointer(&p[0])

View File

@ -180,7 +180,7 @@ func Listen(s int, n int) (err error) {
// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
func Pread(fd int, p []byte, offset int64) (n int, err error) {
func pread(fd int, p []byte, offset int64) (n int, err error) {
var _p0 unsafe.Pointer
if len(p) > 0 {
_p0 = unsafe.Pointer(&p[0])
@ -197,7 +197,7 @@ func Pread(fd int, p []byte, offset int64) (n int, err error) {
// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
func Pwrite(fd int, p []byte, offset int64) (n int, err error) {
func pwrite(fd int, p []byte, offset int64) (n int, err error) {
var _p0 unsafe.Pointer
if len(p) > 0 {
_p0 = unsafe.Pointer(&p[0])
@ -389,17 +389,6 @@ func Truncate(path string, length int64) (err error) {
// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
func accept(s int, rsa *RawSockaddrAny, addrlen *_Socklen) (fd int, err error) {
r0, _, e1 := Syscall(SYS_ACCEPT, uintptr(s), uintptr(unsafe.Pointer(rsa)), uintptr(unsafe.Pointer(addrlen)))
fd = int(r0)
if e1 != 0 {
err = errnoErr(e1)
}
return
}
// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
func accept4(s int, rsa *RawSockaddrAny, addrlen *_Socklen, flags int) (fd int, err error) {
r0, _, e1 := Syscall6(SYS_ACCEPT4, uintptr(s), uintptr(unsafe.Pointer(rsa)), uintptr(unsafe.Pointer(addrlen)), uintptr(flags), 0, 0)
fd = int(r0)

View File

@ -150,7 +150,7 @@ func Listen(s int, n int) (err error) {
// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
func Pread(fd int, p []byte, offset int64) (n int, err error) {
func pread(fd int, p []byte, offset int64) (n int, err error) {
var _p0 unsafe.Pointer
if len(p) > 0 {
_p0 = unsafe.Pointer(&p[0])
@ -167,7 +167,7 @@ func Pread(fd int, p []byte, offset int64) (n int, err error) {
// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
func Pwrite(fd int, p []byte, offset int64) (n int, err error) {
func pwrite(fd int, p []byte, offset int64) (n int, err error) {
var _p0 unsafe.Pointer
if len(p) > 0 {
_p0 = unsafe.Pointer(&p[0])
@ -344,17 +344,6 @@ func Ustat(dev int, ubuf *Ustat_t) (err error) {
// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
func accept(s int, rsa *RawSockaddrAny, addrlen *_Socklen) (fd int, err error) {
r0, _, e1 := Syscall(SYS_ACCEPT, uintptr(s), uintptr(unsafe.Pointer(rsa)), uintptr(unsafe.Pointer(addrlen)))
fd = int(r0)
if e1 != 0 {
err = errnoErr(e1)
}
return
}
// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
func accept4(s int, rsa *RawSockaddrAny, addrlen *_Socklen, flags int) (fd int, err error) {
r0, _, e1 := Syscall6(SYS_ACCEPT4, uintptr(s), uintptr(unsafe.Pointer(rsa)), uintptr(unsafe.Pointer(addrlen)), uintptr(flags), 0, 0)
fd = int(r0)

View File

@ -180,7 +180,7 @@ func Pause() (err error) {
// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
func Pread(fd int, p []byte, offset int64) (n int, err error) {
func pread(fd int, p []byte, offset int64) (n int, err error) {
var _p0 unsafe.Pointer
if len(p) > 0 {
_p0 = unsafe.Pointer(&p[0])
@ -197,7 +197,7 @@ func Pread(fd int, p []byte, offset int64) (n int, err error) {
// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
func Pwrite(fd int, p []byte, offset int64) (n int, err error) {
func pwrite(fd int, p []byte, offset int64) (n int, err error) {
var _p0 unsafe.Pointer
if len(p) > 0 {
_p0 = unsafe.Pointer(&p[0])
@ -399,17 +399,6 @@ func Ustat(dev int, ubuf *Ustat_t) (err error) {
// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
func accept(s int, rsa *RawSockaddrAny, addrlen *_Socklen) (fd int, err error) {
r0, _, e1 := Syscall(SYS_ACCEPT, uintptr(s), uintptr(unsafe.Pointer(rsa)), uintptr(unsafe.Pointer(addrlen)))
fd = int(r0)
if e1 != 0 {
err = errnoErr(e1)
}
return
}
// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
func accept4(s int, rsa *RawSockaddrAny, addrlen *_Socklen, flags int) (fd int, err error) {
r0, _, e1 := Syscall6(SYS_ACCEPT4, uintptr(s), uintptr(unsafe.Pointer(rsa)), uintptr(unsafe.Pointer(addrlen)), uintptr(flags), 0, 0)
fd = int(r0)

View File

@ -180,7 +180,7 @@ func Pause() (err error) {
// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
func Pread(fd int, p []byte, offset int64) (n int, err error) {
func pread(fd int, p []byte, offset int64) (n int, err error) {
var _p0 unsafe.Pointer
if len(p) > 0 {
_p0 = unsafe.Pointer(&p[0])
@ -197,7 +197,7 @@ func Pread(fd int, p []byte, offset int64) (n int, err error) {
// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
func Pwrite(fd int, p []byte, offset int64) (n int, err error) {
func pwrite(fd int, p []byte, offset int64) (n int, err error) {
var _p0 unsafe.Pointer
if len(p) > 0 {
_p0 = unsafe.Pointer(&p[0])
@ -399,17 +399,6 @@ func Ustat(dev int, ubuf *Ustat_t) (err error) {
// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
func accept(s int, rsa *RawSockaddrAny, addrlen *_Socklen) (fd int, err error) {
r0, _, e1 := Syscall(SYS_ACCEPT, uintptr(s), uintptr(unsafe.Pointer(rsa)), uintptr(unsafe.Pointer(addrlen)))
fd = int(r0)
if e1 != 0 {
err = errnoErr(e1)
}
return
}
// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
func accept4(s int, rsa *RawSockaddrAny, addrlen *_Socklen, flags int) (fd int, err error) {
r0, _, e1 := Syscall6(SYS_ACCEPT4, uintptr(s), uintptr(unsafe.Pointer(rsa)), uintptr(unsafe.Pointer(addrlen)), uintptr(flags), 0, 0)
fd = int(r0)

View File

@ -150,7 +150,7 @@ func Listen(s int, n int) (err error) {
// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
func Pread(fd int, p []byte, offset int64) (n int, err error) {
func pread(fd int, p []byte, offset int64) (n int, err error) {
var _p0 unsafe.Pointer
if len(p) > 0 {
_p0 = unsafe.Pointer(&p[0])
@ -167,7 +167,7 @@ func Pread(fd int, p []byte, offset int64) (n int, err error) {
// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
func Pwrite(fd int, p []byte, offset int64) (n int, err error) {
func pwrite(fd int, p []byte, offset int64) (n int, err error) {
var _p0 unsafe.Pointer
if len(p) > 0 {
_p0 = unsafe.Pointer(&p[0])
@ -344,17 +344,6 @@ func Ustat(dev int, ubuf *Ustat_t) (err error) {
// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
func accept(s int, rsa *RawSockaddrAny, addrlen *_Socklen) (fd int, err error) {
r0, _, e1 := Syscall(SYS_ACCEPT, uintptr(s), uintptr(unsafe.Pointer(rsa)), uintptr(unsafe.Pointer(addrlen)))
fd = int(r0)
if e1 != 0 {
err = errnoErr(e1)
}
return
}
// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
func accept4(s int, rsa *RawSockaddrAny, addrlen *_Socklen, flags int) (fd int, err error) {
r0, _, e1 := Syscall6(SYS_ACCEPT4, uintptr(s), uintptr(unsafe.Pointer(rsa)), uintptr(unsafe.Pointer(addrlen)), uintptr(flags), 0, 0)
fd = int(r0)

View File

@ -210,7 +210,7 @@ func Pause() (err error) {
// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
func Pread(fd int, p []byte, offset int64) (n int, err error) {
func pread(fd int, p []byte, offset int64) (n int, err error) {
var _p0 unsafe.Pointer
if len(p) > 0 {
_p0 = unsafe.Pointer(&p[0])
@ -227,7 +227,7 @@ func Pread(fd int, p []byte, offset int64) (n int, err error) {
// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
func Pwrite(fd int, p []byte, offset int64) (n int, err error) {
func pwrite(fd int, p []byte, offset int64) (n int, err error) {
var _p0 unsafe.Pointer
if len(p) > 0 {
_p0 = unsafe.Pointer(&p[0])
@ -409,17 +409,6 @@ func Ustat(dev int, ubuf *Ustat_t) (err error) {
// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
func accept(s int, rsa *RawSockaddrAny, addrlen *_Socklen) (fd int, err error) {
r0, _, e1 := Syscall(SYS_ACCEPT, uintptr(s), uintptr(unsafe.Pointer(rsa)), uintptr(unsafe.Pointer(addrlen)))
fd = int(r0)
if e1 != 0 {
err = errnoErr(e1)
}
return
}
// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
func accept4(s int, rsa *RawSockaddrAny, addrlen *_Socklen, flags int) (fd int, err error) {
r0, _, e1 := Syscall6(SYS_ACCEPT4, uintptr(s), uintptr(unsafe.Pointer(rsa)), uintptr(unsafe.Pointer(addrlen)), uintptr(flags), 0, 0)
fd = int(r0)

Some files were not shown because too many files have changed in this diff Show More