Skip to content

Commit 393b381

Browse files
committed
storage zdb: also check on the mode of the 0-db when allocating volumes
fixes #499
1 parent dab6cfc commit 393b381

File tree

6 files changed

+118
-0
lines changed

6 files changed

+118
-0
lines changed

pkg/storage/zdb.go

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -54,6 +54,7 @@ func (s *storageModule) Allocate(nsID string, diskType pkg.DeviceType, size uint
5454
log := log.With().
5555
Str("type", string(diskType)).
5656
Uint64("size", size).
57+
Str("mode", string(mode)).
5758
Logger()
5859

5960
log.Info().Msg("try to allocation space for 0-DB")
@@ -71,6 +72,7 @@ func (s *storageModule) Allocate(nsID string, diskType pkg.DeviceType, size uint
7172
}
7273

7374
for _, volume := range volumes {
75+
7476
// skip all non-zdb volume
7577
if !filesystem.IsZDBVolume(volume) {
7678
continue
@@ -97,6 +99,11 @@ func (s *storageModule) Allocate(nsID string, diskType pkg.DeviceType, size uint
9799
Free uint64
98100
}
99101

102+
targetMode := zdbpool.IndexModeKeyValue
103+
if mode == pkg.ZDBModeSeq {
104+
targetMode = zdbpool.IndexModeSequential
105+
}
106+
100107
var candidates []Candidate
101108
// okay, so this is a new allocation
102109
// we search all the pools for a zdb subvolume that can
@@ -133,6 +140,20 @@ func (s *storageModule) Allocate(nsID string, diskType pkg.DeviceType, size uint
133140
continue
134141
}
135142

143+
zdb := zdbpool.New(volume.Path())
144+
145+
// check if the mode is the same
146+
indexMode, err := zdb.IndexMode("default")
147+
if err != nil {
148+
log.Err(err).Str("namespace", "default").Msg("failed to read index mode")
149+
continue
150+
}
151+
152+
if indexMode != targetMode {
153+
log.Info().Msg("skip because wrong mode")
154+
continue
155+
}
156+
136157
candidates = append(
137158
candidates,
138159
Candidate{

pkg/storage/zdbpool/index.go

Lines changed: 49 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,49 @@
1+
package zdbpool
2+
3+
import (
4+
"encoding/binary"
5+
"io"
6+
)
7+
8+
// IndexMode represens the mode in which the 0-db is running
9+
// Adapted from https://github.com/threefoldtech/0-db/blob/development/libzdb/index.h#L4
10+
type IndexMode uint8
11+
12+
// Enum values for IndexMode
13+
const (
14+
IndexModeKeyValue IndexMode = 0
15+
IndexModeSequential IndexMode = 1
16+
IndexModeDirectKey IndexMode = 2
17+
IndexModeDirectBlock IndexMode = 3
18+
)
19+
20+
func (i IndexMode) String() string {
21+
switch i {
22+
case IndexModeKeyValue:
23+
return "key-value"
24+
case IndexModeSequential:
25+
return "sequential"
26+
case IndexModeDirectKey:
27+
return "direct-key"
28+
case IndexModeDirectBlock:
29+
return "direct-block"
30+
}
31+
return "unknown"
32+
}
33+
34+
// IndexHeader is the structure contains information about an index
35+
// adapted from https://github.com/threefoldtech/0-db/blob/development/libzdb/index.h#L31
36+
type IndexHeader struct {
37+
Magic [4]byte // four bytes magic bytes to recognize the file
38+
Version uint32 // file version, for possible upgrade compatibility
39+
Created uint64 // unix timestamp of creation time
40+
Opened uint64 // unix timestamp of last opened time
41+
Fileid uint16 // current index file id (sync with dataid)
42+
Mode IndexMode // running mode when index was create
43+
}
44+
45+
// ReadIndex reads index header
46+
func ReadIndex(r io.Reader) (header IndexHeader, err error) {
47+
err = binary.Read(r, binary.LittleEndian, &header)
48+
return
49+
}

pkg/storage/zdbpool/index_test.go

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
package zdbpool
2+
3+
import (
4+
"os"
5+
"testing"
6+
7+
"github.com/stretchr/testify/assert"
8+
"github.com/stretchr/testify/require"
9+
)
10+
11+
func TestReadIndexHeader(t *testing.T) {
12+
f, err := os.Open("./test_data/zdb-index-00000")
13+
require.NoError(t, err)
14+
defer f.Close()
15+
16+
h, err := ReadIndex(f)
17+
require.NoError(t, err)
18+
19+
assert.Equal(t, IndexModeKeyValue, h.Mode)
20+
}

pkg/storage/zdbpool/pool.go

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -128,3 +128,21 @@ func (p *ZDBPool) Exists(name string) bool {
128128
_, err := os.Stat(path)
129129
return err == nil
130130
}
131+
132+
// IndexMode return the mode of the index of the namespace called name
133+
func (p *ZDBPool) IndexMode(name string) (mode IndexMode, err error) {
134+
path := filepath.Join(p.path, name, "zdb-index-00000")
135+
136+
f, err := os.Open(path)
137+
if err != nil {
138+
return mode, err
139+
}
140+
141+
defer f.Close()
142+
index, err := ReadIndex(f)
143+
if err != nil {
144+
return mode, errors.Wrapf(err, "failed to read namespace index header at %s", path)
145+
}
146+
147+
return index.Mode, nil
148+
}

pkg/storage/zdbpool/pool_test.go

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -41,3 +41,13 @@ func TestExists(t *testing.T) {
4141
assert.True(t, pool.Exists("test"))
4242
assert.False(t, pool.Exists("foo"))
4343
}
44+
45+
func TestIndexMode(t *testing.T) {
46+
pool := ZDBPool{
47+
path: "./test_data/pool_layout",
48+
}
49+
50+
mode, err := pool.IndexMode("test")
51+
require.NoError(t, err)
52+
assert.Equal(t, IndexModeKeyValue, mode)
53+
}
27 Bytes
Binary file not shown.

0 commit comments

Comments
 (0)