@node Новости
@section Новости
+@node Релиз 6.1.0
+@subsection Релиз 6.1.0
+@itemize
+
+@item
+Оптимизация: большинство команд теперь не держат открытыми файловые
+дескрипторы. Прежде вы легко могли выйти за пределы максимально
+допустимого количества открытых файлов, если у вас было много пакетов в
+spool директории.
+
+@end itemize
+
@node Релиз 6.0.0
@subsection Релиз 6.0.0
@itemize
See also this page @ref{Новости, on russian}.
+@node Release 6.1.0
+@section Release 6.1.0
+@itemize
+
+@item
+Optimization: most commands do not keep opened file descriptors now.
+Previously you can exceed maximal number of opened files if you have got
+many packets in the spool directory.
+
+@end itemize
+
@node Release 6.0.0
@section Release 6.0.0
@itemize
-@item Log uses human readable and easy machine parseable
+@item
+Log uses human readable and easy machine parseable
@url{https://www.gnu.org/software/recutils/, recfile} format for the
records, instead of structured RFC 3339 lines. Old logs are not readable
by @command{nncp-log} anymore.
"errors"
"io"
"log"
+ "os"
"golang.org/x/crypto/blake2b"
)
{"Pkt", Base32Codec.EncodeToString(job.HshValue[:])},
{"FullSize", job.Size},
}
- gut, err := Check(job.Fd, job.HshValue[:], les, ctx.ShowPrgrs)
- job.Fd.Close() // #nosec G104
+ fd, err := os.Open(job.Path)
+ if err != nil {
+ ctx.LogE("check", les, err, "")
+ return true
+ }
+ gut, err := Check(fd, job.HshValue[:], les, ctx.ShowPrgrs)
+ fd.Close() // #nosec G104
if err != nil {
ctx.LogE("check", les, err, "")
return true
{K: "Pkt", V: "dummy"},
}
for job := range ctx.Jobs(&nodeId, nncp.TTx) {
- pktName = filepath.Base(job.Fd.Name())
+ pktName = filepath.Base(job.Path)
les[len(les)-1].V = pktName
if job.PktEnc.Nice > nice {
ctx.LogD("nncp-bundle", les, "too nice")
- job.Fd.Close() // #nosec G104
continue
}
+ fd, err := os.Open(job.Path)
+ if err != nil {
+ log.Fatalln("Error during opening:", err)
+ }
if err = tarWr.WriteHeader(&tar.Header{
Format: tar.FormatUSTAR,
Name: nncp.NNCPBundlePrefix,
log.Fatalln("Error writing tar header:", err)
}
if _, err = nncp.CopyProgressed(
- tarWr, job.Fd, "Tx",
+ tarWr, bufio.NewReader(fd), "Tx",
append(les, nncp.LEs{
{K: "Pkt", V: nncp.Base32Codec.EncodeToString(job.HshValue[:])},
{K: "FullSize", V: job.Size},
); err != nil {
log.Fatalln("Error during copying to tar:", err)
}
- job.Fd.Close() // #nosec G104
+ if err = fd.Close(); err != nil {
+ log.Fatalln("Error during closing:", err)
+ }
if err = tarWr.Flush(); err != nil {
log.Fatalln("Error during tar flushing:", err)
}
log.Fatalln("Error during stdout flushing:", err)
}
if *doDelete {
- if err = os.Remove(job.Fd.Name()); err != nil {
+ if err = os.Remove(job.Path); err != nil {
log.Fatalln("Error during deletion:", err)
}
}
ctx.LogD("caller", les, "checking tx existence")
txExists := false
for job := range ctx.Jobs(node.Id, nncp.TTx) {
- job.Fd.Close()
if job.PktEnc.Nice > call.Nice {
continue
}
rxNums := make(map[uint8]int)
rxBytes := make(map[uint8]int64)
for job := range ctx.Jobs(node.Id, nncp.TRx) {
- job.Fd.Close() // #nosec G104
if *showPkt {
jobPrint(nncp.TRx, job)
}
txNums := make(map[uint8]int)
txBytes := make(map[uint8]int64)
for job := range ctx.Jobs(node.Id, nncp.TTx) {
- job.Fd.Close() // #nosec G104
if *showPkt {
jobPrint(nncp.TTx, job)
}
}
les = les[:len(les)-1]
for job := range ctx.Jobs(&nodeId, nncp.TTx) {
- pktName := filepath.Base(job.Fd.Name())
+ pktName := filepath.Base(job.Path)
les := append(les, nncp.LE{K: "Pkt", V: pktName})
if job.PktEnc.Nice > nice {
ctx.LogD("nncp-xfer", les, "too nice")
- job.Fd.Close() // #nosec G104
continue
}
if _, err = os.Stat(filepath.Join(dstPath, pktName)); err == nil || !os.IsNotExist(err) {
ctx.LogD("nncp-xfer", les, "already exists")
- job.Fd.Close() // #nosec G104
continue
}
if _, err = os.Stat(filepath.Join(dstPath, pktName+nncp.SeenSuffix)); err == nil || !os.IsNotExist(err) {
ctx.LogD("nncp-xfer", les, "already exists")
- job.Fd.Close() // #nosec G104
continue
}
tmp, err := nncp.TempFile(dstPath, "xfer")
if err != nil {
ctx.LogE("nncp-xfer", les, err, "mktemp")
- job.Fd.Close() // #nosec G104
isBad = true
break
}
les = append(les, nncp.LE{K: "Tmp", V: tmp.Name()})
ctx.LogD("nncp-xfer", les, "created")
+ fd, err := os.Open(job.Path)
+ if err != nil {
+ ctx.LogE("nncp-xfer", les, err, "open")
+ tmp.Close() // #nosec G104
+ isBad = true
+ continue
+ }
bufW := bufio.NewWriter(tmp)
copied, err := nncp.CopyProgressed(
- bufW, bufio.NewReader(job.Fd), "Tx",
+ bufW, bufio.NewReader(fd), "Tx",
append(les, nncp.LE{K: "FullSize", V: job.Size}),
ctx.ShowPrgrs,
)
- job.Fd.Close() // #nosec G104
+ fd.Close() // #nosec G104
if err != nil {
ctx.LogE("nncp-xfer", les, err, "copy")
tmp.Close() // #nosec G104
les = les[:len(les)-1]
ctx.LogI("nncp-xfer", append(les, nncp.LE{K: "Size", V: copied}), "")
if !*keep {
- if err = os.Remove(job.Fd.Name()); err != nil {
+ if err = os.Remove(job.Path); err != nil {
ctx.LogE("nncp-xfer", les, err, "remove")
isBad = true
}
package nncp
import (
- "io"
"os"
"path/filepath"
type Job struct {
PktEnc *PktEnc
- Fd *os.File
+ Path string
Size int64
HshValue *[32]byte
}
if err != nil {
continue
}
- fd, err := os.Open(filepath.Join(rxPath, fi.Name()))
+ pth := filepath.Join(rxPath, fi.Name())
+ fd, err := os.Open(pth)
if err != nil {
continue
}
var pktEnc PktEnc
- if _, err = xdr.Unmarshal(fd, &pktEnc); err != nil || pktEnc.Magic != MagicNNCPEv4 {
- fd.Close() // #nosec G104
- continue
- }
- if _, err = fd.Seek(0, io.SeekStart); err != nil {
- fd.Close() // #nosec G104
+ _, err = xdr.Unmarshal(fd, &pktEnc)
+ fd.Close()
+ if err != nil || pktEnc.Magic != MagicNNCPEv4 {
continue
}
ctx.LogD("jobs", LEs{
}, "taken")
job := Job{
PktEnc: &pktEnc,
- Fd: fd,
+ Path: pth,
Size: fi.Size(),
HshValue: new([32]byte),
}
)
var (
- Version string = "6.0.0"
+ Version string = "6.1.0"
Base32Codec *base32.Encoding = base32.StdEncoding.WithPadding(base32.NoPadding)
)
var infos []*SPInfo
var totalSize int64
for job := range ctx.Jobs(nodeId, TTx) {
- job.Fd.Close() // #nosec G104
if job.PktEnc.Nice > nice {
continue
}
}
defer decompressor.Close()
for job := range ctx.Jobs(nodeId, TRx) {
- pktName := filepath.Base(job.Fd.Name())
+ pktName := filepath.Base(job.Path)
les := LEs{{"Node", job.PktEnc.Sender}, {"Pkt", pktName}}
if job.PktEnc.Nice > nice {
ctx.LogD("rx", append(les, LE{"Nice", int(job.PktEnc.Nice)}), "too nice")
- job.Fd.Close() // #nosec G104
continue
}
+ fd, err := os.Open(job.Path)
+ if err != nil {
+ ctx.LogE("rx", les, err, "open")
+ isBad = true
+ continue
+ }
+
pipeR, pipeW := io.Pipe()
go func(job Job) error {
pipeWB := bufio.NewWriter(pipeW)
- _, _, err := PktEncRead(
- ctx.Self,
- ctx.Neigh,
- bufio.NewReader(job.Fd),
- pipeWB,
- )
- job.Fd.Close() // #nosec G104
+ _, _, err := PktEncRead(ctx.Self, ctx.Neigh, bufio.NewReader(fd), pipeWB)
+ fd.Close() // #nosec G104
if err != nil {
return pipeW.CloseWithError(err)
}
return pipeW.Close()
}(job)
var pkt Pkt
- var err error
var pktSize int64
var pktSizeBlocks int64
if _, err = xdr.Unmarshal(pipeR, &pkt); err != nil {
ctx.LogI("rx", les, "")
if !dryRun {
if doSeen {
- if fd, err := os.Create(job.Fd.Name() + SeenSuffix); err == nil {
+ if fd, err := os.Create(job.Path + SeenSuffix); err == nil {
fd.Close() // #nosec G104
}
}
- if err = os.Remove(job.Fd.Name()); err != nil {
+ if err = os.Remove(job.Path); err != nil {
ctx.LogE("rx", les, err, "remove")
isBad = true
}
ctx.LogI("rx", les, "")
if !dryRun {
if doSeen {
- if fd, err := os.Create(job.Fd.Name() + SeenSuffix); err == nil {
+ if fd, err := os.Create(job.Path + SeenSuffix); err == nil {
fd.Close() // #nosec G104
}
}
- if err = os.Remove(job.Fd.Name()); err != nil {
+ if err = os.Remove(job.Path); err != nil {
ctx.LogE("rx", les, err, "remove")
isBad = true
}
ctx.LogI("rx", les, "")
if !dryRun {
if doSeen {
- if fd, err := os.Create(job.Fd.Name() + SeenSuffix); err == nil {
+ if fd, err := os.Create(job.Path + SeenSuffix); err == nil {
fd.Close() // #nosec G104
}
}
- if err = os.Remove(job.Fd.Name()); err != nil {
+ if err = os.Remove(job.Path); err != nil {
ctx.LogE("rx", les, err, "remove")
isBad = true
}
ctx.LogI("rx", les, "")
if !dryRun {
if doSeen {
- if fd, err := os.Create(job.Fd.Name() + SeenSuffix); err == nil {
+ if fd, err := os.Create(job.Path + SeenSuffix); err == nil {
fd.Close() // #nosec G104
}
}
- if err = os.Remove(job.Fd.Name()); err != nil {
+ if err = os.Remove(job.Path); err != nil {
ctx.LogE("rx", les, err, "remove")
isBad = true
}
}
for job := range ctx.Jobs(ctx.Self.Id, TTx) {
var buf bytes.Buffer
- _, _, err := PktEncRead(ctx.Self, ctx.Neigh, job.Fd, &buf)
+ fd, err := os.Open(job.Path)
+ if err != nil {
+ t.Error(err)
+ return false
+ }
+ _, _, err = PktEncRead(ctx.Self, ctx.Neigh, fd, &buf)
if err != nil {
t.Error(err)
return false
return false
}
txJob := sentJobs[0]
- defer txJob.Fd.Close()
+ fd, err := os.Open(txJob.Path)
+ if err != nil {
+ panic(err)
+ }
+ defer fd.Close()
var bufR bytes.Buffer
- if _, err = io.Copy(&bufR, txJob.Fd); err != nil {
+ if _, err = io.Copy(&bufR, fd); err != nil {
panic(err)
}
var bufW bytes.Buffer