mirror of
https://github.com/minio/minio.git
synced 2024-12-24 22:25:54 -05:00
Deprecate showing drive capacity and total free (#5976)
This addresses a situation that we shouldn't be displaying Total/Free anymore, instead we should simply show the total usage.
This commit is contained in:
parent
e6ec645035
commit
000e360196
@ -25,23 +25,17 @@ export class StorageInfo extends React.Component {
|
|||||||
fetchStorageInfo()
|
fetchStorageInfo()
|
||||||
}
|
}
|
||||||
render() {
|
render() {
|
||||||
const { total, used } = this.props.storageInfo
|
const { used } = this.props.storageInfo
|
||||||
const usedPercent = used / total * 100 + "%"
|
|
||||||
const freePercent = (total - used) * 100 / total
|
|
||||||
return (
|
return (
|
||||||
<div className="feh-used">
|
<div className="feh-used">
|
||||||
<div className="fehu-chart">
|
<div className="fehu-chart">
|
||||||
<div style={{ width: usedPercent }} />
|
<div style={{ width: 0 }} />
|
||||||
</div>
|
</div>
|
||||||
<ul>
|
<ul>
|
||||||
<li>
|
<li>
|
||||||
<span>Used: </span>
|
<span>Used: </span>
|
||||||
{humanize.filesize(used)}
|
{humanize.filesize(used)}
|
||||||
</li>
|
</li>
|
||||||
<li className="pull-right">
|
|
||||||
<span>Free: </span>
|
|
||||||
{humanize.filesize(total - used)}
|
|
||||||
</li>
|
|
||||||
</ul>
|
</ul>
|
||||||
</div>
|
</div>
|
||||||
)
|
)
|
||||||
|
@ -22,7 +22,7 @@ describe("StorageInfo", () => {
|
|||||||
it("should render without crashing", () => {
|
it("should render without crashing", () => {
|
||||||
shallow(
|
shallow(
|
||||||
<StorageInfo
|
<StorageInfo
|
||||||
storageInfo={{ total: 100, used: 60 }}
|
storageInfo={{ used: 60 }}
|
||||||
fetchStorageInfo={jest.fn()}
|
fetchStorageInfo={jest.fn()}
|
||||||
/>
|
/>
|
||||||
)
|
)
|
||||||
@ -32,7 +32,7 @@ describe("StorageInfo", () => {
|
|||||||
const fetchStorageInfo = jest.fn()
|
const fetchStorageInfo = jest.fn()
|
||||||
shallow(
|
shallow(
|
||||||
<StorageInfo
|
<StorageInfo
|
||||||
storageInfo={{ total: 100, used: 60 }}
|
storageInfo={{ used: 60 }}
|
||||||
fetchStorageInfo={fetchStorageInfo}
|
fetchStorageInfo={fetchStorageInfo}
|
||||||
/>
|
/>
|
||||||
)
|
)
|
||||||
|
@ -20,7 +20,7 @@ import * as actionsCommon from "../actions"
|
|||||||
|
|
||||||
jest.mock("../../web", () => ({
|
jest.mock("../../web", () => ({
|
||||||
StorageInfo: jest.fn(() => {
|
StorageInfo: jest.fn(() => {
|
||||||
return Promise.resolve({ storageInfo: { Total: 100, Used: 60 } })
|
return Promise.resolve({ storageInfo: { Used: 60 } })
|
||||||
}),
|
}),
|
||||||
ServerInfo: jest.fn(() => {
|
ServerInfo: jest.fn(() => {
|
||||||
return Promise.resolve({
|
return Promise.resolve({
|
||||||
@ -40,7 +40,7 @@ describe("Common actions", () => {
|
|||||||
it("creates common/SET_STORAGE_INFO after fetching the storage details ", () => {
|
it("creates common/SET_STORAGE_INFO after fetching the storage details ", () => {
|
||||||
const store = mockStore()
|
const store = mockStore()
|
||||||
const expectedActions = [
|
const expectedActions = [
|
||||||
{ type: "common/SET_STORAGE_INFO", storageInfo: { total: 100, used: 60 } }
|
{ type: "common/SET_STORAGE_INFO", storageInfo: { used: 60 } }
|
||||||
]
|
]
|
||||||
return store.dispatch(actionsCommon.fetchStorageInfo()).then(() => {
|
return store.dispatch(actionsCommon.fetchStorageInfo()).then(() => {
|
||||||
const actions = store.getActions()
|
const actions = store.getActions()
|
||||||
|
File diff suppressed because one or more lines are too long
@ -929,9 +929,6 @@ func TestAdminServerInfo(t *testing.T) {
|
|||||||
if serverInfo.Error != "" {
|
if serverInfo.Error != "" {
|
||||||
t.Errorf("Unexpected error = %v\n", serverInfo.Error)
|
t.Errorf("Unexpected error = %v\n", serverInfo.Error)
|
||||||
}
|
}
|
||||||
if serverInfo.Data.StorageInfo.Free == 0 {
|
|
||||||
t.Error("Expected StorageInfo.Free to be non empty")
|
|
||||||
}
|
|
||||||
if serverInfo.Data.Properties.Region != globalMinioDefaultRegion {
|
if serverInfo.Data.Properties.Region != globalMinioDefaultRegion {
|
||||||
t.Errorf("Expected %s, got %s", globalMinioDefaultRegion, serverInfo.Data.Properties.Region)
|
t.Errorf("Expected %s, got %s", globalMinioDefaultRegion, serverInfo.Data.Properties.Region)
|
||||||
}
|
}
|
||||||
|
26
cmd/fs-v1.go
26
cmd/fs-v1.go
@ -176,35 +176,39 @@ func (fs *FSObjects) diskUsage(doneCh chan struct{}) {
|
|||||||
ticker := time.NewTicker(fs.usageCheckInterval)
|
ticker := time.NewTicker(fs.usageCheckInterval)
|
||||||
defer ticker.Stop()
|
defer ticker.Stop()
|
||||||
|
|
||||||
var usage uint64
|
|
||||||
usageFn := func(ctx context.Context, entry string) error {
|
usageFn := func(ctx context.Context, entry string) error {
|
||||||
|
var fi os.FileInfo
|
||||||
|
var err error
|
||||||
if hasSuffix(entry, slashSeparator) {
|
if hasSuffix(entry, slashSeparator) {
|
||||||
return nil
|
fi, err = fsStatDir(ctx, entry)
|
||||||
|
} else {
|
||||||
|
fi, err = fsStatFile(ctx, entry)
|
||||||
}
|
}
|
||||||
fi, err := fsStatFile(ctx, entry)
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
usage = usage + uint64(fi.Size())
|
atomic.AddUint64(&fs.totalUsed, uint64(fi.Size()))
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
if err := getDiskUsage(context.Background(), fs.fsPath, usageFn); err != nil {
|
if err := getDiskUsage(context.Background(), fs.fsPath, usageFn); err != nil {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
atomic.StoreUint64(&fs.totalUsed, usage)
|
|
||||||
|
|
||||||
for {
|
for {
|
||||||
select {
|
select {
|
||||||
case <-doneCh:
|
case <-doneCh:
|
||||||
return
|
return
|
||||||
case <-ticker.C:
|
case <-ticker.C:
|
||||||
usage = 0
|
var usage uint64
|
||||||
usageFn = func(ctx context.Context, entry string) error {
|
usageFn = func(ctx context.Context, entry string) error {
|
||||||
|
var fi os.FileInfo
|
||||||
|
var err error
|
||||||
if hasSuffix(entry, slashSeparator) {
|
if hasSuffix(entry, slashSeparator) {
|
||||||
return nil
|
fi, err = fsStatDir(ctx, entry)
|
||||||
|
} else {
|
||||||
|
fi, err = fsStatFile(ctx, entry)
|
||||||
}
|
}
|
||||||
fi, err := fsStatFile(ctx, entry)
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
@ -221,13 +225,7 @@ func (fs *FSObjects) diskUsage(doneCh chan struct{}) {
|
|||||||
|
|
||||||
// StorageInfo - returns underlying storage statistics.
|
// StorageInfo - returns underlying storage statistics.
|
||||||
func (fs *FSObjects) StorageInfo(ctx context.Context) StorageInfo {
|
func (fs *FSObjects) StorageInfo(ctx context.Context) StorageInfo {
|
||||||
info, err := getDiskInfo(fs.fsPath)
|
|
||||||
logger.GetReqInfo(ctx).AppendTags("path", fs.fsPath)
|
|
||||||
logger.LogIf(ctx, err)
|
|
||||||
|
|
||||||
storageInfo := StorageInfo{
|
storageInfo := StorageInfo{
|
||||||
Total: info.Total,
|
|
||||||
Free: info.Free,
|
|
||||||
Used: atomic.LoadUint64(&fs.totalUsed),
|
Used: atomic.LoadUint64(&fs.totalUsed),
|
||||||
}
|
}
|
||||||
storageInfo.Backend.Type = FS
|
storageInfo.Backend.Type = FS
|
||||||
|
12
cmd/posix.go
12
cmd/posix.go
@ -319,20 +319,16 @@ func (s *posix) diskUsage() {
|
|||||||
ticker := time.NewTicker(s.usageCheckInterval)
|
ticker := time.NewTicker(s.usageCheckInterval)
|
||||||
defer ticker.Stop()
|
defer ticker.Stop()
|
||||||
|
|
||||||
var usage uint64
|
|
||||||
usageFn := func(ctx context.Context, entry string) error {
|
usageFn := func(ctx context.Context, entry string) error {
|
||||||
select {
|
select {
|
||||||
case <-s.stopUsageCh:
|
case <-s.stopUsageCh:
|
||||||
return errWalkAbort
|
return errWalkAbort
|
||||||
default:
|
default:
|
||||||
if hasSuffix(entry, slashSeparator) {
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
fi, err := os.Stat(entry)
|
fi, err := os.Stat(entry)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
usage = usage + uint64(fi.Size())
|
atomic.AddUint64(&s.totalUsage, uint64(fi.Size()))
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -340,7 +336,6 @@ func (s *posix) diskUsage() {
|
|||||||
if err := getDiskUsage(context.Background(), s.diskPath, usageFn); err != nil {
|
if err := getDiskUsage(context.Background(), s.diskPath, usageFn); err != nil {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
atomic.StoreUint64(&s.totalUsage, usage)
|
|
||||||
|
|
||||||
for {
|
for {
|
||||||
select {
|
select {
|
||||||
@ -349,15 +344,12 @@ func (s *posix) diskUsage() {
|
|||||||
case <-globalServiceDoneCh:
|
case <-globalServiceDoneCh:
|
||||||
return
|
return
|
||||||
case <-ticker.C:
|
case <-ticker.C:
|
||||||
usage = 0
|
var usage uint64
|
||||||
usageFn = func(ctx context.Context, entry string) error {
|
usageFn = func(ctx context.Context, entry string) error {
|
||||||
select {
|
select {
|
||||||
case <-s.stopUsageCh:
|
case <-s.stopUsageCh:
|
||||||
return errWalkAbort
|
return errWalkAbort
|
||||||
default:
|
default:
|
||||||
if hasSuffix(entry, slashSeparator) {
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
fi, err := os.Stat(entry)
|
fi, err := os.Stat(entry)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
|
@ -173,19 +173,19 @@ func printObjectAPIMsg() {
|
|||||||
|
|
||||||
// Get formatted disk/storage info message.
|
// Get formatted disk/storage info message.
|
||||||
func getStorageInfoMsg(storageInfo StorageInfo) string {
|
func getStorageInfoMsg(storageInfo StorageInfo) string {
|
||||||
msg := fmt.Sprintf("%s %s Free, %s Total", colorBlue("Drive Capacity:"),
|
var msg string
|
||||||
humanize.IBytes(uint64(storageInfo.Free)),
|
|
||||||
humanize.IBytes(uint64(storageInfo.Total)))
|
|
||||||
if storageInfo.Backend.Type == Erasure {
|
if storageInfo.Backend.Type == Erasure {
|
||||||
diskInfo := fmt.Sprintf(" %d Online, %d Offline. ", storageInfo.Backend.OnlineDisks, storageInfo.Backend.OfflineDisks)
|
diskInfo := fmt.Sprintf(" %d Online, %d Offline. ", storageInfo.Backend.OnlineDisks, storageInfo.Backend.OfflineDisks)
|
||||||
msg += colorBlue("\nStatus:") + fmt.Sprintf(getFormatStr(len(diskInfo), 8), diskInfo)
|
msg += colorBlue("Status:") + fmt.Sprintf(getFormatStr(len(diskInfo), 8), diskInfo)
|
||||||
}
|
}
|
||||||
return msg
|
return msg
|
||||||
}
|
}
|
||||||
|
|
||||||
// Prints startup message of storage capacity and erasure information.
|
// Prints startup message of storage capacity and erasure information.
|
||||||
func printStorageInfo(storageInfo StorageInfo) {
|
func printStorageInfo(storageInfo StorageInfo) {
|
||||||
logger.StartupMessage(getStorageInfoMsg(storageInfo) + "\n")
|
if msg := getStorageInfoMsg(storageInfo); msg != "" {
|
||||||
|
logger.StartupMessage(msg)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func printCacheStorageInfo(storageInfo StorageInfo) {
|
func printCacheStorageInfo(storageInfo StorageInfo) {
|
||||||
|
@ -25,20 +25,16 @@ import (
|
|||||||
"strings"
|
"strings"
|
||||||
"testing"
|
"testing"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
humanize "github.com/dustin/go-humanize"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
// Tests if we generate storage info.
|
// Tests if we generate storage info.
|
||||||
func TestStorageInfoMsg(t *testing.T) {
|
func TestStorageInfoMsg(t *testing.T) {
|
||||||
infoStorage := StorageInfo{}
|
infoStorage := StorageInfo{}
|
||||||
infoStorage.Total = 10 * humanize.GiByte
|
|
||||||
infoStorage.Free = 2 * humanize.GiByte
|
|
||||||
infoStorage.Backend.Type = Erasure
|
infoStorage.Backend.Type = Erasure
|
||||||
infoStorage.Backend.OnlineDisks = 7
|
infoStorage.Backend.OnlineDisks = 7
|
||||||
infoStorage.Backend.OfflineDisks = 1
|
infoStorage.Backend.OfflineDisks = 1
|
||||||
|
|
||||||
if msg := getStorageInfoMsg(infoStorage); !strings.Contains(msg, "2.0 GiB Free, 10 GiB Total") || !strings.Contains(msg, "7 Online, 1 Offline") {
|
if msg := getStorageInfoMsg(infoStorage); !strings.Contains(msg, "7 Online, 1 Offline") {
|
||||||
t.Fatal("Unexpected storage info message, found:", msg)
|
t.Fatal("Unexpected storage info message, found:", msg)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -221,13 +221,9 @@ func testStorageInfoWebHandler(obj ObjectLayer, instanceType string, t TestErrHa
|
|||||||
if rec.Code != http.StatusOK {
|
if rec.Code != http.StatusOK {
|
||||||
t.Fatalf("Expected the response status to be 200, but instead found `%d`", rec.Code)
|
t.Fatalf("Expected the response status to be 200, but instead found `%d`", rec.Code)
|
||||||
}
|
}
|
||||||
err = getTestWebRPCResponse(rec, &storageInfoReply)
|
if err = getTestWebRPCResponse(rec, &storageInfoReply); err != nil {
|
||||||
if err != nil {
|
|
||||||
t.Fatalf("Failed %v", err)
|
t.Fatalf("Failed %v", err)
|
||||||
}
|
}
|
||||||
if storageInfoReply.StorageInfo.Total <= 0 {
|
|
||||||
t.Fatalf("Got a zero or negative total free space disk")
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Wrapper for calling ServerInfo Web Handler
|
// Wrapper for calling ServerInfo Web Handler
|
||||||
|
@ -280,8 +280,6 @@ func (s *xlSets) StorageInfo(ctx context.Context) StorageInfo {
|
|||||||
storageInfo.Backend.Type = Erasure
|
storageInfo.Backend.Type = Erasure
|
||||||
for _, set := range s.sets {
|
for _, set := range s.sets {
|
||||||
lstorageInfo := set.StorageInfo(ctx)
|
lstorageInfo := set.StorageInfo(ctx)
|
||||||
storageInfo.Total = storageInfo.Total + lstorageInfo.Total
|
|
||||||
storageInfo.Free = storageInfo.Free + lstorageInfo.Free
|
|
||||||
storageInfo.Used = storageInfo.Used + lstorageInfo.Used
|
storageInfo.Used = storageInfo.Used + lstorageInfo.Used
|
||||||
storageInfo.Backend.OnlineDisks = storageInfo.Backend.OnlineDisks + lstorageInfo.Backend.OnlineDisks
|
storageInfo.Backend.OnlineDisks = storageInfo.Backend.OnlineDisks + lstorageInfo.Backend.OnlineDisks
|
||||||
storageInfo.Backend.OfflineDisks = storageInfo.Backend.OfflineDisks + lstorageInfo.Backend.OfflineDisks
|
storageInfo.Backend.OfflineDisks = storageInfo.Backend.OfflineDisks + lstorageInfo.Backend.OfflineDisks
|
||||||
|
@ -98,46 +98,6 @@ func TestNewXLSets(t *testing.T) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// TestStorageInfoSets - tests storage info for erasure coded sets of disks.
|
|
||||||
func TestStorageInfoSets(t *testing.T) {
|
|
||||||
var nDisks = 16 // Maximum disks.
|
|
||||||
var erasureDisks []string
|
|
||||||
for i := 0; i < nDisks; i++ {
|
|
||||||
// Do not attempt to create this path, the test validates
|
|
||||||
// so that newXLSets initializes non existing paths
|
|
||||||
// and successfully returns initialized object layer.
|
|
||||||
disk := filepath.Join(globalTestTmpDir, "minio-"+nextSuffix())
|
|
||||||
erasureDisks = append(erasureDisks, disk)
|
|
||||||
defer os.RemoveAll(disk)
|
|
||||||
}
|
|
||||||
|
|
||||||
endpoints := mustGetNewEndpointList(erasureDisks...)
|
|
||||||
// Initializes all erasure disks
|
|
||||||
format, err := waitForFormatXL(context.Background(), true, endpoints, 1, 16)
|
|
||||||
if err != nil {
|
|
||||||
t.Fatalf("Unable to format disks for erasure, %s", err)
|
|
||||||
}
|
|
||||||
|
|
||||||
objLayer, err := newXLSets(endpoints, format, 1, 16)
|
|
||||||
if err != nil {
|
|
||||||
t.Fatal(err)
|
|
||||||
}
|
|
||||||
|
|
||||||
// Get storage info first attempt.
|
|
||||||
disks16Info := objLayer.StorageInfo(context.Background())
|
|
||||||
|
|
||||||
// This test assumes homogeneity between all disks,
|
|
||||||
// i.e if we loose one disk the effective storage
|
|
||||||
// usage values is assumed to decrease. If we have
|
|
||||||
// heterogenous environment this is not true all the time.
|
|
||||||
if disks16Info.Free <= 0 {
|
|
||||||
t.Fatalf("Diskinfo total free values should be greater 0")
|
|
||||||
}
|
|
||||||
if disks16Info.Total <= 0 {
|
|
||||||
t.Fatalf("Diskinfo total values should be greater 0")
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// TestHashedLayer - tests the hashed layer which will be returned
|
// TestHashedLayer - tests the hashed layer which will be returned
|
||||||
// consistently for a given object name.
|
// consistently for a given object name.
|
||||||
func TestHashedLayer(t *testing.T) {
|
func TestHashedLayer(t *testing.T) {
|
||||||
|
13
cmd/xl-v1.go
13
cmd/xl-v1.go
@ -173,10 +173,7 @@ func getStorageInfo(disks []StorageAPI) StorageInfo {
|
|||||||
validDisksInfo := sortValidDisksInfo(disksInfo)
|
validDisksInfo := sortValidDisksInfo(disksInfo)
|
||||||
// If there are no valid disks, set total and free disks to 0
|
// If there are no valid disks, set total and free disks to 0
|
||||||
if len(validDisksInfo) == 0 {
|
if len(validDisksInfo) == 0 {
|
||||||
return StorageInfo{
|
return StorageInfo{}
|
||||||
Total: 0,
|
|
||||||
Free: 0,
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
_, sscParity := getRedundancyCount(standardStorageClass, len(disks))
|
_, sscParity := getRedundancyCount(standardStorageClass, len(disks))
|
||||||
@ -192,13 +189,7 @@ func getStorageInfo(disks []StorageAPI) StorageInfo {
|
|||||||
availableDataDisks = uint64(onlineDisks)
|
availableDataDisks = uint64(onlineDisks)
|
||||||
}
|
}
|
||||||
|
|
||||||
// Return calculated storage info, choose the lowest Total and
|
storageInfo := StorageInfo{}
|
||||||
// Free as the total aggregated values. Total capacity is always
|
|
||||||
// the multiple of smallest disk among the disk list.
|
|
||||||
storageInfo := StorageInfo{
|
|
||||||
Total: validDisksInfo[0].Total * availableDataDisks,
|
|
||||||
Free: validDisksInfo[0].Free * availableDataDisks,
|
|
||||||
}
|
|
||||||
|
|
||||||
// Combine all disks to get total usage.
|
// Combine all disks to get total usage.
|
||||||
var used uint64
|
var used uint64
|
||||||
|
@ -17,39 +17,10 @@
|
|||||||
package cmd
|
package cmd
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"context"
|
|
||||||
"os"
|
|
||||||
"reflect"
|
"reflect"
|
||||||
"testing"
|
"testing"
|
||||||
)
|
)
|
||||||
|
|
||||||
// TestStorageInfo - tests storage info.
|
|
||||||
func TestStorageInfo(t *testing.T) {
|
|
||||||
objLayer, fsDirs, err := prepareXL16()
|
|
||||||
if err != nil {
|
|
||||||
t.Fatalf("Unable to initialize 'XL' object layer.")
|
|
||||||
}
|
|
||||||
|
|
||||||
// Remove all dirs.
|
|
||||||
for _, dir := range fsDirs {
|
|
||||||
defer os.RemoveAll(dir)
|
|
||||||
}
|
|
||||||
|
|
||||||
// Get storage info first attempt.
|
|
||||||
disks16Info := objLayer.StorageInfo(context.Background())
|
|
||||||
|
|
||||||
// This test assumes homogenity between all disks,
|
|
||||||
// i.e if we loose one disk the effective storage
|
|
||||||
// usage values is assumed to decrease. If we have
|
|
||||||
// heterogenous environment this is not true all the time.
|
|
||||||
if disks16Info.Free <= 0 {
|
|
||||||
t.Fatalf("Diskinfo total free values should be greater 0")
|
|
||||||
}
|
|
||||||
if disks16Info.Total <= 0 {
|
|
||||||
t.Fatalf("Diskinfo total values should be greater 0")
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Sort valid disks info.
|
// Sort valid disks info.
|
||||||
func TestSortingValidDisks(t *testing.T) {
|
func TestSortingValidDisks(t *testing.T) {
|
||||||
testCases := []struct {
|
testCases := []struct {
|
||||||
|
@ -44,8 +44,6 @@ type DriveInfo HealDriveInfo
|
|||||||
|
|
||||||
// StorageInfo - represents total capacity of underlying storage.
|
// StorageInfo - represents total capacity of underlying storage.
|
||||||
type StorageInfo struct {
|
type StorageInfo struct {
|
||||||
Total uint64 // Total disk space.
|
|
||||||
Free uint64 // Free space available.
|
|
||||||
Used uint64 // Total used spaced per tenant.
|
Used uint64 // Total used spaced per tenant.
|
||||||
|
|
||||||
// Backend type.
|
// Backend type.
|
||||||
|
Loading…
Reference in New Issue
Block a user