diff --git a/apps/glusterfs/app_device.go b/apps/glusterfs/app_device.go index 79144da39e312ba00533632b5636b63987b27123..76cac51d4066f5a9710ff23fb91d1b42b53ffdb7 100644 --- a/apps/glusterfs/app_device.go +++ b/apps/glusterfs/app_device.go @@ -346,8 +346,9 @@ func (a *App) DeviceResync(w http.ResponseWriter, r *http.Request) { deviceId := vars["id"] var ( - device *DeviceEntry - node *NodeEntry + device *DeviceEntry + node *NodeEntry + brickSizesSum uint64 ) // Get device info from DB @@ -361,6 +362,13 @@ func (a *App) DeviceResync(w http.ResponseWriter, r *http.Request) { if err != nil { return err } + for _, brick := range device.Bricks { + brickEntry, err := NewBrickEntryFromId(tx, brick) + if err != nil { + return err + } + brickSizesSum += brickEntry.Info.Size + } return nil }) if err == ErrNotFound { @@ -383,20 +391,6 @@ func (a *App) DeviceResync(w http.ResponseWriter, r *http.Request) { return "", err } - // Note that method GetDeviceInfo returns the free disk space available for allocation. - // The free disk space is equal to the total disk space only if we haven't already - // allocated space, because every allocation decreases the free disk space returned - // by method GetDeviceInfo. In order to calculate a new total space we need to sum - // the free disk space and the space used by heketi. - if device.Info.Storage.Total == info.Size+device.Info.Storage.Used { - logger.Info("Device %v is up to date", device.Info.Id) - return "", nil - } - - logger.Debug("Free space of '%v' (%v) has changed %v -> %v", device.Info.Name, device.Info.Id, - device.Info.Storage.Free, info.Size) - - // Update device err = a.db.Update(func(tx *bolt.Tx) error { // Reload device in current transaction @@ -406,14 +400,15 @@ func (a *App) DeviceResync(w http.ResponseWriter, r *http.Request) { return err } - newFreeSize := info.Size - newTotalSize := newFreeSize + device.Info.Storage.Used + if brickSizesSum != info.UsedSize { + logger.Info("Sum of sizes of all bricks on the device:%v differs from used size from LVM:%v", brickSizesSum, info.UsedSize) + logger.Info("Database needs cleaning") + } - logger.Info("Updating device %v, total: %v -> %v, free: %v -> %v", device.Info.Name, - device.Info.Storage.Total, newTotalSize, device.Info.Storage.Free, newFreeSize) + logger.Info("Updating device %v, total: %v -> %v, free: %v -> %v, used: %v -> %v", device.Info.Name, + device.Info.Storage.Total, info.TotalSize, device.Info.Storage.Free, info.FreeSize, device.Info.Storage.Used, info.UsedSize) - device.Info.Storage.Total = newTotalSize - device.Info.Storage.Free = newFreeSize + device.StorageSet(info.TotalSize, info.FreeSize, info.UsedSize) // Save updated device err = device.Save(tx) diff --git a/apps/glusterfs/app_device_test.go b/apps/glusterfs/app_device_test.go index 6036b1a1a27c7414fe8a94497a8d182f52dbe561..4ebbd1b04fb318dc0d5701aefe90c8e9a3910209 100644 --- a/apps/glusterfs/app_device_test.go +++ b/apps/glusterfs/app_device_test.go @@ -789,14 +789,13 @@ func TestDeviceSync(t *testing.T) { ts := httptest.NewServer(router) defer ts.Close() - var total, used, newFree uint64 - total = 200 * 1024 * 1024 - used = 100 * 1024 * 1024 - newFree = 500 * 1024 * 1024 // see mockexec - nodeId := utils.GenUUID() deviceId := utils.GenUUID() + var total uint64 = 600 * 1024 * 1024 + var used uint64 = 250 * 1024 * 1024 + var free uint64 = 350 * 1024 * 1024 + // Init test database err := app.db.Update(func(tx *bolt.Tx) error { cluster := NewClusterEntry() @@ -809,8 +808,8 @@ func TestDeviceSync(t *testing.T) { device.Info.Id = deviceId device.Info.Name = "/dev/abc" device.NodeId = nodeId - device.StorageSet(total) - device.StorageAllocate(used) + device.StorageSet(total, total, 0) + device.StorageAllocate(100) if err := device.Save(tx); err != nil { return err @@ -833,6 +832,14 @@ func TestDeviceSync(t *testing.T) { }) tests.Assert(t, err == nil) + app.xo.MockGetDeviceInfo = func(host, device, vgid string) (*executors.DeviceInfo, error) { + d := &executors.DeviceInfo{} + d.TotalSize = total + d.FreeSize = free + d.UsedSize = used + d.ExtentSize = 4096 + return d, nil + } r, err := http.Get(ts.URL + "/devices/" + deviceId + "/resync") tests.Assert(t, err == nil) tests.Assert(t, r.StatusCode == http.StatusAccepted) @@ -856,12 +863,13 @@ func TestDeviceSync(t *testing.T) { err = app.db.View(func(tx *bolt.Tx) error { device, err := NewDeviceEntryFromId(tx, deviceId) tests.Assert(t, err == nil) - tests.Assert(t, device.Info.Storage.Total == newFree+used) - tests.Assert(t, device.Info.Storage.Free == newFree) + tests.Assert(t, device.Info.Storage.Total == total, "expected:", total, "got:", device.Info.Storage.Total) + tests.Assert(t, device.Info.Storage.Free == free) tests.Assert(t, device.Info.Storage.Used == used) return nil }) tests.Assert(t, err == nil) + } func TestDeviceSyncIdNotFound(t *testing.T) { diff --git a/executors/mockexec/mock.go b/executors/mockexec/mock.go index 6a2a443572e7fa1fa0976f5bcbfb305837d4e9c7..986acc484f92d20bcd443c0273e87818d1861078 100644 --- a/executors/mockexec/mock.go +++ b/executors/mockexec/mock.go @@ -20,6 +20,7 @@ type MockExecutor struct { MockPeerDetach func(exec_host, newnode string) error MockDeviceSetup func(host, device, vgid string, destroy bool) (*executors.DeviceInfo, error) MockDeviceTeardown func(host, device, vgid string) error + MockGetDeviceInfo func(host, device, vgid string) (*executors.DeviceInfo, error) MockBrickCreate func(host string, brick *executors.BrickRequest) (*executors.BrickInfo, error) MockBrickDestroy func(host string, brick *executors.BrickRequest) (bool, error) MockVolumeCreate func(host string, volume *executors.VolumeRequest) (*executors.Volume, error) @@ -66,6 +67,15 @@ func NewMockExecutor() (*MockExecutor, error) { return nil } + m.MockGetDeviceInfo = func(host, device, vgid string) (*executors.DeviceInfo, error) { + d := &executors.DeviceInfo{} + d.TotalSize = 500 * 1024 * 1024 + d.FreeSize = 500 * 1024 * 1024 + d.UsedSize = 0 + d.ExtentSize = 4096 + return d, nil + } + m.MockBrickCreate = func(host string, brick *executors.BrickRequest) (*executors.BrickInfo, error) { b := &executors.BrickInfo{ Path: "/mockpath", @@ -204,7 +214,7 @@ func (m *MockExecutor) DeviceSetup(host, device, vgid string, destroy bool) (*ex } func (m *MockExecutor) GetDeviceInfo(host, device, vgid string) (*executors.DeviceInfo, error) { - return m.MockDeviceSetup(host, device, vgid, false) + return m.MockGetDeviceInfo(host, device, vgid) } func (m *MockExecutor) DeviceTeardown(host, device, vgid string) error {