From b06d2796f8196cf1899afeadd3552ef12637bd70 Mon Sep 17 00:00:00 2001 From: Yicheng Qin Date: Wed, 9 Apr 2014 09:56:18 -0700 Subject: [PATCH] feat: set NOCOW for log directory when in btrfs --- etcd/etcd.go | 6 ++++ pkg/fs/.util_linux.go.swp | Bin 0 -> 12288 bytes pkg/fs/fs.go | 60 ++++++++++++++++++++++++++++++++++++++ pkg/fs/fs_test.go | 21 +++++++++++++ test.sh | 3 ++ 5 files changed, 90 insertions(+) create mode 100644 pkg/fs/.util_linux.go.swp create mode 100644 pkg/fs/fs.go create mode 100644 pkg/fs/fs_test.go diff --git a/etcd/etcd.go b/etcd/etcd.go index c4c5db783..8c94ac89f 100644 --- a/etcd/etcd.go +++ b/etcd/etcd.go @@ -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() diff --git a/pkg/fs/.util_linux.go.swp b/pkg/fs/.util_linux.go.swp new file mode 100644 index 0000000000000000000000000000000000000000..36326a025aaa4d8f9c8b8bd1b52db9c65a53c77e GIT binary patch literal 12288 zcmeI2&u<$=6vro2LUL&-P|;>|~4-X6)EBO@nf1ogcE4)}>CVI9coU?0S{;j=M9P z)S|#202ieG0|<`X0QCYA=Sm=P03=Qbj$Gk@#G&6A+li7wXt@DzrB8O(Z{~U4=gmfn zvc1~ttt8tH0blC+y9S#ev$>TlE005U)Z9@Ri$qL-IWvPONOW~aR1o#UsU zyYZ;AX&f0K17v^fDHT#4FrA0o;?np!s7A&|JmRFznx<2SMUq?5qt-}1^2*b;8XB1 zcn`b_Zh;Os4;r8jj)9+^X6y^_A-D_P2fLsN&Vp0m1o-|WW1oPJzz5(CP+$mB&;;|~ zIQabp)&sr*_rd4jF1QN*Kpj7TZ@|~!9+033mca#Z8rXWD2Xv4DGC&5%02v?yWPl9( z&kelAN`2WY;xzNUM1>|5S{jk5Q0)p`grSsuugppqR?4L*@(dS$G9gNXSc@n~Qad_{ zcvB3=E}!2NNoM@0U#{@=PPf%=b~|fZ>zkK0Iu-7}Y%>DVmn7mvr z^K&b_#@}Qmd(ZEzAT4rSZ8zIDyX%`rFDphJkF~6g$6r?I;o|;57Ue-z z)wIRf)T?$MN51Cm&ZzqrE_jh|BymAzC4HudbQT%Majj)!3#ds+6mQ7GLmav2#Q zYu_ZS&C2Mw5l&Qv&ttLWSDn~>*|v4~{LqZ}=PKiF2rkkwbG>Wn%hu1rOcOcQU{m$9+NjCW^ z#!&I0=a%E4y!}e8wzRldtM5f;8{b8jCeZ~KojtEEfHG2Rt CrpGJ* literal 0 HcmV?d00001 diff --git a/pkg/fs/fs.go b/pkg/fs/fs.go new file mode 100644 index 000000000..6af3af3a8 --- /dev/null +++ b/pkg/fs/fs.go @@ -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) +} diff --git a/pkg/fs/fs_test.go b/pkg/fs/fs_test.go new file mode 100644 index 000000000..5098b3ebc --- /dev/null +++ b/pkg/fs/fs_test.go @@ -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) + } + } +} diff --git a/test.sh b/test.sh index 981649bcf..cf2a2e8a7 100755 --- a/test.sh +++ b/test.sh @@ -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