Skip to content

Commit

Permalink
Merge pull request #14 from NearNodeFlash/feature/persistent
Browse files Browse the repository at this point in the history
Persistent Storage API
  • Loading branch information
Nate Roiger authored Jul 20, 2022
2 parents e3216b0 + d6f3600 commit 4fb0436
Show file tree
Hide file tree
Showing 15 changed files with 447 additions and 110 deletions.
6 changes: 6 additions & 0 deletions pkg/controller.go
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,7 @@ import (
nnf "github.com/NearNodeFlash/nnf-ec/pkg/manager-nnf"
nvme "github.com/NearNodeFlash/nnf-ec/pkg/manager-nvme"
telemetry "github.com/NearNodeFlash/nnf-ec/pkg/manager-telemetry"
"github.com/NearNodeFlash/nnf-ec/pkg/persistent"
log "github.com/sirupsen/logrus"
)

Expand All @@ -54,6 +55,7 @@ type Options struct {
cli bool // Enable CLI commands instead of binary
persistence bool // Enable persistent object storage; used during crash/reboot recovery

json string // Initialize the element controller with the provided json file
direct string // Enable direct management of NVMe devices matching this regexp pattern
}

Expand All @@ -71,6 +73,7 @@ func BindFlags(fs *flag.FlagSet) *Options {
fs.BoolVar(&opts.mock, "mock", opts.mock, "Enable mock (simulated) environment.")
fs.BoolVar(&opts.cli, "cli", opts.cli, "Enable CLI interfaces with devices, instead of raw binary.")
fs.BoolVar(&opts.persistence, "persistence", opts.persistence, "Enable persistent object storage (used during crash/reboot recovery)")
fs.StringVar(&opts.json, "json", "", "Initialize database with provided json file")
fs.StringVar(&opts.direct, "direct", opts.direct, "Enable direct management of NVMe block devices matching this regexp pattern. Implies Mock.")

nvme.BindFlags(fs)
Expand Down Expand Up @@ -106,7 +109,10 @@ func NewController(opts *Options) *ec.Controller {
} else {
nnfCtrl = nnf.NewMockNnfController(opts.persistence)
}
}

if len(opts.json) != 0 {
persistent.StorageProvider = persistent.NewJsonFilePersistentStorageProvider(opts.json)
}

return &ec.Controller{
Expand Down
6 changes: 3 additions & 3 deletions pkg/manager-nnf/file_share.go
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@ import (
"fmt"
"strings"

"github.com/NearNodeFlash/nnf-ec/internal/kvstore"
"github.com/NearNodeFlash/nnf-ec/pkg/persistent"
sf "github.com/NearNodeFlash/nnf-ec/pkg/rfsf/pkg/models"
)

Expand Down Expand Up @@ -134,13 +134,13 @@ type fileShareRecoveryRegistry struct {
storageService *StorageService
}

func NewFileShareRecoveryRegistry(s *StorageService) kvstore.Registry {
func NewFileShareRecoveryRegistry(s *StorageService) persistent.Registry {
return &fileShareRecoveryRegistry{storageService: s}
}

func (r *fileShareRecoveryRegistry) Prefix() string { return fileShareRegistryPrefix }

func (r *fileShareRecoveryRegistry) NewReplay(id string) kvstore.ReplayHandler {
func (r *fileShareRecoveryRegistry) NewReplay(id string) persistent.ReplayHandler {
ids := strings.SplitN(id, ":", 2)

return &fileShareRecoveryReplayHandler{
Expand Down
7 changes: 3 additions & 4 deletions pkg/manager-nnf/file_system.go
Original file line number Diff line number Diff line change
Expand Up @@ -26,8 +26,7 @@ import (

server "github.com/NearNodeFlash/nnf-ec/pkg/manager-server"
sf "github.com/NearNodeFlash/nnf-ec/pkg/rfsf/pkg/models"

"github.com/NearNodeFlash/nnf-ec/internal/kvstore"
"github.com/NearNodeFlash/nnf-ec/pkg/persistent"
)

type FileSystem struct {
Expand Down Expand Up @@ -162,13 +161,13 @@ type fileSystemRecoveryRegistry struct {
storageService *StorageService
}

func NewFileSystemRecoveryRegistry(s *StorageService) kvstore.Registry {
func NewFileSystemRecoveryRegistry(s *StorageService) persistent.Registry {
return &fileSystemRecoveryRegistry{storageService: s}
}

func (*fileSystemRecoveryRegistry) Prefix() string { return fileSystemRegistryPrefix }

func (r *fileSystemRecoveryRegistry) NewReplay(id string) kvstore.ReplayHandler {
func (r *fileSystemRecoveryRegistry) NewReplay(id string) persistent.ReplayHandler {
return &fileSystemRecoveryReplyHandler{
fileSystemId: id,
storageService: r.storageService,
Expand Down
15 changes: 9 additions & 6 deletions pkg/manager-nnf/manager.go
Original file line number Diff line number Diff line change
Expand Up @@ -28,18 +28,21 @@ import (
"github.com/google/uuid"
log "github.com/sirupsen/logrus"

"github.com/NearNodeFlash/nnf-ec/internal/kvstore"
ec "github.com/NearNodeFlash/nnf-ec/pkg/ec"
event "github.com/NearNodeFlash/nnf-ec/pkg/manager-event"
fabric "github.com/NearNodeFlash/nnf-ec/pkg/manager-fabric"
msgreg "github.com/NearNodeFlash/nnf-ec/pkg/manager-message-registry/registries"
nvme "github.com/NearNodeFlash/nnf-ec/pkg/manager-nvme"
server "github.com/NearNodeFlash/nnf-ec/pkg/manager-server"
"github.com/NearNodeFlash/nnf-ec/pkg/persistent"
openapi "github.com/NearNodeFlash/nnf-ec/pkg/rfsf/pkg/common"
sf "github.com/NearNodeFlash/nnf-ec/pkg/rfsf/pkg/models"
)

var storageService = StorageService{}
var storageService = StorageService{
id: DefaultStorageServiceId,
state: sf.DISABLED_RST,
}

func NewDefaultStorageService() StorageServiceApi {
return NewAerService(&storageService) // Wrap the default storage service with Advanced Error Reporting capabilities
Expand All @@ -51,7 +54,7 @@ type StorageService struct {
health sf.ResourceHealth

config *ConfigFile
store *kvstore.Store
store *persistent.Store
serverControllerProvider server.ServerControllerProvider
persistentController PersistentControllerApi

Expand All @@ -74,7 +77,7 @@ func (s *StorageService) OdataIdRef(ref string) sf.OdataV4IdRef {
return sf.OdataV4IdRef{OdataId: fmt.Sprintf("%s%s", s.OdataId(), ref)}
}

func (s *StorageService) GetStore() *kvstore.Store {
func (s *StorageService) GetStore() *persistent.Store {
return s.store
}

Expand Down Expand Up @@ -424,12 +427,12 @@ func (*StorageService) Initialize(ctrl NnfControllerInterface) error {

// Create the key-value storage database
{
s.store, err = kvstore.Open("nnf.db", false)
s.store, err = persistent.Open("nnf.db", false)
if err != nil {
return err
}

s.store.Register([]kvstore.Registry{
s.store.Register([]persistent.Registry{
NewStoragePoolRecoveryRegistry(s),
NewStorageGroupRecoveryRegistry(s),
NewFileSystemRecoveryRegistry(s),
Expand Down
7 changes: 4 additions & 3 deletions pkg/manager-nnf/persistent.go
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@
package nnf

import (
"github.com/NearNodeFlash/nnf-ec/internal/kvstore"
"github.com/NearNodeFlash/nnf-ec/pkg/persistent"
log "github.com/sirupsen/logrus"
)

Expand All @@ -37,8 +37,9 @@ func NewDefaultPersistentController() PersistentControllerApi {
return &DefaultPersistentController{}
}

// Persistent Store Provider provides an interface for supplying a Key-Value Store
type PersistentStoreProvider interface {
GetStore() *kvstore.Store
GetStore() *persistent.Store
}

// Persistent Object API provides interface for creating or updating a persistent object.
Expand Down Expand Up @@ -107,7 +108,7 @@ func (*DefaultPersistentController) DeletePersistentObject(obj PersistentObjectA
return ledger.Close(true)
}

func executePersistentObjectTransaction(ledger *kvstore.Ledger, obj PersistentObjectApi, updateFunc func() error, startingState, endingState uint32) error {
func executePersistentObjectTransaction(ledger *persistent.Ledger, obj PersistentObjectApi, updateFunc func() error, startingState, endingState uint32) error {

data, err := obj.GenerateStateData(startingState)
if err != nil {
Expand Down
7 changes: 3 additions & 4 deletions pkg/manager-nnf/storage_group.go
Original file line number Diff line number Diff line change
Expand Up @@ -25,8 +25,7 @@ import (

nvme "github.com/NearNodeFlash/nnf-ec/pkg/manager-nvme"
server "github.com/NearNodeFlash/nnf-ec/pkg/manager-server"

"github.com/NearNodeFlash/nnf-ec/internal/kvstore"
"github.com/NearNodeFlash/nnf-ec/pkg/persistent"
sf "github.com/NearNodeFlash/nnf-ec/pkg/rfsf/pkg/models"
)

Expand Down Expand Up @@ -156,13 +155,13 @@ type storageGroupRecoveryRegistry struct {
storageService *StorageService
}

func NewStorageGroupRecoveryRegistry(s *StorageService) kvstore.Registry {
func NewStorageGroupRecoveryRegistry(s *StorageService) persistent.Registry {
return &storageGroupRecoveryRegistry{storageService: s}
}

func (r *storageGroupRecoveryRegistry) Prefix() string { return storageGroupRegistryPrefix }

func (r *storageGroupRecoveryRegistry) NewReplay(id string) kvstore.ReplayHandler {
func (r *storageGroupRecoveryRegistry) NewReplay(id string) persistent.ReplayHandler {
return &storageGroupRecoveryReplyHandler{id: id, storageService: r.storageService}
}

Expand Down
6 changes: 3 additions & 3 deletions pkg/manager-nnf/storage_pool.go
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@ import (

"github.com/google/uuid"

"github.com/NearNodeFlash/nnf-ec/internal/kvstore"
"github.com/NearNodeFlash/nnf-ec/pkg/persistent"
nvme2 "github.com/NearNodeFlash/nnf-ec/internal/switchtec/pkg/nvme"
nvme "github.com/NearNodeFlash/nnf-ec/pkg/manager-nvme"
sf "github.com/NearNodeFlash/nnf-ec/pkg/rfsf/pkg/models"
Expand Down Expand Up @@ -230,13 +230,13 @@ type storagePoolRecoveryRegistry struct {
storageService *StorageService
}

func NewStoragePoolRecoveryRegistry(s *StorageService) kvstore.Registry {
func NewStoragePoolRecoveryRegistry(s *StorageService) persistent.Registry {
return &storagePoolRecoveryRegistry{storageService: s}
}

func (*storagePoolRecoveryRegistry) Prefix() string { return storagePoolRegistryPrefix }

func (r *storagePoolRecoveryRegistry) NewReplay(id string) kvstore.ReplayHandler {
func (r *storagePoolRecoveryRegistry) NewReplay(id string) persistent.ReplayHandler {
return &storagePoolRecoveryReplayHandler{storageService: r.storageService, storagePool: StoragePool{id: id}}
}

Expand Down
12 changes: 6 additions & 6 deletions pkg/manager-nvme/nvme_mock_persistence.go
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@ import (
"errors"
"fmt"

"github.com/NearNodeFlash/nnf-ec/internal/kvstore"
"github.com/NearNodeFlash/nnf-ec/pkg/persistent"
"github.com/NearNodeFlash/nnf-ec/internal/switchtec/pkg/nvme"
)

Expand All @@ -47,20 +47,20 @@ const (
var errDeviceNotFound = errors.New("Device Not Found")

type MockNvmePersistenceManager struct {
store *kvstore.Store
store *persistent.Store
replays []mockNvmePersistenceReplay
}

// Initialize the Mock NVMe Persistent Manager - This opens the key-value store for access and registers
// the Mock NVMe Persistence Registry to handle any Replays in the database.
func (mgr *MockNvmePersistenceManager) initialize() (err error) {

mgr.store, err = kvstore.Open("mock.db", false)
mgr.store, err = persistent.Open("mock.db", false)
if err != nil {
panic(err)
}

mgr.store.Register([]kvstore.Registry{newMockNvmePersistenceRegistry(mgr)})
mgr.store.Register([]persistent.Registry{newMockNvmePersistenceRegistry(mgr)})

if err := mgr.store.Replay(); err != nil {
panic(err)
Expand Down Expand Up @@ -202,15 +202,15 @@ type mockNvmePersistenceRegistry struct {
mgr *MockNvmePersistenceManager
}

func newMockNvmePersistenceRegistry(mgr *MockNvmePersistenceManager) kvstore.Registry {
func newMockNvmePersistenceRegistry(mgr *MockNvmePersistenceManager) persistent.Registry {
return &mockNvmePersistenceRegistry{mgr: mgr}
}

func (reg *mockNvmePersistenceRegistry) Prefix() string {
return mockNvmePersistenceRegistryPrefix
}

func (reg *mockNvmePersistenceRegistry) NewReplay(id string) kvstore.ReplayHandler {
func (reg *mockNvmePersistenceRegistry) NewReplay(id string) persistent.ReplayHandler {
reg.mgr.replays = append(reg.mgr.replays, mockNvmePersistenceReplay{id: id})
return &reg.mgr.replays[len(reg.mgr.replays)-1]
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -23,21 +23,27 @@ import (
"flag"
"fmt"

"github.com/NearNodeFlash/nnf-ec/internal/kvstore"
"github.com/NearNodeFlash/nnf-ec/pkg/persistent"
)

func main() {
var path string
var json string
flag.StringVar(&path, "path", "nnf.db", "the kvstore database to display")
flag.StringVar(&json, "json", "", "json file to parse")
flag.Parse()

if len(json) != 0 {
persistent.StorageProvider = persistent.NewJsonFilePersistentStorageProvider(json)
}

fmt.Printf("Debug KVStore Tool. Path: '%s'\n", path)
store, err := kvstore.Open(path, true)
store, err := persistent.Open(path, true)
if err != nil {
panic(err)
}

store.Register([]kvstore.Registry{&debugRegistry{}})
store.Register([]persistent.Registry{&debugRegistry{}})

if err := store.Replay(); err != nil {
panic(err)
Expand All @@ -46,8 +52,10 @@ func main() {

type debugRegistry struct{}

func (*debugRegistry) Prefix() string { return "" }
func (*debugRegistry) NewReplay(id string) kvstore.ReplayHandler { return &debugReplayHandler{id: id} }
func (*debugRegistry) Prefix() string { return "" }
func (*debugRegistry) NewReplay(id string) persistent.ReplayHandler {
return &debugReplayHandler{id: id}
}

type debugReplayHandler struct {
id string
Expand Down
Loading

0 comments on commit 4fb0436

Please sign in to comment.