Skip to content

Commit 568d778

Browse files
Corbin Phelpssamuelkarp
authored andcommitted
handlers: moved fifo setup/cleanup to handler
fifos for Firecracker logs and metrics are now created and queued for cleanup in CreateLogFilesHandler. This removes warnings when using the jailer and setting other paths for the fifos. Fixes: #133 Original contribution: #134 Signed-off-by: Samuel Karp <[email protected]>
1 parent 7ce9cc0 commit 568d778

File tree

4 files changed

+115
-18
lines changed

4 files changed

+115
-18
lines changed

.gitignore

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,3 +2,5 @@ firecracker
22
jailer
33
firecracker-*
44
vmlinux
5+
root-drive.img
6+
TestPID.img

handlers.go

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@ package firecracker
1616
import (
1717
"context"
1818
"fmt"
19+
"os"
1920
)
2021

2122
// Handler name constants
@@ -135,6 +136,27 @@ var CreateLogFilesHandler = Handler{
135136
return err
136137
}
137138

139+
m.cleanupFuncs = append(m.cleanupFuncs,
140+
func() error {
141+
if err := os.Remove(logFifoPath); !os.IsNotExist(err) {
142+
return err
143+
}
144+
return nil
145+
},
146+
func() error {
147+
if err := os.Remove(metricsFifoPath); !os.IsNotExist(err) {
148+
return err
149+
}
150+
return nil
151+
},
152+
)
153+
154+
if m.Cfg.FifoLogWriter != nil {
155+
if err := captureFifoToFile(m.logger, logFifoPath, m.Cfg.FifoLogWriter); err != nil {
156+
m.logger.Warnf("captureFifoToFile() returned %s. Continuing anyway.", err)
157+
}
158+
}
159+
138160
m.logger.Debug("Created metrics and logging fifos.")
139161

140162
return nil

handlers_test.go

Lines changed: 91 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,16 +1,19 @@
11
package firecracker
22

33
import (
4+
"bytes"
45
"context"
56
"fmt"
67
"os"
78
"path/filepath"
89
"reflect"
910
"testing"
11+
"time"
1012

1113
models "github.com/firecracker-microvm/firecracker-go-sdk/client/models"
1214
ops "github.com/firecracker-microvm/firecracker-go-sdk/client/operations"
1315
"github.com/firecracker-microvm/firecracker-go-sdk/fctesting"
16+
"github.com/pkg/errors"
1417
)
1518

1619
func TestHandlerListAppend(t *testing.T) {
@@ -660,6 +663,76 @@ func TestHandlers(t *testing.T) {
660663
}
661664
}
662665

666+
func TestCreateLogFilesHandler(t *testing.T) {
667+
logWriterBuf := &bytes.Buffer{}
668+
config := Config{
669+
LogFifo: filepath.Join(testDataPath, "firecracker-log.fifo"),
670+
MetricsFifo: filepath.Join(testDataPath, "firecracker-metrics.fifo"),
671+
FifoLogWriter: logWriterBuf,
672+
}
673+
674+
defer func() {
675+
os.Remove(config.LogFifo)
676+
os.Remove(config.MetricsFifo)
677+
}()
678+
679+
ctx := context.Background()
680+
m, err := NewMachine(ctx, config, WithLogger(fctesting.NewLogEntry(t)))
681+
if err != nil {
682+
t.Fatalf("failed to create machine: %v", err)
683+
}
684+
685+
// spin off goroutine to write to Log fifo so we don't block
686+
doneChan := make(chan struct{}, 1)
687+
go func() {
688+
defer close(doneChan)
689+
690+
// try to open file
691+
fifoPipe, err := openFileRetry(config.LogFifo)
692+
if err != nil {
693+
t.Error(err)
694+
}
695+
696+
if _, err := fifoPipe.WriteString("data\n"); err != nil {
697+
t.Errorf("Failed to write to fifo %v", err)
698+
}
699+
700+
fifoPipe.Close()
701+
return
702+
}()
703+
704+
// Execute Handler
705+
if err := CreateLogFilesHandler.Fn(ctx, m); err != nil {
706+
t.Errorf("failed to call CreateLogFilesHandler function: %v", err)
707+
return
708+
}
709+
710+
// Block until writing go routine is done to check data that was written
711+
<-doneChan
712+
713+
// Poll for verifying logs were written as we need to allow time
714+
// for copying from the log fifo into the FifoLogWriter
715+
timer := time.NewTimer(1 * time.Second)
716+
for {
717+
select {
718+
case <-timer.C:
719+
t.Fatal("timed out reading from log writer")
720+
default:
721+
logData, err := logWriterBuf.ReadString('\n')
722+
if err != nil {
723+
time.Sleep(10 * time.Millisecond)
724+
continue
725+
}
726+
727+
if logData != "data\n" {
728+
t.Errorf("expected 'data' written to log got '%s'", logData)
729+
}
730+
return
731+
}
732+
}
733+
734+
}
735+
663736
func compareHandlerLists(l1, l2 HandlerList) bool {
664737
if l1.Len() != l2.Len() {
665738
return false
@@ -681,3 +754,21 @@ func compareHandlerLists(l1, l2 HandlerList) bool {
681754

682755
return true
683756
}
757+
758+
func openFileRetry(filePath string) (file *os.File, err error) {
759+
timer := time.NewTimer(1 * time.Second)
760+
for {
761+
select {
762+
case <-timer.C:
763+
err = errors.New("timed out waiting for file")
764+
return
765+
default:
766+
file, err = os.OpenFile(filePath, os.O_WRONLY, os.ModePerm)
767+
if err == nil {
768+
timer.Stop()
769+
return
770+
}
771+
time.Sleep(10 * time.Millisecond)
772+
}
773+
}
774+
}

machine.go

Lines changed: 0 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -455,18 +455,6 @@ func (m *Machine) startVMM(ctx context.Context) error {
455455
}
456456
return nil
457457
},
458-
func() error {
459-
if err := os.Remove(m.Cfg.LogFifo); !os.IsNotExist(err) {
460-
return err
461-
}
462-
return nil
463-
},
464-
func() error {
465-
if err := os.Remove(m.Cfg.MetricsFifo); !os.IsNotExist(err) {
466-
return err
467-
}
468-
return nil
469-
},
470458
)
471459

472460
errCh := make(chan error)
@@ -585,12 +573,6 @@ func (m *Machine) setupLogging(ctx context.Context) error {
585573
m.Cfg.MetricsFifo,
586574
)
587575

588-
if m.Cfg.FifoLogWriter != nil {
589-
if err := captureFifoToFile(m.logger, m.Cfg.LogFifo, m.Cfg.FifoLogWriter); err != nil {
590-
return err
591-
}
592-
}
593-
594576
return nil
595577
}
596578

0 commit comments

Comments
 (0)