22162: Add a couple of additional tests related to mknod
[arvados.git] / services / keepstore / volume.go
1 // Copyright (C) The Arvados Authors. All rights reserved.
2 //
3 // SPDX-License-Identifier: AGPL-3.0
4
5 package keepstore
6
7 import (
8         "context"
9         "io"
10         "time"
11
12         "git.arvados.org/arvados.git/sdk/go/arvados"
13         "github.com/sirupsen/logrus"
14 )
15
16 // volume is the interface to a back-end storage device.
17 type volume interface {
18         // Return a unique identifier for the backend device. If
19         // possible, this should be chosen such that keepstore
20         // processes running on different hosts, and accessing the
21         // same backend device, will return the same string.
22         //
23         // This helps keep-balance avoid redundantly downloading
24         // multiple index listings for the same backend device.
25         DeviceID() string
26
27         // Copy a block from the backend device to writeTo.
28         //
29         // As with all volume methods, the hash argument is a
30         // 32-character hexadecimal string.
31         //
32         // Data can be written to writeTo in any order, and concurrent
33         // calls to writeTo.WriteAt() are allowed.  However, BlockRead
34         // must not do multiple writes that intersect with any given
35         // byte offset.
36         //
37         // BlockRead is not expected to verify data integrity.
38         //
39         // If the indicated block does not exist, or has been trashed,
40         // BlockRead must return os.ErrNotExist.
41         BlockRead(ctx context.Context, hash string, writeTo io.WriterAt) error
42
43         // Store a block on the backend device, and set its timestamp
44         // to the current time.
45         //
46         // The implementation must ensure that regardless of any
47         // errors encountered while writing, a partially written block
48         // is not left behind: a subsequent BlockRead call must return
49         // either a) the data previously stored under the given hash,
50         // if any, or b) os.ErrNotExist.
51         BlockWrite(ctx context.Context, hash string, data []byte) error
52
53         // Update the indicated block's stored timestamp to the
54         // current time.
55         BlockTouch(hash string) error
56
57         // Return the indicated block's stored timestamp.
58         Mtime(hash string) (time.Time, error)
59
60         // Mark the indicated block as trash, such that -- unless it
61         // is untrashed before time.Now() + BlobTrashLifetime --
62         // BlockRead returns os.ErrNotExist and the block is not
63         // listed by Index.
64         BlockTrash(hash string) error
65
66         // Un-mark the indicated block as trash. If the block has not
67         // been trashed, return os.ErrNotExist.
68         BlockUntrash(hash string) error
69
70         // Permanently delete all blocks that have been marked as
71         // trash for BlobTrashLifetime or longer.
72         EmptyTrash()
73
74         // Write an index of all non-trashed blocks available on the
75         // backend device whose hash begins with the given prefix
76         // (prefix is a string of zero or more hexadecimal digits).
77         //
78         // Each block is written as "{hash}+{size} {timestamp}\n"
79         // where timestamp is a decimal-formatted number of
80         // nanoseconds since the UTC Unix epoch.
81         //
82         // Index should abort and return ctx.Err() if ctx is cancelled
83         // before indexing is complete.
84         Index(ctx context.Context, prefix string, writeTo io.Writer) error
85 }
86
87 type volumeDriver func(newVolumeParams) (volume, error)
88
89 type newVolumeParams struct {
90         UUID         string
91         Cluster      *arvados.Cluster
92         ConfigVolume arvados.Volume
93         Logger       logrus.FieldLogger
94         MetricsVecs  *volumeMetricsVecs
95         BufferPool   *bufferPool
96 }
97
98 // ioStats tracks I/O statistics for a volume or server
99 type ioStats struct {
100         Errors     uint64
101         Ops        uint64
102         CompareOps uint64
103         GetOps     uint64
104         PutOps     uint64
105         TouchOps   uint64
106         InBytes    uint64
107         OutBytes   uint64
108 }