Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fixes aof file permission with arbitrary user #91

Open
wants to merge 4 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
17 changes: 0 additions & 17 deletions core/aof.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,11 +2,8 @@ package core

import (
"fmt"
"log"
"os"
"strings"

"github.com/dicedb/dice/config"
)

// TODO: Support Expiration
Expand All @@ -17,17 +14,3 @@ func dumpKey(fp *os.File, key string, obj *Obj) {
tokens := strings.Split(cmd, " ")
fp.Write(Encode(tokens, false))
}

// TODO: To to new and switch
func DumpAllAOF() {
fp, err := os.OpenFile(config.AOFFile, os.O_CREATE|os.O_WRONLY, os.ModeAppend)
if err != nil {
fmt.Print("error", err)
return
}
log.Println("rewriting AOF file at", config.AOFFile)
for k, obj := range store {
dumpKey(fp, k, obj)
}
log.Println("AOF file rewrite complete")
}
41 changes: 41 additions & 0 deletions core/aof_darwin.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
package core

import (
"fmt"
"github.com/dicedb/dice/config"
"log"
"os"
)

func FileSync(f *os.File) error {
_, _, err := syscall.Syscall(syscall.SYS_FCNTL, f.Fd(), syscall.F_FULLFSYNC, 0)
if err == 0 {
return nil
}
return err
}

// TODO: To to new and switch
func DumpAllAOF() error {
fp, err := os.OpenFile(config.AOFFile, os.O_APPEND|os.O_CREATE|os.O_WRONLY, 0644)
if err != nil {
return err
}
/* Note: A close function also returns an error, a plain defer is harmful.
A successful close does not guarantee that the data has been successfully saved
to disk,as the kernel uses the buffer cache to defer writes or write calls delays the writing
to disk to mitigate cost of frequent writes to disk. A more reliable method is to use
fsync() or f.Sync() and Close()
*/
defer func() {
if err := fp.Close(); err != nil {
fmt.Print("error", err)
return
}
}()
log.Println("rewriting AOF file at", config.AOFFile)
for k, obj := range store {
dumpKey(fp, k, obj)
}
return FileSync(fp)
}
33 changes: 33 additions & 0 deletions core/aof_linux.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
package core

import (
"fmt"
"github.com/dicedb/dice/config"
"log"
"os"
)

// TODO: To to new and switch
func DumpAllAOF() error {
fp, err := os.OpenFile(config.AOFFile, os.O_APPEND|os.O_CREATE|os.O_WRONLY, 0644)
if err != nil {
return err
}
/* Note: A close function also returns an error, a plain defer is harmful.
A successful close does not guarantee that the data has been successfully saved
to disk,as the kernel uses the buffer cache to defer writes or write calls delays the writing
to disk to mitigate cost of frequent writes to disk. A more reliable method is to use
fsync() or f.Sync() and Close()
*/
defer func() {
if err := fp.Close(); err != nil {
fmt.Print("error", err)
return
}
}()
log.Println("rewriting AOF file at", config.AOFFile)
for k, obj := range store {
dumpKey(fp, k, obj)
}
return fp.Sync()
}
18 changes: 14 additions & 4 deletions core/eval.go
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ import (
"bytes"
"errors"
"fmt"
"log"
"strconv"
"syscall"
"time"
Expand Down Expand Up @@ -46,7 +47,9 @@ func evalPING(args []string) []byte {
// evalSET puts a new <key, value> pair in db as in the args
// args must contain key and value.
// args can also contain multiple options -
// EX or ex which will set the expiry time(in secs) for the key
//
// EX or ex which will set the expiry time(in secs) for the key
//
// Returns encoded error response if at least a <key, value> pair is not part of args
// Returns encoded error response if expiry tme value in not integer
// Returns encoded OK RESP once new entry is added
Expand Down Expand Up @@ -116,8 +119,9 @@ func evalGET(args []string) []byte {
// evalTTL returns Time-to-Live in secs for the queried key in args
// The key should be the only param in args else returns with an error
// Returns RESP encoded time (in secs) remaining for the key to expire
// RESP encoded -2 stating key doesn't exist or key is expired
// RESP encoded -1 in case no expiration is set on the key
//
// RESP encoded -2 stating key doesn't exist or key is expired
// RESP encoded -1 in case no expiration is set on the key
func evalTTL(args []string) []byte {
if len(args) != 1 {
return Encode(errors.New("ERR wrong number of arguments for 'ttl' command"), false)
Expand Down Expand Up @@ -206,7 +210,13 @@ func evalBGREWRITEAOF(args []string) []byte {
newChild, _, _ := syscall.Syscall(syscall.SYS_FORK, 0, 0, 0)
if newChild == 0 {
//We are inside child process now, so we'll start flushing to disk.
DumpAllAOF()
err := DumpAllAOF()
if err != nil {
return Encode(errors.New("ERR AOF failed"), false)
} else {
log.Println("AOF file rewrite completed")
}
syscall.Exit(0)
return []byte("")
} else {
//Back to main thread
Expand Down
2 changes: 2 additions & 0 deletions main.go
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,8 @@ func main() {

var sigs chan os.Signal = make(chan os.Signal, 1)
signal.Notify(sigs, syscall.SIGTERM, syscall.SIGINT)
//Need to clean up zombie process as soon as they appear once AOF background thread exits.
signal.Ignore(syscall.SIGCHLD)
var wg sync.WaitGroup
wg.Add(1)

Expand Down