Skip to content

Instantly share code, notes, and snippets.

Show Gist options
  • Star 1 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save JustinVenus/7d26ff5e885dc0ed34951ce20e5e79e0 to your computer and use it in GitHub Desktop.
Save JustinVenus/7d26ff5e885dc0ed34951ce20e5e79e0 to your computer and use it in GitHub Desktop.
RexRay EBS Volume Workaround for M5/C5
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
}
```
@oogali
Copy link

oogali commented Jun 11, 2018

@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

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment