mirror of
https://github.com/k3s-io/kubernetes.git
synced 2025-07-20 10:20:51 +00:00
Merge pull request #39928 from humblec/iscsi-multipath-backuptp
Automatic merge from submit-queue Add mulitpath support to iscsi plugin #issue https://github.com/kubernetes/kubernetes/issues/39345 Signed-off-by: Humble Chirammal <hchiramm@redhat.com>
This commit is contained in:
commit
a75b61d7a3
@ -36654,6 +36654,13 @@
|
||||
"type": "integer",
|
||||
"format": "int32"
|
||||
},
|
||||
"portals": {
|
||||
"description": "iSCSI target portal List. The portal is either an IP or ip_addr:port if the port is other than default (typically TCP ports 860 and 3260).",
|
||||
"type": "array",
|
||||
"items": {
|
||||
"type": "string"
|
||||
}
|
||||
},
|
||||
"readOnly": {
|
||||
"description": "ReadOnly here will force the ReadOnly setting in VolumeMounts. Defaults to false.",
|
||||
"type": "boolean"
|
||||
|
@ -1645,7 +1645,8 @@
|
||||
"required": [
|
||||
"targetPortal",
|
||||
"iqn",
|
||||
"lun"
|
||||
"lun",
|
||||
"portals"
|
||||
],
|
||||
"properties": {
|
||||
"targetPortal": {
|
||||
@ -1672,6 +1673,13 @@
|
||||
"readOnly": {
|
||||
"type": "boolean",
|
||||
"description": "ReadOnly here will force the ReadOnly setting in VolumeMounts. Defaults to false."
|
||||
},
|
||||
"portals": {
|
||||
"type": "array",
|
||||
"items": {
|
||||
"type": "string"
|
||||
},
|
||||
"description": "iSCSI target portal List. The portal is either an IP or ip_addr:port if the port is other than default (typically TCP ports 860 and 3260)."
|
||||
}
|
||||
}
|
||||
},
|
||||
|
@ -1650,7 +1650,8 @@
|
||||
"required": [
|
||||
"targetPortal",
|
||||
"iqn",
|
||||
"lun"
|
||||
"lun",
|
||||
"portals"
|
||||
],
|
||||
"properties": {
|
||||
"targetPortal": {
|
||||
@ -1677,6 +1678,13 @@
|
||||
"readOnly": {
|
||||
"type": "boolean",
|
||||
"description": "ReadOnly here will force the ReadOnly setting in VolumeMounts. Defaults to false."
|
||||
},
|
||||
"portals": {
|
||||
"type": "array",
|
||||
"items": {
|
||||
"type": "string"
|
||||
},
|
||||
"description": "iSCSI target portal List. The portal is either an IP or ip_addr:port if the port is other than default (typically TCP ports 860 and 3260)."
|
||||
}
|
||||
}
|
||||
},
|
||||
|
@ -7052,7 +7052,8 @@
|
||||
"required": [
|
||||
"targetPortal",
|
||||
"iqn",
|
||||
"lun"
|
||||
"lun",
|
||||
"portals"
|
||||
],
|
||||
"properties": {
|
||||
"targetPortal": {
|
||||
@ -7079,6 +7080,13 @@
|
||||
"readOnly": {
|
||||
"type": "boolean",
|
||||
"description": "ReadOnly here will force the ReadOnly setting in VolumeMounts. Defaults to false."
|
||||
},
|
||||
"portals": {
|
||||
"type": "array",
|
||||
"items": {
|
||||
"type": "string"
|
||||
},
|
||||
"description": "iSCSI target portal List. The portal is either an IP or ip_addr:port if the port is other than default (typically TCP ports 860 and 3260)."
|
||||
}
|
||||
}
|
||||
},
|
||||
|
@ -17847,7 +17847,8 @@
|
||||
"required": [
|
||||
"targetPortal",
|
||||
"iqn",
|
||||
"lun"
|
||||
"lun",
|
||||
"portals"
|
||||
],
|
||||
"properties": {
|
||||
"targetPortal": {
|
||||
@ -17874,6 +17875,13 @@
|
||||
"readOnly": {
|
||||
"type": "boolean",
|
||||
"description": "ReadOnly here will force the ReadOnly setting in VolumeMounts. Defaults to false."
|
||||
},
|
||||
"portals": {
|
||||
"type": "array",
|
||||
"items": {
|
||||
"type": "string"
|
||||
},
|
||||
"description": "iSCSI target portal List. The portal is either an IP or ip_addr:port if the port is other than default (typically TCP ports 860 and 3260)."
|
||||
}
|
||||
}
|
||||
},
|
||||
|
@ -2497,6 +2497,13 @@ Populated by the system when a graceful deletion is requested. Read-only. More i
|
||||
<td class="tableblock halign-left valign-top"><p class="tableblock">boolean</p></td>
|
||||
<td class="tableblock halign-left valign-top"><p class="tableblock">false</p></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td class="tableblock halign-left valign-top"><p class="tableblock">portals</p></td>
|
||||
<td class="tableblock halign-left valign-top"><p class="tableblock">iSCSI target portal List. The portal is either an IP or ip_addr:port if the port is other than default (typically TCP ports 860 and 3260).</p></td>
|
||||
<td class="tableblock halign-left valign-top"><p class="tableblock">true</p></td>
|
||||
<td class="tableblock halign-left valign-top"><p class="tableblock">string array</p></td>
|
||||
<td class="tableblock halign-left valign-top"></td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
|
||||
@ -5074,7 +5081,7 @@ Examples:<br>
|
||||
</div>
|
||||
<div id="footer">
|
||||
<div id="footer-text">
|
||||
Last updated 2017-02-02 23:51:07 UTC
|
||||
Last updated 2017-02-06 11:50:05 UTC
|
||||
</div>
|
||||
</div>
|
||||
</body>
|
||||
|
@ -2408,6 +2408,13 @@ Populated by the system when a graceful deletion is requested. Read-only. More i
|
||||
<td class="tableblock halign-left valign-top"><p class="tableblock">boolean</p></td>
|
||||
<td class="tableblock halign-left valign-top"><p class="tableblock">false</p></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td class="tableblock halign-left valign-top"><p class="tableblock">portals</p></td>
|
||||
<td class="tableblock halign-left valign-top"><p class="tableblock">iSCSI target portal List. The portal is either an IP or ip_addr:port if the port is other than default (typically TCP ports 860 and 3260).</p></td>
|
||||
<td class="tableblock halign-left valign-top"><p class="tableblock">true</p></td>
|
||||
<td class="tableblock halign-left valign-top"><p class="tableblock">string array</p></td>
|
||||
<td class="tableblock halign-left valign-top"></td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
|
||||
@ -5006,7 +5013,7 @@ Examples:<br>
|
||||
</div>
|
||||
<div id="footer">
|
||||
<div id="footer-text">
|
||||
Last updated 2017-02-02 23:51:26 UTC
|
||||
Last updated 2017-02-06 11:50:30 UTC
|
||||
</div>
|
||||
</div>
|
||||
</body>
|
||||
|
@ -2239,6 +2239,13 @@ Populated by the system when a graceful deletion is requested. Read-only. More i
|
||||
<td class="tableblock halign-left valign-top"><p class="tableblock">boolean</p></td>
|
||||
<td class="tableblock halign-left valign-top"><p class="tableblock">false</p></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td class="tableblock halign-left valign-top"><p class="tableblock">portals</p></td>
|
||||
<td class="tableblock halign-left valign-top"><p class="tableblock">iSCSI target portal List. The portal is either an IP or ip_addr:port if the port is other than default (typically TCP ports 860 and 3260).</p></td>
|
||||
<td class="tableblock halign-left valign-top"><p class="tableblock">true</p></td>
|
||||
<td class="tableblock halign-left valign-top"><p class="tableblock">string array</p></td>
|
||||
<td class="tableblock halign-left valign-top"></td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
|
||||
@ -7297,7 +7304,7 @@ Both these may change in the future. Incoming requests are matched against the h
|
||||
</div>
|
||||
<div id="footer">
|
||||
<div id="footer-text">
|
||||
Last updated 2017-02-02 23:51:41 UTC
|
||||
Last updated 2017-02-06 11:50:48 UTC
|
||||
</div>
|
||||
</div>
|
||||
</body>
|
||||
|
@ -2420,6 +2420,13 @@ Populated by the system when a graceful deletion is requested. Read-only. More i
|
||||
<td class="tableblock halign-left valign-top"><p class="tableblock">boolean</p></td>
|
||||
<td class="tableblock halign-left valign-top"><p class="tableblock">false</p></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td class="tableblock halign-left valign-top"><p class="tableblock">portals</p></td>
|
||||
<td class="tableblock halign-left valign-top"><p class="tableblock">iSCSI target portal List. The portal is either an IP or ip_addr:port if the port is other than default (typically TCP ports 860 and 3260).</p></td>
|
||||
<td class="tableblock halign-left valign-top"><p class="tableblock">true</p></td>
|
||||
<td class="tableblock halign-left valign-top"><p class="tableblock">string array</p></td>
|
||||
<td class="tableblock halign-left valign-top"></td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
|
||||
@ -9254,7 +9261,7 @@ Examples:<br>
|
||||
</div>
|
||||
<div id="footer">
|
||||
<div id="footer-text">
|
||||
Last updated 2017-02-02 23:51:00 UTC
|
||||
Last updated 2017-02-06 11:49:57 UTC
|
||||
</div>
|
||||
</div>
|
||||
</body>
|
||||
|
@ -18,7 +18,7 @@ If there isn't one in place then it is possible to setup a software version on L
|
||||
|
||||
## Creating the pod with iSCSI persistent storage
|
||||
|
||||
Once you have configured the iSCSI initiator, you can create a pod based on the example *iscsi.yaml*. In the pod YAML, you need to provide *targetPortal* (the iSCSI target's **IP** address and *port* if not the default port 3260), target's *iqn*, *lun*, and the type of the filesystem that has been created on the lun, and *readOnly* boolean. No initiator information is required.
|
||||
Once you have configured the iSCSI initiator, you can create a pod based on the example *iscsi.yaml*. In the pod YAML, you need to provide *targetPortal* (the iSCSI target's **IP** address and *port* if not the default port 3260), target's *iqn*, *lun*, and the type of the filesystem that has been created on the lun, and *readOnly* boolean. No initiator information is required. If you have more than one target portals for a single IQN, you can mention other portal IPs in *portals* field.
|
||||
|
||||
If you want to use an iSCSI offload card or other open-iscsi transports besides tcp, setup an iSCSI interface and provide *iscsiInterface* in the pod YAML. The default name for an iscsi iface (open-iscsi parameter iface.iscsi\_ifacename) is in the format transport\_name.hwaddress when generated by iscsiadm. See [open-iscsi](http://www.open-iscsi.org/docs/README) or [openstack](http://docs.openstack.org/kilo/config-reference/content/iscsi-iface-config.html) for detailed configuration information.
|
||||
|
||||
@ -48,19 +48,23 @@ For a non mpio device the output should look like the following
|
||||
|
||||
```console
|
||||
# mount |grep kub
|
||||
/dev/sdb on /var/lib/kubelet/plugins/kubernetes.io/iscsi/10.0.2.15:3260-iqn.2001-04.com.example:storage.kube.sys1.xyz-lun-0 type ext4 (ro,relatime,data=ordered)
|
||||
/dev/sdb on /var/lib/kubelet/pods/f527ca5b-6d87-11e5-aa7e-080027ff6387/volumes/kubernetes.io~iscsi/iscsipd-ro type ext4 (ro,relatime,data=ordered)
|
||||
/dev/sdc on /var/lib/kubelet/plugins/kubernetes.io/iscsi/10.0.2.15:3260-iqn.2001-04.com.example:storage.kube.sys1.xyz-lun-1 type ext4 (rw,relatime,data=ordered)
|
||||
/dev/sdb on /var/lib/kubelet/plugins/kubernetes.io/iscsi/10.0.2.15:3260-iqn.2001-04.com.example:storage.kube.sys1.xyz-lun-0 type ext4 (rw,relatime,data=ordered)
|
||||
/dev/sdb on /var/lib/kubelet/pods/f527ca5b-6d87-11e5-aa7e-080027ff6387/volumes/kubernetes.io~iscsi/iscsipd-rw type ext4 (ro,relatime,data=ordered)
|
||||
/dev/sdc on /var/lib/kubelet/plugins/kubernetes.io/iscsi/10.0.2.16:3260-iqn.2001-04.com.example:storage.kube.sys1.xyz-lun-0 type ext4 (rw,relatime,data=ordered)
|
||||
/dev/sdc on /var/lib/kubelet/pods/f527ca5b-6d87-11e5-aa7e-080027ff6387/volumes/kubernetes.io~iscsi/iscsipd-rw type ext4 (rw,relatime,data=ordered)
|
||||
/dev/sdd on /var/lib/kubelet/plugins/kubernetes.io/iscsi/10.0.2.17:3260-iqn.2001-04.com.example:storage.kube.sys1.xyz-lun-0 type ext4 (rw,relatime,data=ordered)
|
||||
/dev/sdd on /var/lib/kubelet/pods/f527ca5b-6d87-11e5-aa7e-080027ff6387/volumes/kubernetes.io~iscsi/iscsipd-rw type ext4 (rw,relatime,data=ordered)
|
||||
```
|
||||
|
||||
And for a node with mpio enabled the expected output would be similar to the following
|
||||
|
||||
```console
|
||||
# mount |grep kub
|
||||
/dev/mapper/mpatha on /var/lib/kubelet/plugins/kubernetes.io/iscsi/10.0.2.15:3260-iqn.2001-04.com.example:storage.kube.sys1.xyz-lun-0 type ext4 (ro,relatime,data=ordered)
|
||||
/dev/mapper/mpatha on /var/lib/kubelet/plugins/kubernetes.io/iscsi/10.0.2.15:3260-iqn.2001-04.com.example:storage.kube.sys1.xyz-lun-0 type ext4 (rw,relatime,data=ordered)
|
||||
/dev/mapper/mpatha on /var/lib/kubelet/pods/f527ca5b-6d87-11e5-aa7e-080027ff6387/volumes/kubernetes.io~iscsi/iscsipd-ro type ext4 (ro,relatime,data=ordered)
|
||||
/dev/mapper/mpathb on /var/lib/kubelet/plugins/kubernetes.io/iscsi/10.0.2.15:3260-iqn.2001-04.com.example:storage.kube.sys1.xyz-lun-1 type ext4 (rw,relatime,data=ordered)
|
||||
/dev/mapper/mpathb on /var/lib/kubelet/plugins/kubernetes.io/iscsi/10.0.2.16:3260-iqn.2001-04.com.example:storage.kube.sys1.xyz-lun-0 type ext4 (rw,relatime,data=ordered)
|
||||
/dev/mapper/mpathb on /var/lib/kubelet/pods/f527ca5b-6d87-11e5-aa7e-080027ff6387/volumes/kubernetes.io~iscsi/iscsipd-rw type ext4 (rw,relatime,data=ordered)
|
||||
/dev/mapper/mpathc on /var/lib/kubelet/plugins/kubernetes.io/iscsi/10.0.2.17:3260-iqn.2001-04.com.example:storage.kube.sys1.xyz-lun-0 type ext4 (rw,relatime,data=ordered)
|
||||
/dev/mapper/mpathb on /var/lib/kubelet/pods/f527ca5b-6d87-11e5-aa7e-080027ff6387/volumes/kubernetes.io~iscsi/iscsipd-rw type ext4 (rw,relatime,data=ordered)
|
||||
```
|
||||
|
||||
@ -70,7 +74,6 @@ If you ssh to that machine, you can run `docker ps` to see the actual pod.
|
||||
```console
|
||||
# docker ps
|
||||
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
|
||||
f855336407f4 kubernetes/pause "/pause" 6 minutes ago Up 6 minutes k8s_iscsipd-ro.d130ec3e_iscsipd_default_f527ca5b-6d87-11e5-aa7e-080027ff6387_5409a4cb
|
||||
3b8a772515d2 kubernetes/pause "/pause" 6 minutes ago Up 6 minutes k8s_iscsipd-rw.ed58ec4e_iscsipd_default_f527ca5b-6d87-11e5-aa7e-080027ff6387_d25592c5
|
||||
```
|
||||
|
||||
|
@ -5,28 +5,17 @@ metadata:
|
||||
name: iscsipd
|
||||
spec:
|
||||
containers:
|
||||
- name: iscsipd-ro
|
||||
image: kubernetes/pause
|
||||
volumeMounts:
|
||||
- mountPath: "/mnt/iscsipd"
|
||||
name: iscsipd-ro
|
||||
- name: iscsipd-rw
|
||||
image: kubernetes/pause
|
||||
volumeMounts:
|
||||
- mountPath: "/mnt/iscsipd"
|
||||
name: iscsipd-rw
|
||||
volumes:
|
||||
- name: iscsipd-ro
|
||||
- name: iscsipd-rw
|
||||
iscsi:
|
||||
targetPortal: 10.0.2.15:3260
|
||||
portals: ['10.0.2.16:3260', '10.0.2.17:3260']
|
||||
iqn: iqn.2001-04.com.example:storage.kube.sys1.xyz
|
||||
lun: 0
|
||||
fsType: ext4
|
||||
readOnly: true
|
||||
- name: iscsipd-rw
|
||||
iscsi:
|
||||
targetPortal: 10.0.2.15:3260
|
||||
iqn: iqn.2001-04.com.example:storage.kube.sys1.xyz
|
||||
lun: 1
|
||||
fsType: ext4
|
||||
readOnly: false
|
||||
|
@ -12038,6 +12038,13 @@
|
||||
"type": "integer",
|
||||
"format": "int32"
|
||||
},
|
||||
"portals": {
|
||||
"description": "iSCSI target portal List. The portal is either an IP or ip_addr:port if the port is other than default (typically TCP ports 860 and 3260).",
|
||||
"type": "array",
|
||||
"items": {
|
||||
"type": "string"
|
||||
}
|
||||
},
|
||||
"readOnly": {
|
||||
"description": "ReadOnly here will force the ReadOnly setting in VolumeMounts. Defaults to false.",
|
||||
"type": "boolean"
|
||||
|
@ -4569,7 +4569,8 @@
|
||||
"type": "array",
|
||||
"items": {
|
||||
"$ref": "v1.Container"
|
||||
}
|
||||
},
|
||||
"description": "List of initialization containers belonging to the pod. Init containers are executed in order prior to containers being started. If any init container fails, the pod is considered to have failed and is handled according to its restartPolicy. The name for an init container or normal container must be unique among all containers. Init containers may not have Lifecycle actions, Readiness probes, or Liveness probes. The resourceRequirements of an init container are taken into account during scheduling by finding the highest request/limit for each resource type, and then using the max of of that value or the sum of the normal containers. Limits are applied to init containers in a similar fashion. Init containers cannot currently be added or removed. Cannot be updated. More info: http://kubernetes.io/docs/user-guide/containers"
|
||||
},
|
||||
"containers": {
|
||||
"type": "array",
|
||||
@ -4931,7 +4932,8 @@
|
||||
"required": [
|
||||
"targetPortal",
|
||||
"iqn",
|
||||
"lun"
|
||||
"lun",
|
||||
"portals"
|
||||
],
|
||||
"properties": {
|
||||
"targetPortal": {
|
||||
@ -4958,6 +4960,12 @@
|
||||
"readOnly": {
|
||||
"type": "boolean",
|
||||
"description": "ReadOnly here will force the ReadOnly setting in VolumeMounts. Defaults to false."
|
||||
},
|
||||
"portals": {
|
||||
"type": "array",
|
||||
"items": {
|
||||
"type": "string"
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
|
@ -625,6 +625,10 @@ type ISCSIVolumeSource struct {
|
||||
// the ReadOnly setting in VolumeMounts.
|
||||
// +optional
|
||||
ReadOnly bool
|
||||
// Required: list of iSCSI target portal ips for high availability.
|
||||
// the portal is either an IP or ip_addr:port if port is other than default (typically TCP ports 860 and 3260)
|
||||
// +optional
|
||||
Portals []string
|
||||
}
|
||||
|
||||
// Represents a Fibre Channel volume.
|
||||
|
File diff suppressed because it is too large
Load Diff
@ -1179,6 +1179,11 @@ message ISCSIVolumeSource {
|
||||
// Defaults to false.
|
||||
// +optional
|
||||
optional bool readOnly = 6;
|
||||
|
||||
// iSCSI target portal List. The portal is either an IP or ip_addr:port if the port
|
||||
// is other than default (typically TCP ports 860 and 3260).
|
||||
// +optional
|
||||
repeated string portals = 7;
|
||||
}
|
||||
|
||||
// Maps a string key to a path within a volume.
|
||||
|
@ -14833,7 +14833,7 @@ func (x *ISCSIVolumeSource) CodecEncodeSelf(e *codec1978.Encoder) {
|
||||
} else {
|
||||
yysep2 := !z.EncBinary()
|
||||
yy2arr2 := z.EncBasicHandle().StructToArray
|
||||
var yyq2 [6]bool
|
||||
var yyq2 [7]bool
|
||||
_, _, _ = yysep2, yyq2, yy2arr2
|
||||
const yyr2 bool = false
|
||||
yyq2[3] = x.ISCSIInterface != ""
|
||||
@ -14841,9 +14841,9 @@ func (x *ISCSIVolumeSource) CodecEncodeSelf(e *codec1978.Encoder) {
|
||||
yyq2[5] = x.ReadOnly != false
|
||||
var yynn2 int
|
||||
if yyr2 || yy2arr2 {
|
||||
r.EncodeArrayStart(6)
|
||||
r.EncodeArrayStart(7)
|
||||
} else {
|
||||
yynn2 = 3
|
||||
yynn2 = 4
|
||||
for _, b := range yyq2 {
|
||||
if b {
|
||||
yynn2++
|
||||
@ -14984,6 +14984,33 @@ func (x *ISCSIVolumeSource) CodecEncodeSelf(e *codec1978.Encoder) {
|
||||
}
|
||||
}
|
||||
}
|
||||
if yyr2 || yy2arr2 {
|
||||
z.EncSendContainerState(codecSelfer_containerArrayElem1234)
|
||||
if x.Portals == nil {
|
||||
r.EncodeNil()
|
||||
} else {
|
||||
yym22 := z.EncBinary()
|
||||
_ = yym22
|
||||
if false {
|
||||
} else {
|
||||
z.F.EncSliceStringV(x.Portals, false, e)
|
||||
}
|
||||
}
|
||||
} else {
|
||||
z.EncSendContainerState(codecSelfer_containerMapKey1234)
|
||||
r.EncodeString(codecSelferC_UTF81234, string("portals"))
|
||||
z.EncSendContainerState(codecSelfer_containerMapValue1234)
|
||||
if x.Portals == nil {
|
||||
r.EncodeNil()
|
||||
} else {
|
||||
yym23 := z.EncBinary()
|
||||
_ = yym23
|
||||
if false {
|
||||
} else {
|
||||
z.F.EncSliceStringV(x.Portals, false, e)
|
||||
}
|
||||
}
|
||||
}
|
||||
if yyr2 || yy2arr2 {
|
||||
z.EncSendContainerState(codecSelfer_containerArrayEnd1234)
|
||||
} else {
|
||||
@ -15117,6 +15144,18 @@ func (x *ISCSIVolumeSource) codecDecodeSelfFromMap(l int, d *codec1978.Decoder)
|
||||
*((*bool)(yyv14)) = r.DecodeBool()
|
||||
}
|
||||
}
|
||||
case "portals":
|
||||
if r.TryDecodeAsNil() {
|
||||
x.Portals = nil
|
||||
} else {
|
||||
yyv16 := &x.Portals
|
||||
yym17 := z.DecBinary()
|
||||
_ = yym17
|
||||
if false {
|
||||
} else {
|
||||
z.F.DecSliceStringX(yyv16, false, d)
|
||||
}
|
||||
}
|
||||
default:
|
||||
z.DecStructFieldNotFound(-1, yys3)
|
||||
} // end switch yys3
|
||||
@ -15128,16 +15167,16 @@ func (x *ISCSIVolumeSource) codecDecodeSelfFromArray(l int, d *codec1978.Decoder
|
||||
var h codecSelfer1234
|
||||
z, r := codec1978.GenHelperDecoder(d)
|
||||
_, _, _ = h, z, r
|
||||
var yyj16 int
|
||||
var yyb16 bool
|
||||
var yyhl16 bool = l >= 0
|
||||
yyj16++
|
||||
if yyhl16 {
|
||||
yyb16 = yyj16 > l
|
||||
var yyj18 int
|
||||
var yyb18 bool
|
||||
var yyhl18 bool = l >= 0
|
||||
yyj18++
|
||||
if yyhl18 {
|
||||
yyb18 = yyj18 > l
|
||||
} else {
|
||||
yyb16 = r.CheckBreak()
|
||||
yyb18 = r.CheckBreak()
|
||||
}
|
||||
if yyb16 {
|
||||
if yyb18 {
|
||||
z.DecSendContainerState(codecSelfer_containerArrayEnd1234)
|
||||
return
|
||||
}
|
||||
@ -15145,29 +15184,7 @@ func (x *ISCSIVolumeSource) codecDecodeSelfFromArray(l int, d *codec1978.Decoder
|
||||
if r.TryDecodeAsNil() {
|
||||
x.TargetPortal = ""
|
||||
} else {
|
||||
yyv17 := &x.TargetPortal
|
||||
yym18 := z.DecBinary()
|
||||
_ = yym18
|
||||
if false {
|
||||
} else {
|
||||
*((*string)(yyv17)) = r.DecodeString()
|
||||
}
|
||||
}
|
||||
yyj16++
|
||||
if yyhl16 {
|
||||
yyb16 = yyj16 > l
|
||||
} else {
|
||||
yyb16 = r.CheckBreak()
|
||||
}
|
||||
if yyb16 {
|
||||
z.DecSendContainerState(codecSelfer_containerArrayEnd1234)
|
||||
return
|
||||
}
|
||||
z.DecSendContainerState(codecSelfer_containerArrayElem1234)
|
||||
if r.TryDecodeAsNil() {
|
||||
x.IQN = ""
|
||||
} else {
|
||||
yyv19 := &x.IQN
|
||||
yyv19 := &x.TargetPortal
|
||||
yym20 := z.DecBinary()
|
||||
_ = yym20
|
||||
if false {
|
||||
@ -15175,13 +15192,35 @@ func (x *ISCSIVolumeSource) codecDecodeSelfFromArray(l int, d *codec1978.Decoder
|
||||
*((*string)(yyv19)) = r.DecodeString()
|
||||
}
|
||||
}
|
||||
yyj16++
|
||||
if yyhl16 {
|
||||
yyb16 = yyj16 > l
|
||||
yyj18++
|
||||
if yyhl18 {
|
||||
yyb18 = yyj18 > l
|
||||
} else {
|
||||
yyb16 = r.CheckBreak()
|
||||
yyb18 = r.CheckBreak()
|
||||
}
|
||||
if yyb16 {
|
||||
if yyb18 {
|
||||
z.DecSendContainerState(codecSelfer_containerArrayEnd1234)
|
||||
return
|
||||
}
|
||||
z.DecSendContainerState(codecSelfer_containerArrayElem1234)
|
||||
if r.TryDecodeAsNil() {
|
||||
x.IQN = ""
|
||||
} else {
|
||||
yyv21 := &x.IQN
|
||||
yym22 := z.DecBinary()
|
||||
_ = yym22
|
||||
if false {
|
||||
} else {
|
||||
*((*string)(yyv21)) = r.DecodeString()
|
||||
}
|
||||
}
|
||||
yyj18++
|
||||
if yyhl18 {
|
||||
yyb18 = yyj18 > l
|
||||
} else {
|
||||
yyb18 = r.CheckBreak()
|
||||
}
|
||||
if yyb18 {
|
||||
z.DecSendContainerState(codecSelfer_containerArrayEnd1234)
|
||||
return
|
||||
}
|
||||
@ -15189,21 +15228,21 @@ func (x *ISCSIVolumeSource) codecDecodeSelfFromArray(l int, d *codec1978.Decoder
|
||||
if r.TryDecodeAsNil() {
|
||||
x.Lun = 0
|
||||
} else {
|
||||
yyv21 := &x.Lun
|
||||
yym22 := z.DecBinary()
|
||||
_ = yym22
|
||||
yyv23 := &x.Lun
|
||||
yym24 := z.DecBinary()
|
||||
_ = yym24
|
||||
if false {
|
||||
} else {
|
||||
*((*int32)(yyv21)) = int32(r.DecodeInt(32))
|
||||
*((*int32)(yyv23)) = int32(r.DecodeInt(32))
|
||||
}
|
||||
}
|
||||
yyj16++
|
||||
if yyhl16 {
|
||||
yyb16 = yyj16 > l
|
||||
yyj18++
|
||||
if yyhl18 {
|
||||
yyb18 = yyj18 > l
|
||||
} else {
|
||||
yyb16 = r.CheckBreak()
|
||||
yyb18 = r.CheckBreak()
|
||||
}
|
||||
if yyb16 {
|
||||
if yyb18 {
|
||||
z.DecSendContainerState(codecSelfer_containerArrayEnd1234)
|
||||
return
|
||||
}
|
||||
@ -15211,29 +15250,7 @@ func (x *ISCSIVolumeSource) codecDecodeSelfFromArray(l int, d *codec1978.Decoder
|
||||
if r.TryDecodeAsNil() {
|
||||
x.ISCSIInterface = ""
|
||||
} else {
|
||||
yyv23 := &x.ISCSIInterface
|
||||
yym24 := z.DecBinary()
|
||||
_ = yym24
|
||||
if false {
|
||||
} else {
|
||||
*((*string)(yyv23)) = r.DecodeString()
|
||||
}
|
||||
}
|
||||
yyj16++
|
||||
if yyhl16 {
|
||||
yyb16 = yyj16 > l
|
||||
} else {
|
||||
yyb16 = r.CheckBreak()
|
||||
}
|
||||
if yyb16 {
|
||||
z.DecSendContainerState(codecSelfer_containerArrayEnd1234)
|
||||
return
|
||||
}
|
||||
z.DecSendContainerState(codecSelfer_containerArrayElem1234)
|
||||
if r.TryDecodeAsNil() {
|
||||
x.FSType = ""
|
||||
} else {
|
||||
yyv25 := &x.FSType
|
||||
yyv25 := &x.ISCSIInterface
|
||||
yym26 := z.DecBinary()
|
||||
_ = yym26
|
||||
if false {
|
||||
@ -15241,13 +15258,35 @@ func (x *ISCSIVolumeSource) codecDecodeSelfFromArray(l int, d *codec1978.Decoder
|
||||
*((*string)(yyv25)) = r.DecodeString()
|
||||
}
|
||||
}
|
||||
yyj16++
|
||||
if yyhl16 {
|
||||
yyb16 = yyj16 > l
|
||||
yyj18++
|
||||
if yyhl18 {
|
||||
yyb18 = yyj18 > l
|
||||
} else {
|
||||
yyb16 = r.CheckBreak()
|
||||
yyb18 = r.CheckBreak()
|
||||
}
|
||||
if yyb16 {
|
||||
if yyb18 {
|
||||
z.DecSendContainerState(codecSelfer_containerArrayEnd1234)
|
||||
return
|
||||
}
|
||||
z.DecSendContainerState(codecSelfer_containerArrayElem1234)
|
||||
if r.TryDecodeAsNil() {
|
||||
x.FSType = ""
|
||||
} else {
|
||||
yyv27 := &x.FSType
|
||||
yym28 := z.DecBinary()
|
||||
_ = yym28
|
||||
if false {
|
||||
} else {
|
||||
*((*string)(yyv27)) = r.DecodeString()
|
||||
}
|
||||
}
|
||||
yyj18++
|
||||
if yyhl18 {
|
||||
yyb18 = yyj18 > l
|
||||
} else {
|
||||
yyb18 = r.CheckBreak()
|
||||
}
|
||||
if yyb18 {
|
||||
z.DecSendContainerState(codecSelfer_containerArrayEnd1234)
|
||||
return
|
||||
}
|
||||
@ -15255,26 +15294,48 @@ func (x *ISCSIVolumeSource) codecDecodeSelfFromArray(l int, d *codec1978.Decoder
|
||||
if r.TryDecodeAsNil() {
|
||||
x.ReadOnly = false
|
||||
} else {
|
||||
yyv27 := &x.ReadOnly
|
||||
yym28 := z.DecBinary()
|
||||
_ = yym28
|
||||
yyv29 := &x.ReadOnly
|
||||
yym30 := z.DecBinary()
|
||||
_ = yym30
|
||||
if false {
|
||||
} else {
|
||||
*((*bool)(yyv27)) = r.DecodeBool()
|
||||
*((*bool)(yyv29)) = r.DecodeBool()
|
||||
}
|
||||
}
|
||||
yyj18++
|
||||
if yyhl18 {
|
||||
yyb18 = yyj18 > l
|
||||
} else {
|
||||
yyb18 = r.CheckBreak()
|
||||
}
|
||||
if yyb18 {
|
||||
z.DecSendContainerState(codecSelfer_containerArrayEnd1234)
|
||||
return
|
||||
}
|
||||
z.DecSendContainerState(codecSelfer_containerArrayElem1234)
|
||||
if r.TryDecodeAsNil() {
|
||||
x.Portals = nil
|
||||
} else {
|
||||
yyv31 := &x.Portals
|
||||
yym32 := z.DecBinary()
|
||||
_ = yym32
|
||||
if false {
|
||||
} else {
|
||||
z.F.DecSliceStringX(yyv31, false, d)
|
||||
}
|
||||
}
|
||||
for {
|
||||
yyj16++
|
||||
if yyhl16 {
|
||||
yyb16 = yyj16 > l
|
||||
yyj18++
|
||||
if yyhl18 {
|
||||
yyb18 = yyj18 > l
|
||||
} else {
|
||||
yyb16 = r.CheckBreak()
|
||||
yyb18 = r.CheckBreak()
|
||||
}
|
||||
if yyb16 {
|
||||
if yyb18 {
|
||||
break
|
||||
}
|
||||
z.DecSendContainerState(codecSelfer_containerArrayElem1234)
|
||||
z.DecStructFieldNotFound(yyj16-1, "")
|
||||
z.DecStructFieldNotFound(yyj18-1, "")
|
||||
}
|
||||
z.DecSendContainerState(codecSelfer_containerArrayEnd1234)
|
||||
}
|
||||
|
@ -988,6 +988,10 @@ type ISCSIVolumeSource struct {
|
||||
// Defaults to false.
|
||||
// +optional
|
||||
ReadOnly bool `json:"readOnly,omitempty" protobuf:"varint,6,opt,name=readOnly"`
|
||||
// iSCSI target portal List. The portal is either an IP or ip_addr:port if the port
|
||||
// is other than default (typically TCP ports 860 and 3260).
|
||||
// +optional
|
||||
Portals []string `json:"portals" protobuf:"bytes,7,opt,name=portals"`
|
||||
}
|
||||
|
||||
// Represents a Fibre Channel volume.
|
||||
|
@ -637,6 +637,7 @@ var map_ISCSIVolumeSource = map[string]string{
|
||||
"iscsiInterface": "Optional: Defaults to 'default' (tcp). iSCSI interface name that uses an iSCSI transport.",
|
||||
"fsType": "Filesystem type of the volume that you want to mount. Tip: Ensure that the filesystem type is supported by the host operating system. Examples: \"ext4\", \"xfs\", \"ntfs\". Implicitly inferred to be \"ext4\" if unspecified. More info: http://kubernetes.io/docs/user-guide/volumes#iscsi",
|
||||
"readOnly": "ReadOnly here will force the ReadOnly setting in VolumeMounts. Defaults to false.",
|
||||
"portals": "iSCSI target portal List. The portal is either an IP or ip_addr:port if the port is other than default (typically TCP ports 860 and 3260).",
|
||||
}
|
||||
|
||||
func (ISCSIVolumeSource) SwaggerDoc() map[string]string {
|
||||
|
@ -1613,6 +1613,7 @@ func autoConvert_v1_ISCSIVolumeSource_To_api_ISCSIVolumeSource(in *ISCSIVolumeSo
|
||||
out.ISCSIInterface = in.ISCSIInterface
|
||||
out.FSType = in.FSType
|
||||
out.ReadOnly = in.ReadOnly
|
||||
out.Portals = *(*[]string)(unsafe.Pointer(&in.Portals))
|
||||
return nil
|
||||
}
|
||||
|
||||
@ -1627,6 +1628,7 @@ func autoConvert_api_ISCSIVolumeSource_To_v1_ISCSIVolumeSource(in *api.ISCSIVolu
|
||||
out.ISCSIInterface = in.ISCSIInterface
|
||||
out.FSType = in.FSType
|
||||
out.ReadOnly = in.ReadOnly
|
||||
out.Portals = *(*[]string)(unsafe.Pointer(&in.Portals))
|
||||
return nil
|
||||
}
|
||||
|
||||
|
@ -1140,6 +1140,11 @@ func DeepCopy_v1_ISCSIVolumeSource(in interface{}, out interface{}, c *conversio
|
||||
in := in.(*ISCSIVolumeSource)
|
||||
out := out.(*ISCSIVolumeSource)
|
||||
*out = *in
|
||||
if in.Portals != nil {
|
||||
in, out := &in.Portals, &out.Portals
|
||||
*out = make([]string, len(*in))
|
||||
copy(*out, *in)
|
||||
}
|
||||
return nil
|
||||
}
|
||||
}
|
||||
@ -1885,7 +1890,9 @@ func DeepCopy_v1_PersistentVolumeSource(in interface{}, out interface{}, c *conv
|
||||
if in.ISCSI != nil {
|
||||
in, out := &in.ISCSI, &out.ISCSI
|
||||
*out = new(ISCSIVolumeSource)
|
||||
**out = **in
|
||||
if err := DeepCopy_v1_ISCSIVolumeSource(*in, *out, c); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
if in.Cinder != nil {
|
||||
in, out := &in.Cinder, &out.Cinder
|
||||
@ -3155,7 +3162,9 @@ func DeepCopy_v1_VolumeSource(in interface{}, out interface{}, c *conversion.Clo
|
||||
if in.ISCSI != nil {
|
||||
in, out := &in.ISCSI, &out.ISCSI
|
||||
*out = new(ISCSIVolumeSource)
|
||||
**out = **in
|
||||
if err := DeepCopy_v1_ISCSIVolumeSource(*in, *out, c); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
if in.Glusterfs != nil {
|
||||
in, out := &in.Glusterfs, &out.Glusterfs
|
||||
|
@ -1168,6 +1168,11 @@ func DeepCopy_api_ISCSIVolumeSource(in interface{}, out interface{}, c *conversi
|
||||
in := in.(*ISCSIVolumeSource)
|
||||
out := out.(*ISCSIVolumeSource)
|
||||
*out = *in
|
||||
if in.Portals != nil {
|
||||
in, out := &in.Portals, &out.Portals
|
||||
*out = make([]string, len(*in))
|
||||
copy(*out, *in)
|
||||
}
|
||||
return nil
|
||||
}
|
||||
}
|
||||
@ -1934,7 +1939,9 @@ func DeepCopy_api_PersistentVolumeSource(in interface{}, out interface{}, c *con
|
||||
if in.ISCSI != nil {
|
||||
in, out := &in.ISCSI, &out.ISCSI
|
||||
*out = new(ISCSIVolumeSource)
|
||||
**out = **in
|
||||
if err := DeepCopy_api_ISCSIVolumeSource(*in, *out, c); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
if in.FlexVolume != nil {
|
||||
in, out := &in.FlexVolume, &out.FlexVolume
|
||||
@ -3182,7 +3189,9 @@ func DeepCopy_api_VolumeSource(in interface{}, out interface{}, c *conversion.Cl
|
||||
if in.ISCSI != nil {
|
||||
in, out := &in.ISCSI, &out.ISCSI
|
||||
*out = new(ISCSIVolumeSource)
|
||||
**out = **in
|
||||
if err := DeepCopy_api_ISCSIVolumeSource(*in, *out, c); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
if in.Glusterfs != nil {
|
||||
in, out := &in.Glusterfs, &out.Glusterfs
|
||||
|
@ -3017,6 +3017,20 @@ func GetOpenAPIDefinitions(ref openapi.ReferenceCallback) map[string]openapi.Ope
|
||||
Format: "",
|
||||
},
|
||||
},
|
||||
"portals": {
|
||||
SchemaProps: spec.SchemaProps{
|
||||
Description: "iSCSI target portal List. The portal is either an IP or ip_addr:port if the port is other than default (typically TCP ports 860 and 3260).",
|
||||
Type: []string{"array"},
|
||||
Items: &spec.SchemaOrArray{
|
||||
Schema: &spec.Schema{
|
||||
SchemaProps: spec.SchemaProps{
|
||||
Type: []string{"string"},
|
||||
Format: "",
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
Required: []string{"targetPortal", "iqn", "lun"},
|
||||
},
|
||||
|
@ -104,14 +104,18 @@ func (plugin *iscsiPlugin) newMounterInternal(spec *volume.Spec, podUID types.UI
|
||||
|
||||
lun := strconv.Itoa(int(iscsi.Lun))
|
||||
portal := portalMounter(iscsi.TargetPortal)
|
||||
|
||||
var bkportal []string
|
||||
bkportal = append(bkportal, portal)
|
||||
for _, tp := range iscsi.Portals {
|
||||
bkportal = append(bkportal, portalMounter(string(tp)))
|
||||
}
|
||||
iface := iscsi.ISCSIInterface
|
||||
|
||||
return &iscsiDiskMounter{
|
||||
iscsiDisk: &iscsiDisk{
|
||||
podUID: podUID,
|
||||
volName: spec.Name(),
|
||||
portal: portal,
|
||||
portals: bkportal,
|
||||
iqn: iscsi.IQN,
|
||||
lun: lun,
|
||||
iface: iface,
|
||||
@ -162,7 +166,7 @@ func (plugin *iscsiPlugin) ConstructVolumeSpec(volumeName, mountPath string) (*v
|
||||
type iscsiDisk struct {
|
||||
volName string
|
||||
podUID types.UID
|
||||
portal string
|
||||
portals []string
|
||||
iqn string
|
||||
lun string
|
||||
iface string
|
||||
|
@ -98,13 +98,13 @@ func makePDNameInternal(host volume.VolumeHost, portal string, iqn string, lun s
|
||||
type ISCSIUtil struct{}
|
||||
|
||||
func (util *ISCSIUtil) MakeGlobalPDName(iscsi iscsiDisk) string {
|
||||
return makePDNameInternal(iscsi.plugin.host, iscsi.portal, iscsi.iqn, iscsi.lun)
|
||||
return makePDNameInternal(iscsi.plugin.host, iscsi.portals[0], iscsi.iqn, iscsi.lun)
|
||||
}
|
||||
|
||||
func (util *ISCSIUtil) AttachDisk(b iscsiDiskMounter) error {
|
||||
var devicePath string
|
||||
var devicePaths []string
|
||||
var iscsiTransport string
|
||||
|
||||
out, err := b.plugin.execCommand("iscsiadm", []string{"-m", "iface", "-I", b.iface, "-o", "show"})
|
||||
if err != nil {
|
||||
glog.Errorf("iscsi: could not read iface %s error: %s", b.iface, string(out))
|
||||
@ -112,34 +112,50 @@ func (util *ISCSIUtil) AttachDisk(b iscsiDiskMounter) error {
|
||||
}
|
||||
|
||||
iscsiTransport = extractTransportname(string(out))
|
||||
bkpPortal := b.portals
|
||||
for _, tp := range bkpPortal {
|
||||
if iscsiTransport == "" {
|
||||
glog.Errorf("iscsi: could not find transport name in iface %s", b.iface)
|
||||
return errors.New(fmt.Sprintf("Could not parse iface file for %s", b.iface))
|
||||
} else if iscsiTransport == "tcp" {
|
||||
devicePath = strings.Join([]string{"/dev/disk/by-path/ip", tp, "iscsi", b.iqn, "lun", b.lun}, "-")
|
||||
} else {
|
||||
devicePath = strings.Join([]string{"/dev/disk/by-path/pci", "*", "ip", tp, "iscsi", b.iqn, "lun", b.lun}, "-")
|
||||
}
|
||||
exist := waitForPathToExist(devicePath, 1, iscsiTransport)
|
||||
if exist == false {
|
||||
// discover iscsi target
|
||||
out, err := b.plugin.execCommand("iscsiadm", []string{"-m", "discovery", "-t", "sendtargets", "-p", tp, "-I", b.iface})
|
||||
if err != nil {
|
||||
glog.Errorf("iscsi: failed to sendtargets to portal %s error: %s", tp, string(out))
|
||||
continue
|
||||
}
|
||||
// login to iscsi target
|
||||
out, err = b.plugin.execCommand("iscsiadm", []string{"-m", "node", "-p", tp, "-T", b.iqn, "-I", b.iface, "--login"})
|
||||
if err != nil {
|
||||
glog.Errorf("iscsi: failed to attach disk:Error: %s (%v)", string(out), err)
|
||||
continue
|
||||
}
|
||||
exist = waitForPathToExist(devicePath, 10, iscsiTransport)
|
||||
if !exist {
|
||||
glog.Errorf("Could not attach disk: Timeout after 10s")
|
||||
} else {
|
||||
devicePaths = append(devicePaths, devicePath)
|
||||
}
|
||||
} else {
|
||||
glog.V(4).Infof("iscsi: devicepath (%s) exists", devicePath)
|
||||
devicePaths = append(devicePaths, devicePath)
|
||||
}
|
||||
}
|
||||
|
||||
if iscsiTransport == "" {
|
||||
glog.Errorf("iscsi: could not find transport name in iface %s", b.iface)
|
||||
return errors.New(fmt.Sprintf("Could not parse iface file for %s", b.iface))
|
||||
} else if iscsiTransport == "tcp" {
|
||||
devicePath = strings.Join([]string{"/dev/disk/by-path/ip", b.portal, "iscsi", b.iqn, "lun", b.lun}, "-")
|
||||
} else {
|
||||
devicePath = strings.Join([]string{"/dev/disk/by-path/pci", "*", "ip", b.portal, "iscsi", b.iqn, "lun", b.lun}, "-")
|
||||
}
|
||||
exist := waitForPathToExist(devicePath, 1, iscsiTransport)
|
||||
if exist == false {
|
||||
// discover iscsi target
|
||||
out, err := b.plugin.execCommand("iscsiadm", []string{"-m", "discovery", "-t", "sendtargets", "-p", b.portal, "-I", b.iface})
|
||||
if err != nil {
|
||||
glog.Errorf("iscsi: failed to sendtargets to portal %s error: %s", b.portal, string(out))
|
||||
return err
|
||||
}
|
||||
// login to iscsi target
|
||||
out, err = b.plugin.execCommand("iscsiadm", []string{"-m", "node", "-p", b.portal, "-T", b.iqn, "-I", b.iface, "--login"})
|
||||
if err != nil {
|
||||
glog.Errorf("iscsi: failed to attach disk:Error: %s (%v)", string(out), err)
|
||||
return err
|
||||
}
|
||||
exist = waitForPathToExist(devicePath, 10, iscsiTransport)
|
||||
if !exist {
|
||||
return errors.New("Could not attach disk: Timeout after 10s")
|
||||
}
|
||||
if len(devicePaths) == 0 {
|
||||
glog.Errorf("iscsi: failed to get any path for iscsi disk")
|
||||
return errors.New("failed to get any path for iscsi disk")
|
||||
}
|
||||
|
||||
//Make sure we use a valid devicepath to find mpio device.
|
||||
devicePath = devicePaths[0]
|
||||
|
||||
// mount it
|
||||
globalPDPath := b.manager.MakeGlobalPDName(*b.iscsiDisk)
|
||||
notMnt, err := b.mounter.IsLikelyNotMountPoint(globalPDPath)
|
||||
@ -153,9 +169,17 @@ func (util *ISCSIUtil) AttachDisk(b iscsiDiskMounter) error {
|
||||
return err
|
||||
}
|
||||
|
||||
// check if the dev is using mpio and if so mount it via the dm-XX device
|
||||
if mappedDevicePath := b.deviceUtil.FindMultipathDeviceForDevice(devicePath); mappedDevicePath != "" {
|
||||
devicePath = mappedDevicePath
|
||||
for _, path := range devicePaths {
|
||||
// There shouldnt be any empty device paths. However adding this check
|
||||
// for safer side to avoid the possibility of an empty entry.
|
||||
if path == "" {
|
||||
continue
|
||||
}
|
||||
// check if the dev is using mpio and if so mount it via the dm-XX device
|
||||
if mappedDevicePath := b.deviceUtil.FindMultipathDeviceForDevice(path); mappedDevicePath != "" {
|
||||
devicePath = mappedDevicePath
|
||||
break
|
||||
}
|
||||
}
|
||||
err = b.mounter.FormatAndMount(devicePath, globalPDPath, b.fsType, nil)
|
||||
if err != nil {
|
||||
|
Loading…
Reference in New Issue
Block a user