Created
June 7, 2018 05:42
-
-
Save JustinVenus/7d26ff5e885dc0ed34951ce20e5e79e0 to your computer and use it in GitHub Desktop.
RexRay EBS Volume Workaround for M5/C5
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
UDEV rules and script Based on https://gist.github.com/jalaziz/bcfe2f71e3f7e8fe42a9c294c1e9279f. | |
Requires `nvme-cli` package found at https://github.com/linux-nvme/nvme-cli. | |
Based on rexray commit d5cf3ed1aac75a4595760fc0830beea5886588f0 | |
```sh | |
[root@ip-172-31-2-242 ~]# /usr/bin/dvdcli --volumedriver=rexray --volumename=mesos-master01fu2.aws.sig path | |
INFO[0000] /var/lib/rexray/volumes/mesos-master01fu2.aws.sig/data | |
/var/lib/rexray/volumes/mesos-master01fu2.aws.sig/data | |
[root@ip-172-31-2-242 ~]# mount | grep mesos-master01fu2.aws.sig | |
/dev/nvme0n1 on /var/lib/rexray/volumes/mesos-master01fu2.aws.sig type ext4 (rw,relatime,data=ordered) | |
[root@ip-172-31-2-242 ~]# cat /etc/udev/rules.d/999-aws-ebs-nvme.rules | |
# ebs nvme devices | |
KERNEL=="nvme[0-9]*n[0-9]*", ENV{DEVTYPE}=="disk", ATTRS{model}=="Amazon Elastic Block Store", PROGRAM="/usr/local/bin/ebs-nvme-mapping /dev/%k", SYMLINK+="%c" | |
[root@ip-172-31-2-242 ~]# cat /usr/local/bin/ebs-nvme-mapping | |
#!/bin/bash | |
vol=$(/usr/sbin/nvme id-ctrl --raw-binary "$1" | cut -c3073-3104 | tr -s ' ' | sed 's/ $//g') | |
vol=${vol#/dev/} | |
if [[ -n "$vol" ]]; then | |
echo ${vol/xvd/sd} ${vol/sd/xvd} | |
fi | |
``` | |
RexRay Changes that works w/ udev rules to mount EBS volumes on M5/C5 | |
``` | |
diff --git a/libstorage/drivers/storage/ebs/executor/ebs_executor.go b/libstorage/drivers/storage/ebs/executor/ebs_executor.go | |
index aa00a86d..2d1bd352 100644 | |
--- a/libstorage/drivers/storage/ebs/executor/ebs_executor.go | |
+++ b/libstorage/drivers/storage/ebs/executor/ebs_executor.go | |
@@ -15,6 +15,7 @@ import ( | |
"github.com/akutz/goof" | |
log "github.com/sirupsen/logrus" | |
+ "github.com/rexray/rexray/libstorage/api/context" | |
"github.com/rexray/rexray/libstorage/api/registry" | |
"github.com/rexray/rexray/libstorage/api/types" | |
"github.com/rexray/rexray/libstorage/drivers/storage/ebs" | |
@@ -49,7 +50,8 @@ func (d *driver) Init(ctx types.Context, config gofig.Config) error { | |
// initialize device range config | |
useLargeDeviceRange := d.config.GetBool(ebs.ConfigUseLargeDeviceRange) | |
log.Debug("executor using large device range: ", useLargeDeviceRange) | |
- d.deviceRange = ebsUtils.GetDeviceRange(useLargeDeviceRange) | |
+ d.deviceRange = ebsUtils.GetDeviceRange( | |
+ useLargeDeviceRange, d.InstanceType(ctx)) | |
return nil | |
} | |
@@ -74,6 +76,15 @@ func (d *driver) InstanceID( | |
return ebsUtils.InstanceID(ctx, d.Name()) | |
} | |
+func (d *driver) InstanceType(ctx types.Context) string { | |
+ if iid, ok := context.InstanceID(ctx); ok { | |
+ if v, ok := iid.Fields["instanceType"]; ok && v != "" { | |
+ return v | |
+ } | |
+ } | |
+ return "default" | |
+} | |
+ | |
var errNoAvaiDevice = goof.New("no available device") | |
// NextDevice returns the next available device. | |
@@ -170,6 +181,7 @@ func (d *driver) LocalDevices( | |
} | |
devPath := path.Join("/dev/", devName) | |
devMap[devPath] = devPath | |
+ log.Debug("LocalDevice: ", devPath) | |
} | |
ld := &types.LocalDevices{Driver: d.Name()} | |
diff --git a/libstorage/drivers/storage/ebs/storage/ebs_storage.go b/libstorage/drivers/storage/ebs/storage/ebs_storage.go | |
index f5dd44e2..8589813d 100644 | |
--- a/libstorage/drivers/storage/ebs/storage/ebs_storage.go | |
+++ b/libstorage/drivers/storage/ebs/storage/ebs_storage.go | |
@@ -4,6 +4,7 @@ import ( | |
"crypto/md5" | |
"fmt" | |
"hash" | |
+ "path/filepath" | |
"strings" | |
"sync" | |
"time" | |
@@ -103,7 +104,8 @@ func (d *driver) Init(context types.Context, config gofig.Config) error { | |
} | |
useLargeDeviceRange := d.config.GetBool(ebs.ConfigUseLargeDeviceRange) | |
- d.deviceRange = ebsUtils.GetDeviceRange(useLargeDeviceRange) | |
+ d.deviceRange = ebsUtils.GetDeviceRange( | |
+ useLargeDeviceRange, d.InstanceType(context)) | |
log.Info("storage driver initialized, using large device range: ", | |
useLargeDeviceRange) | |
@@ -216,6 +218,15 @@ func mustInstanceIDID(ctx types.Context) *string { | |
return &context.MustInstanceID(ctx).ID | |
} | |
+func (d *driver) InstanceType(ctx types.Context) string { | |
+ if iid, ok := context.InstanceID(ctx); ok { | |
+ if v, ok := iid.Fields["instanceType"]; ok && v != "" { | |
+ return v | |
+ } | |
+ } | |
+ return "default" | |
+} | |
+ | |
func (d *driver) mustRegion(ctx types.Context) *string { | |
if iid, ok := context.InstanceID(ctx); ok { | |
if v, ok := iid.Fields[ebs.InstanceIDFieldRegion]; ok && v != "" { | |
@@ -959,7 +970,20 @@ func (d *driver) toTypesVolume( | |
d.deviceRange.NextDeviceInfo.Prefix, 1) | |
// Keep device name if it is found in local devices | |
if _, ok := ld.DeviceMap[deviceName]; !ok { | |
- deviceName = "" | |
+ device, err := filepath.EvalSymlinks(deviceName) | |
+ if err != nil { | |
+ log.Error(err) | |
+ deviceName = "" | |
+ } else { | |
+ log.Info(fmt.Sprintf("nvme: %s => %s", deviceName, device)) | |
+ if _, ok2 := ld.DeviceMap[device]; ! ok2 { | |
+ deviceName = "" | |
+ } else { | |
+ log.Debug("Detected NVME deviceName: ", deviceName) | |
+ } | |
+ } | |
+ } else { | |
+ log.Debug("Detected deviceName: ", deviceName) | |
} | |
} | |
attachmentSD := &types.VolumeAttachment{ | |
diff --git a/libstorage/drivers/storage/ebs/utils/utils.go b/libstorage/drivers/storage/ebs/utils/utils.go | |
index 70f644eb..1151fe8d 100644 | |
--- a/libstorage/drivers/storage/ebs/utils/utils.go | |
+++ b/libstorage/drivers/storage/ebs/utils/utils.go | |
@@ -44,6 +44,7 @@ type instanceIdentityDoc struct { | |
InstanceID string `json:"instanceId,omitempty"` | |
Region string `json:"region,omitempty"` | |
AvailabilityZone string `json:"availabilityZone,omitempty"` | |
+ InstanceType string `json:"instanceType,omitempty"` | |
} | |
// InstanceID returns the instance ID for the local host. | |
@@ -74,6 +75,7 @@ func InstanceID( | |
Fields: map[string]string{ | |
ebs.InstanceIDFieldRegion: iid.Region, | |
ebs.InstanceIDFieldAvailabilityZone: iid.AvailabilityZone, | |
+ "instanceType": iid.InstanceType, | |
}, | |
}, nil | |
} | |
diff --git a/libstorage/drivers/storage/ebs/utils/utils_unix.go b/libstorage/drivers/storage/ebs/utils/utils_unix.go | |
index 4a06b35e..d9cd7260 100644 | |
--- a/libstorage/drivers/storage/ebs/utils/utils_unix.go | |
+++ b/libstorage/drivers/storage/ebs/utils/utils_unix.go | |
@@ -4,7 +4,9 @@ package utils | |
import ( | |
"regexp" | |
+ "strings" | |
+ log "github.com/sirupsen/logrus" | |
"github.com/rexray/rexray/libstorage/api/types" | |
) | |
@@ -49,10 +51,27 @@ var ( | |
}, | |
DeviceRE: regexp.MustCompile(`^xvd[f-p]$`), | |
} | |
+ nvmeDeviceRange = &DeviceRange{ | |
+ ParentLetters: []string{"0"}, | |
+ ChildLetters: []string{ | |
+ "0", "1", "2", "3", "4", "5", "6", "7", "8", "9", "10", "11", "12", "13", | |
+ "14", "15", "16", "17", "18", "19", "20", "21", "22", "23", "24", "25", "26"}, | |
+ NextDeviceInfo: &types.NextDeviceInfo{ | |
+ Prefix: "nvme", | |
+ Pattern: "[0-26]n.*", | |
+ Ignore: false, | |
+ }, | |
+ DeviceRE: regexp.MustCompile(`^nvme[0-26]n.*`), | |
+ } | |
) | |
// GetDeviceRange returns a specified DeviceRange object | |
-func GetDeviceRange(useLargeDeviceRange bool) *DeviceRange { | |
+func GetDeviceRange(useLargeDeviceRange bool, instanceType string) *DeviceRange { | |
+ log.Debug("InstanceType: ", instanceType) | |
+ if strings.HasPrefix(instanceType, "c5") || strings.HasPrefix(instanceType, "m5") { | |
+ log.Debug("nvme device") | |
+ return nvmeDeviceRange | |
+ } | |
if useLargeDeviceRange { | |
return largeDeviceRange | |
} | |
``` |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
@JustinVenus I'm pleased that you've discovered my solution[1] for dealing with NVMe devices in AWS by way of the CoreOS project, but as a courtesy, can you include a copy of the license and copyright notice[2] in your derivative work?
1: https://github.com/oogali/ebs-automatic-nvme-mapping
2: https://github.com/oogali/ebs-automatic-nvme-mapping/blob/master/LICENSE