forked from whamcloud/go-lustre
/
hsm_state.go
114 lines (94 loc) · 2.9 KB
/
hsm_state.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
// Copyright (c) 2016 Intel Corporation. All rights reserved.
// Use of this source code is governed by a MIT-style
// license that can be found in the LICENSE file.
package llapi
/*
#include <lustre/lustreapi.h>
#include <stdlib.h>
// This doesn't exist in the API, but maybe it should?
struct hsm_user_state *_hsm_user_state_alloc()
{
int len = 0;
len += sizeof(struct hsm_user_state);
len += sizeof(struct hsm_extent);
return (struct hsm_user_state *)malloc(len);
}
*/
import "C"
import (
"fmt"
"strings"
"unsafe"
)
type (
// HsmFileState is a bitmask containing the hsm state(s) for a file.
HsmFileState uint32
// HsmStateFlag represents a given HSM state flag
HsmStateFlag uint32
)
// HSM State flags
const (
HsmFileExists = HsmStateFlag(C.HS_EXISTS)
HsmFileArchived = HsmStateFlag(C.HS_ARCHIVED)
HsmFileReleased = HsmStateFlag(C.HS_RELEASED)
HsmFileDirty = HsmStateFlag(C.HS_DIRTY)
HsmFileNoRelease = HsmStateFlag(C.HS_NORELEASE)
HsmFileNoArchive = HsmStateFlag(C.HS_NOARCHIVE)
HsmFileLost = HsmStateFlag(C.HS_LOST)
)
// HsmStateFlags is a map of HsmStateFlag -> string
// NB: There's no llapi.hsm_state2name(), so we have to do it ourselves...
var HsmStateFlags = map[HsmStateFlag]string{
HsmFileExists: "exists",
HsmFileArchived: "archived",
HsmFileReleased: "released",
HsmFileDirty: "dirty",
HsmFileNoRelease: "no_release",
HsmFileNoArchive: "no_archive",
HsmFileLost: "lost",
}
func (s HsmFileState) String() string {
return fmt.Sprintf("%#x %s", s, strings.Join(s.Flags(), " "))
}
func (f HsmStateFlag) String() string {
return HsmStateFlags[f]
}
// HasFlag checks to see if the supplied flag matches
func (s HsmFileState) HasFlag(flag HsmStateFlag) bool {
return uint32(s)&uint32(flag) > 0
}
// Flags returns a list of flag strings
func (s HsmFileState) Flags() []string {
var flagStrings []string
for flag, str := range HsmStateFlags {
if s.HasFlag(flag) {
flagStrings = append(flagStrings, str)
}
}
return flagStrings
}
// GetHsmFileStatus returns the HSM state and archive number for the given file.
func GetHsmFileStatus(filePath string) (HsmFileState, uint32, error) {
hus := C._hsm_user_state_alloc()
defer C.free(unsafe.Pointer(hus))
buf := C.CString(filePath)
defer C.free(unsafe.Pointer(buf))
rc, err := C.llapi_hsm_state_get(buf, hus)
if err != nil {
return 0, 0, err
}
if rc > 0 {
return 0, 0, fmt.Errorf("Got %d from llapi_hsm_state_get, expected 0", rc)
}
return HsmFileState(hus.hus_states), uint32(hus.hus_archive_id), nil
}
// SetHsmFileStatus updates the file's HSM flags and/or archive ID
func SetHsmFileStatus(filePath string, setMask, clearMask uint64, archiveID uint32) error {
buf := C.CString(filePath)
defer C.free(unsafe.Pointer(buf))
rc, err := C.llapi_hsm_state_set(buf, C.__u64(setMask), C.__u64(clearMask), C.__u32(archiveID))
if rc > 0 {
return fmt.Errorf("Got %d from llapi_hsm_state_set, expected 0", rc)
}
return err
}