Skip to content

Commit 3ac029f

Browse files
committed
PR: move log file creation/management to (*Container).Start
Signed-off-by: Hamza El-Saawy <hamzaelsaawy@microsoft.com>
1 parent d054668 commit 3ac029f

File tree

2 files changed

+35
-27
lines changed

2 files changed

+35
-27
lines changed

internal/guest/runtime/hcsv2/container.go

Lines changed: 29 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -48,7 +48,8 @@ type Container struct {
4848
id string
4949

5050
vsock transport.Transport
51-
logFile *os.File
51+
logPath string // path to [logFile].
52+
logFile *os.File // file to redirect container's stdio to.
5253

5354
spec *oci.Spec
5455
ociBundlePath string
@@ -77,14 +78,37 @@ type Container struct {
7778
scratchDirPath string
7879
}
7980

80-
func (c *Container) Start(ctx context.Context, conSettings stdio.ConnectionSettings) (int, error) {
81-
log.G(ctx).WithField(logfields.ContainerID, c.id).Info("opengcs::Container::Start")
81+
func (c *Container) Start(ctx context.Context, conSettings stdio.ConnectionSettings) (_ int, err error) {
82+
entity := log.G(ctx).WithField(logfields.ContainerID, c.id)
83+
entity.Info("opengcs::Container::Start")
8284

8385
// only use the logfile for the init process, since we don't want to tee stdio of execs
8486
t := c.vsock
85-
if c.logFile != nil {
87+
if c.logPath != "" {
88+
// don't use [os.Create] since that truncates an existing file, which is not desired
89+
if c.logFile, err = os.OpenFile(c.logPath, os.O_RDWR|os.O_CREATE, 0666); err != nil {
90+
return -1, fmt.Errorf("failed to open log file: %s: %w", c.logPath, err)
91+
}
92+
go func() {
93+
// initProcess is already created in [(*Host).CreateContainer], and is, therefore, "waitable"
94+
// wait in `writersWg`, which is closed after process is cleaned up (including io Relays)
95+
//
96+
// Note: [PipeRelay] and [TtyRelay] are not safe to call multiple times, so it is safer to wait
97+
// on the parent (init) process.
98+
c.initProcess.writersWg.Wait()
99+
100+
if lfErr := c.logFile.Close(); lfErr != nil {
101+
entity.WithFields(logrus.Fields{
102+
logrus.ErrorKey: err,
103+
logfields.Path: c.logFile.Name(),
104+
}).Warn("failed to close log file")
105+
}
106+
c.logFile = nil
107+
}()
108+
86109
t = transport.NewMultiWriter(c.vsock, c.logFile)
87110
}
111+
88112
stdioSet, err := stdio.Connect(t, conSettings)
89113
if err != nil {
90114
return -1, err
@@ -189,24 +213,12 @@ func (c *Container) GetAllProcessPids(ctx context.Context) ([]int, error) {
189213

190214
// Kill sends 'signal' to the container process.
191215
func (c *Container) Kill(ctx context.Context, signal syscall.Signal) error {
192-
entity := log.G(ctx).WithField(logfields.ContainerID, c.id)
193-
entity.Info("opengcs::Container::Kill")
216+
log.G(ctx).WithField(logfields.ContainerID, c.id).Info("opengcs::Container::Kill")
194217
err := c.container.Kill(signal)
195218
if err != nil {
196219
return err
197220
}
198-
199221
c.setExitType(signal)
200-
if c.logFile != nil {
201-
if err = c.logFile.Close(); err != nil {
202-
entity.WithFields(logrus.Fields{
203-
logrus.ErrorKey: err,
204-
logfields.Path: c.logFile.Name(),
205-
}).Warn("failed to close log file")
206-
}
207-
c.logFile = nil
208-
}
209-
210222
return nil
211223
}
212224

internal/guest/runtime/hcsv2/uvm.go

Lines changed: 6 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -502,24 +502,20 @@ func (h *Host) CreateContainer(ctx context.Context, id string, settings *prot.VM
502502
return nil, errors.Errorf("teeing container stdio to log path %q denied due to policy not allowing stdio access", logPath)
503503
}
504504

505-
logPath = specGuest.SandboxLogPath(sandboxID, logPath)
505+
c.logPath = specGuest.SandboxLogPath(sandboxID, logPath)
506506
// verify the logpath is still under the correct directory
507-
if !strings.HasPrefix(logPath, specGuest.SandboxLogsDir(sandboxID)) {
508-
return nil, errors.Errorf("log path %v is not within sandbox's log dir", logPath)
507+
if !strings.HasPrefix(c.logPath, specGuest.SandboxLogsDir(sandboxID)) {
508+
return nil, errors.Errorf("log path %v is not within sandbox's log dir", c.logPath)
509509
}
510510

511+
dir := filepath.Dir(c.logPath)
511512
log.G(ctx).WithFields(logrus.Fields{
512-
logfields.Path: logPath,
513+
logfields.Path: dir,
513514
logfields.ContainerID: id,
514-
}).Debug("creating container log file in uVM")
515-
dir := filepath.Dir(logPath)
515+
}).Debug("creating container log file parent directory in uVM")
516516
if err := mkdirAllModePerm(dir); err != nil {
517517
return nil, errors.Wrapf(err, "failed to create log file parent directory: %s", dir)
518518
}
519-
// don't use [os.Create] since that truncates an existing file, which is not desired
520-
if c.logFile, err = os.OpenFile(logPath, os.O_RDWR|os.O_CREATE, 0666); err != nil {
521-
return nil, errors.Wrapf(err, "failed to create log file: %s", logPath)
522-
}
523519
}
524520

525521
if envToKeep != nil {

0 commit comments

Comments
 (0)