]> Cypherpunks.ru repositories - nncp.git/commitdiff
Sync directories for rename assurance
authorSergey Matveev <stargrave@stargrave.org>
Mon, 9 Dec 2019 13:20:47 +0000 (16:20 +0300)
committerSergey Matveev <stargrave@stargrave.org>
Fri, 13 Dec 2019 15:37:30 +0000 (18:37 +0300)
VERSION
doc/news.ru.texi
doc/news.texi
src/cmd/nncp-bundle/main.go
src/cmd/nncp-reass/main.go
src/cmd/nncp-xfer/main.go
src/sp.go
src/tmp.go
src/toss.go

diff --git a/VERSION b/VERSION
index ac14c3dfaa865ea332c62348d1bca867bdbbd1cf..61fcc87350341bc51d640aa9161073ce615703ce 100644 (file)
--- a/VERSION
+++ b/VERSION
@@ -1 +1 @@
-5.1.1
+5.1.2
index 6cf154b9df23e7af3948851e317a41cd18716482..d99a621ecac048171d449be586b48b6d14a9599c 100644 (file)
@@ -1,6 +1,16 @@
 @node Новости
 @section Новости
 
+@node Релиз 5.1.2
+@subsection Релиз 5.1.2
+@itemize
+
+@item
+Явная синхронизация (fsync) директорий для гарантированного
+переименования файлов.
+
+@end itemize
+
 @node Релиз 5.1.1
 @subsection Релиз 5.1.1
 @itemize
index 3e04abb053d7c81487a96d082cad7d404db7c479..5b9d06bba8fe43683531d9b4ee37f075db2eba26 100644 (file)
@@ -3,6 +3,15 @@
 
 See also this page @ref{Новости, on russian}.
 
+@node Release 5.1.2
+@section Release 5.1.2
+@itemize
+
+@item
+Explicit directories fsync-ing for guaranteed files renaming.
+
+@end itemize
+
 @node Release 5.1.1
 @section Release 5.1.1
 @itemize
index 380b3917e7e5706253a0cecbd43a4fbc416aac13..60bb1130c83d09559084b633d7f5c3f9cea1c5d7 100644 (file)
@@ -378,6 +378,9 @@ func main() {
                                        if err = os.Rename(tmp.Name(), dstPath); err != nil {
                                                log.Fatalln("Error during renaming:", err)
                                        }
+                                       if err = nncp.DirSync(selfPath); err != nil {
+                                               log.Fatalln("Error during syncing:", err)
+                                       }
                                }
                        }
                        ctx.LogI("nncp-bundle", nncp.SdsAdd(sds, nncp.SDS{
index d7d79b082d327d964fc514112bb0c0a2b11c8097..161e86f602ad53961ac2167d503b121f71e0960a 100644 (file)
@@ -238,6 +238,9 @@ func process(ctx *nncp.Ctx, path string, keep, dryRun, stdout, dumpMeta bool) bo
        if err = os.Rename(tmp.Name(), dstPath); err != nil {
                log.Fatalln(err)
        }
+       if err = nncp.DirSync(mainDir); err != nil {
+               log.Fatalln(err)
+       }
        ctx.LogI("nncp-reass", nncp.SDS{"path": path}, "done")
        return !hasErrors
 }
index cfe16b779c6bff49586e34e79808c12a969fba3e..c784b4e6bfade94a0105447ac95a595133f154d2 100644 (file)
@@ -330,6 +330,11 @@ Tx:
                                isBad = true
                                continue
                        }
+                       if err = nncp.DirSync(dstPath); err != nil {
+                               ctx.LogE("nncp-xfer", nncp.SdsAdd(sds, nncp.SDS{"err": err}), "sync")
+                               isBad = true
+                               continue
+                       }
                        os.Remove(filepath.Join(dstPath, pktName+".part"))
                        delete(sds, "tmp")
                        ctx.LogI("nncp-xfer", nncp.SdsAdd(sds, nncp.SDS{
index 540e0e52a22a4f016114ca8a9fed71599802ed54..b6e49b415e06b8f9f7a9b65f5079ff25e7d16dd6 100644 (file)
--- a/src/sp.go
+++ b/src/sp.go
@@ -838,12 +838,12 @@ func (state *SPState) ProcessSP(payload []byte) ([][]byte, error) {
                        sdsp["xx"] = string(TRx)
                        sdsp["hash"] = ToBase32(file.Hash[:])
                        sdsp["size"] = strconv.Itoa(len(file.Payload))
-                       filePath := filepath.Join(
+                       dirToSync := filepath.Join(
                                state.Ctx.Spool,
                                state.Node.Id.String(),
                                string(TRx),
-                               ToBase32(file.Hash[:]),
                        )
+                       filePath := filepath.Join(dirToSync, ToBase32(file.Hash[:]))
                        state.Ctx.LogD("sp-file", sdsp, "opening part")
                        fd, err := os.OpenFile(
                                filePath+PartSuffix,
@@ -901,7 +901,14 @@ func (state *SPState) ProcessSP(payload []byte) ([][]byte, error) {
                                        return
                                }
                                state.Ctx.LogI("sp-done", SdsAdd(sdsp, SDS{"xx": string(TRx)}), "")
-                               os.Rename(filePath+PartSuffix, filePath)
+                               if err = os.Rename(filePath+PartSuffix, filePath); err != nil {
+                                       state.Ctx.LogE("sp-file", SdsAdd(sdsp, SDS{"err": err}), "rename")
+                                       return
+                               }
+                               if err = DirSync(dirToSync); err != nil {
+                                       state.Ctx.LogE("sp-file", SdsAdd(sdsp, SDS{"err": err}), "sync")
+                                       return
+                               }
                                state.Lock()
                                delete(state.infosTheir, *file.Hash)
                                state.Unlock()
index 95e45ee4a6162a3eb01ea084ecce9c6606f804e6..0784b996eea067656966f6e2b5bfb8a516f31242 100644 (file)
@@ -79,6 +79,19 @@ func (tmp *TmpFileWHash) Cancel() {
        os.Remove(tmp.Fd.Name())
 }
 
+func DirSync(dirPath string) error {
+       fd, err := os.Open(dirPath)
+       if err != nil {
+               return err
+       }
+       err = fd.Sync()
+       if err != nil {
+               fd.Close()
+               return err
+       }
+       return fd.Close()
+}
+
 func (tmp *TmpFileWHash) Commit(dir string) error {
        var err error
        if err = os.MkdirAll(dir, os.FileMode(0777)); err != nil {
@@ -95,5 +108,8 @@ func (tmp *TmpFileWHash) Commit(dir string) error {
        tmp.Fd.Close()
        checksum := ToBase32(tmp.Hsh.Sum(nil))
        tmp.ctx.LogD("tmp", SDS{"src": tmp.Fd.Name(), "dst": checksum}, "commit")
-       return os.Rename(tmp.Fd.Name(), filepath.Join(dir, checksum))
+       if err = os.Rename(tmp.Fd.Name(), filepath.Join(dir, checksum)); err != nil {
+               return err
+       }
+       return DirSync(dir)
 }
index 586f378076746fb689338dd14f0df44b75fc7860..5bc8b7960b79b8d2e904405b1e1aacd7282672d8 100644 (file)
@@ -261,6 +261,10 @@ func (ctx *Ctx) Toss(
                                        ctx.LogE("rx", SdsAdd(sds, SDS{"err": err}), "rename")
                                        isBad = true
                                }
+                               if err = DirSync(*incoming); err != nil {
+                                       ctx.LogE("rx", SdsAdd(sds, SDS{"err": err}), "sync")
+                                       isBad = true
+                               }
                                delete(sds, "tmp")
                        }
                        ctx.LogI("rx", sds, "")