Skip to content
Projects
Groups
Snippets
Help
This project
Loading...
Sign in / Register
Toggle navigation
K
k3s
Project
Project
Details
Activity
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
0
Issues
0
List
Board
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Charts
Registry
Registry
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
Jacklull
k3s
Commits
7189db37
Commit
7189db37
authored
Jan 22, 2016
by
Zach Loafman
Browse files
Options
Browse Files
Download
Plain Diff
Merge pull request #19396 from justinsb/aws_mountdevice
AWS: Use a strongly typed mountDevice
parents
4803b8a9
03900b1d
Hide whitespace changes
Inline
Side-by-side
Showing
1 changed file
with
35 additions
and
27 deletions
+35
-27
aws.go
pkg/cloudprovider/providers/aws/aws.go
+35
-27
No files found.
pkg/cloudprovider/providers/aws/aws.go
View file @
7189db37
...
...
@@ -820,12 +820,16 @@ func (self *AWSCloud) GetZone() (cloudprovider.Zone, error) {
type
awsInstanceType
struct
{
}
// Used to represent a mount device for attaching an EBS volume
// This should be stored as a single letter (i.e. c, not sdc or /dev/sdc)
type
mountDevice
string
// TODO: Also return number of mounts allowed?
func
(
self
*
awsInstanceType
)
getEBSMountDevices
()
[]
string
{
func
(
self
*
awsInstanceType
)
getEBSMountDevices
()
[]
mountDevice
{
// See: https://docs.aws.amazon.com/AWSEC2/latest/UserGuide/block-device-mapping-concepts.html
devices
:=
[]
string
{}
devices
:=
[]
mountDevice
{}
for
c
:=
'f'
;
c
<=
'p'
;
c
++
{
devices
=
append
(
devices
,
fmt
.
Sprintf
(
"%c"
,
c
))
devices
=
append
(
devices
,
mountDevice
(
fmt
.
Sprintf
(
"%c"
,
c
)
))
}
return
devices
}
...
...
@@ -846,7 +850,7 @@ type awsInstance struct {
// We must cache because otherwise there is a race condition,
// where we assign a device mapping and then get a second request before we attach the volume
deviceMappings
map
[
string
]
string
deviceMappings
map
[
mountDevice
]
string
}
func
newAWSInstance
(
ec2
EC2
,
awsID
,
nodeName
string
,
availabilityZone
string
)
*
awsInstance
{
...
...
@@ -885,9 +889,10 @@ func (self *awsInstance) getInfo() (*ec2.Instance, error) {
return
instances
[
0
],
nil
}
// Assigns an unused mountpoint (device) for the specified volume.
// If the volume is already assigned, this will return the existing mountpoint and true
func
(
self
*
awsInstance
)
assignMountpoint
(
volumeID
string
)
(
mountpoint
string
,
alreadyAttached
bool
,
err
error
)
{
// Gets the mountDevice already assigned to the volume, or assigns an unused mountDevice.
// If the volume is already assigned, this will return the existing mountDevice with alreadyAttached=true.
// Otherwise the mountDevice is assigned by finding the first available mountDevice, and it is returned with alreadyAttached=false.
func
(
self
*
awsInstance
)
getMountDevice
(
volumeID
string
)
(
assigned
mountDevice
,
alreadyAttached
bool
,
err
error
)
{
instanceType
:=
self
.
getInstanceType
()
if
instanceType
==
nil
{
return
""
,
false
,
fmt
.
Errorf
(
"could not get instance type for instance: %s"
,
self
.
awsID
)
...
...
@@ -905,35 +910,38 @@ func (self *awsInstance) assignMountpoint(volumeID string) (mountpoint string, a
if
err
!=
nil
{
return
""
,
false
,
err
}
deviceMappings
:=
map
[
string
]
string
{}
deviceMappings
:=
map
[
mountDevice
]
string
{}
for
_
,
blockDevice
:=
range
info
.
BlockDeviceMappings
{
mountpoint
:=
orEmpty
(
blockDevice
.
DeviceName
)
if
strings
.
HasPrefix
(
mountpoint
,
"/dev/sd"
)
{
mountpoint
=
mountpoint
[
7
:
]
name
:=
aws
.
StringValue
(
blockDevice
.
DeviceName
)
if
strings
.
HasPrefix
(
name
,
"/dev/sd"
)
{
name
=
name
[
7
:
]
}
if
strings
.
HasPrefix
(
name
,
"/dev/xvd"
)
{
name
=
name
[
8
:
]
}
if
strings
.
HasPrefix
(
mountpoint
,
"/dev/xvd"
)
{
mountpoint
=
mountpoint
[
8
:
]
if
len
(
name
)
!=
1
{
glog
.
Warningf
(
"Unexpected EBS DeviceName: %q"
,
aws
.
StringValue
(
blockDevice
.
DeviceName
))
}
deviceMappings
[
mount
point
]
=
orEmpty
(
blockDevice
.
Ebs
.
VolumeId
)
deviceMappings
[
mount
Device
(
name
)]
=
aws
.
StringValue
(
blockDevice
.
Ebs
.
VolumeId
)
}
self
.
deviceMappings
=
deviceMappings
}
// Check to see if this volume is already assigned a device on this machine
for
mount
point
,
mappingVolumeID
:=
range
self
.
deviceMappings
{
for
mount
Device
,
mappingVolumeID
:=
range
self
.
deviceMappings
{
if
volumeID
==
mappingVolumeID
{
glog
.
Warningf
(
"Got assignment call for already-assigned volume: %s@%s"
,
mount
point
,
mappingVolumeID
)
return
mount
point
,
true
,
nil
glog
.
Warningf
(
"Got assignment call for already-assigned volume: %s@%s"
,
mount
Device
,
mappingVolumeID
)
return
mount
Device
,
true
,
nil
}
}
// Check all the valid mountpoints to see if any of them are free
valid
:=
instanceType
.
getEBSMountDevices
()
chosen
:=
""
for
_
,
d
evice
:=
range
valid
{
_
,
found
:=
self
.
deviceMappings
[
d
evice
]
chosen
:=
mountDevice
(
""
)
for
_
,
mountD
evice
:=
range
valid
{
_
,
found
:=
self
.
deviceMappings
[
mountD
evice
]
if
!
found
{
chosen
=
d
evice
chosen
=
mountD
evice
break
}
}
...
...
@@ -949,7 +957,7 @@ func (self *awsInstance) assignMountpoint(volumeID string) (mountpoint string, a
return
chosen
,
false
,
nil
}
func
(
self
*
awsInstance
)
releaseMountDevice
(
volumeID
string
,
mountDevice
string
)
{
func
(
self
*
awsInstance
)
releaseMountDevice
(
volumeID
string
,
mountDevice
mountDevice
)
{
self
.
mutex
.
Lock
()
defer
self
.
mutex
.
Unlock
()
...
...
@@ -1155,24 +1163,24 @@ func (c *AWSCloud) AttachDisk(instanceName string, diskName string, readOnly boo
return
""
,
errors
.
New
(
"AWS volumes cannot be mounted read-only"
)
}
mount
point
,
alreadyAttached
,
err
:=
awsInstance
.
assignMountpoint
(
disk
.
awsID
)
mount
Device
,
alreadyAttached
,
err
:=
awsInstance
.
getMountDevice
(
disk
.
awsID
)
if
err
!=
nil
{
return
""
,
err
}
// Inside the instance, the mountpoint always looks like /dev/xvdX (?)
hostDevice
:=
"/dev/xvd"
+
mountpoint
hostDevice
:=
"/dev/xvd"
+
string
(
mountDevice
)
// In the EC2 API, it is sometimes is /dev/sdX and sometimes /dev/xvdX
// We are running on the node here, so we check if /dev/xvda exists to determine this
ec2Device
:=
"/dev/xvd"
+
mountpoint
ec2Device
:=
"/dev/xvd"
+
string
(
mountDevice
)
if
_
,
err
:=
os
.
Stat
(
"/dev/xvda"
);
os
.
IsNotExist
(
err
)
{
ec2Device
=
"/dev/sd"
+
mountpoint
ec2Device
=
"/dev/sd"
+
string
(
mountDevice
)
}
attached
:=
false
defer
func
()
{
if
!
attached
{
awsInstance
.
releaseMountDevice
(
disk
.
awsID
,
mount
point
)
awsInstance
.
releaseMountDevice
(
disk
.
awsID
,
mount
Device
)
}
}()
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment