diff options
author | FUJITA Tomonori <fujita.tomonori@lab.ntt.co.jp> | 2015-11-12 14:47:59 +0900 |
---|---|---|
committer | FUJITA Tomonori <fujita.tomonori@lab.ntt.co.jp> | 2015-11-12 15:01:12 +0900 |
commit | 95e7cc73083dfbc161b4ac6b0271c006d822d38d (patch) | |
tree | f76aeb30f19ee66aca066f366f105c0d0a5bf20c /server/watcher.go | |
parent | 180d68f88f457096ec92bcb6eabd915a64bb8858 (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.go | 57 |
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 |