feat: set NOCOW for log directory when in btrfs

This commit is contained in:
Yicheng Qin 2014-04-09 09:56:18 -07:00
parent 84ad6ddd79
commit b06d2796f8
5 changed files with 90 additions and 0 deletions

View File

@ -33,6 +33,7 @@ import (
ehttp "github.com/coreos/etcd/http"
"github.com/coreos/etcd/log"
"github.com/coreos/etcd/metrics"
"github.com/coreos/etcd/pkg/fs"
"github.com/coreos/etcd/server"
"github.com/coreos/etcd/store"
)
@ -102,6 +103,11 @@ func (e *Etcd) Run() {
log.Warnf("All cached configuration is now ignored. The file %s can be removed.", info)
}
// Set NOCOW for data directory in btrfs
if fs.IsBtrfs(e.Config.DataDir) {
fs.SetNOCOW(e.Config.DataDir)
}
var mbName string
if e.Config.Trace() {
mbName = e.Config.MetricsBucketName()

BIN
pkg/fs/.util_linux.go.swp Normal file

Binary file not shown.

60
pkg/fs/fs.go Normal file
View File

@ -0,0 +1,60 @@
package fs
import (
"os"
"runtime"
"syscall"
"unsafe"
"github.com/coreos/etcd/log"
)
const (
// from Linux/include/uapi/linux/magic.h
BTRFS_SUPER_MAGIC = 0x9123683E
// from Linux/include/uapi/linux/fs.h
FS_NOCOW_FL = 0x00800000
FS_IOC_GETFLAGS = 0x80086601
FS_IOC_SETFLAGS = 0x40086602
)
// IsBtrfs checks whether the file is in btrfs
func IsBtrfs(path string) bool {
// btrfs is developed on linux only
if runtime.GOOS != "linux" {
return false
}
var buf syscall.Statfs_t
if err := syscall.Statfs(path, &buf); err != nil {
log.Warnf("Failed to statfs: %v", err)
return false
}
log.Debugf("The type of path %v is %v", path, buf.Type)
if buf.Type != BTRFS_SUPER_MAGIC {
return false
}
log.Infof("The path %v is in btrfs", path)
return true
}
// SetNOCOW sets NOCOW flag for the file
func SetNOCOW(path string) {
file, err := os.Open(path)
if err != nil {
log.Warnf("Failed to open %v: %v", path, err)
return
}
defer file.Close()
var attr int
if _, _, errno := syscall.Syscall(syscall.SYS_IOCTL, file.Fd(), FS_IOC_GETFLAGS, uintptr(unsafe.Pointer(&attr))); errno != 0 {
log.Warnf("Failed to get file flags: %v", errno.Error())
return
}
attr |= FS_NOCOW_FL
if _, _, errno := syscall.Syscall(syscall.SYS_IOCTL, file.Fd(), FS_IOC_SETFLAGS, uintptr(unsafe.Pointer(&attr))); errno != 0 {
log.Warnf("Failed to set file flags: %v", errno.Error())
return
}
log.Infof("Set NOCOW to path %v succeed", path)
}

21
pkg/fs/fs_test.go Normal file
View File

@ -0,0 +1,21 @@
package fs
import (
"os/exec"
"strings"
"testing"
)
func TestSetNOCOW(t *testing.T) {
if IsBtrfs("/") {
SetNOCOW("/")
cmd := exec.Command("lsattr", "/")
out, err := cmd.Output()
if err != nil {
t.Fatal("Failed executing lsattr")
}
if strings.Contains(string(out), "---------------C") {
t.Fatal("Failed setting NOCOW:\n", out)
}
}
}

View File

@ -23,6 +23,9 @@ go test -v ./server/v2/tests
go test -i ./mod/lock/v2/tests
go test -v ./mod/lock/v2/tests
go test -i ./pkg/fs
go test -v ./pkg/fs
go test -i ./tests/functional
ETCD_BIN_PATH=$(pwd)/bin/etcd go test -v ./tests/functional