summaryrefslogtreecommitdiffhomepage
path: root/server/watcher.go
diff options
context:
space:
mode:
authorFUJITA Tomonori <fujita.tomonori@lab.ntt.co.jp>2015-11-12 14:47:59 +0900
committerFUJITA Tomonori <fujita.tomonori@lab.ntt.co.jp>2015-11-12 15:01:12 +0900
commit95e7cc73083dfbc161b4ac6b0271c006d822d38d (patch)
treef76aeb30f19ee66aca066f366f105c0d0a5bf20c /server/watcher.go
parent180d68f88f457096ec92bcb6eabd915a64bb8858 (diff)
mrt: support reset/rotate commands
$ gobgp mrt update reset create a new file or reopen the existing file and continue to write update messages to it. $ gobgp mrt update <filename> rename the current logging file to <filename> and truncate the logging file and continue to write update messages to it. Signed-off-by: FUJITA Tomonori <fujita.tomonori@lab.ntt.co.jp>
Diffstat (limited to 'server/watcher.go')
-rw-r--r--server/watcher.go57
1 files changed, 53 insertions, 4 deletions
diff --git a/server/watcher.go b/server/watcher.go
index a4c3a192..bed70538 100644
--- a/server/watcher.go
+++ b/server/watcher.go
@@ -16,6 +16,7 @@
package server
import (
+ "fmt"
log "github.com/Sirupsen/logrus"
"github.com/osrg/gobgp/packet"
"gopkg.in/tomb.v2"
@@ -66,14 +67,21 @@ type watcherEventUpdateMsg struct {
type watcher interface {
notify(watcherEventType) chan watcherEvent
+ restart(string) error
stop()
}
+type mrtWatcherOp struct {
+ filename string //used for rotate
+ result chan error
+}
+
type mrtWatcher struct {
t tomb.Tomb
filename string
file *os.File
ch chan watcherEvent
+ opCh chan *mrtWatcherOp
}
func (w *mrtWatcher) notify(t watcherEventType) chan watcherEvent {
@@ -87,7 +95,21 @@ func (w *mrtWatcher) stop() {
w.t.Kill(nil)
}
+func (w *mrtWatcher) restart(filename string) error {
+ adminOp := &mrtWatcherOp{
+ filename: filename,
+ result: make(chan error),
+ }
+ select {
+ case w.opCh <- adminOp:
+ default:
+ return fmt.Errorf("already an admin operaiton in progress")
+ }
+ return <-adminOp.result
+}
+
func (w *mrtWatcher) loop() error {
+ defer w.file.Close()
for {
write := func(ev watcherEvent) {
m := ev.(*watcherEventUpdateMsg)
@@ -117,28 +139,55 @@ func (w *mrtWatcher) loop() error {
}
}
- select {
- case <-w.t.Dying():
+ drain := func() {
for len(w.ch) > 0 {
m := <-w.ch
write(m)
}
+ }
+
+ select {
+ case <-w.t.Dying():
+ drain()
return nil
case m := <-w.ch:
write(m)
+ case adminOp := <-w.opCh:
+ var err error
+ if adminOp.filename != "" {
+ err = os.Rename(w.file.Name(), adminOp.filename)
+ }
+ if err == nil {
+ var file *os.File
+ file, err = mrtFileOpen(w.file.Name())
+ if err == nil {
+ w.file.Close()
+ w.file = file
+ }
+ }
+ adminOp.result <- err
}
}
}
-func newMrtWatcher(filename string) (*mrtWatcher, error) {
+func mrtFileOpen(filename string) (*os.File, error) {
file, err := os.OpenFile(filename, os.O_CREATE|os.O_RDWR|os.O_APPEND, 0644)
if err != nil {
- log.Fatal(err)
+ log.Warn(err)
+ }
+ return file, err
+}
+
+func newMrtWatcher(filename string) (*mrtWatcher, error) {
+ file, err := mrtFileOpen(filename)
+ if err != nil {
+ return nil, err
}
w := mrtWatcher{
filename: filename,
file: file,
ch: make(chan watcherEvent),
+ opCh: make(chan *mrtWatcherOp, 1),
}
w.t.Go(w.loop)
return &w, nil