-
Notifications
You must be signed in to change notification settings - Fork 7
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Signed-off-by: black-desk <me@black-desk.cn>
- Loading branch information
1 parent
ad5f56e
commit 9770260
Showing
7 changed files
with
231 additions
and
4 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,10 @@ | ||
package cgfsmon2 | ||
|
||
import "errors" | ||
|
||
var ( | ||
ErrContextMissing = errors.New("context is missing.") | ||
ErrCGroupRootNotFound = errors.New("cgroup v2 file system mount point is missing.") | ||
ErrLoggerMissing = errors.New("logger is missing.") | ||
ErrUnderlingWatcherExited = errors.New("underling file system watcher has exited.") | ||
) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,76 @@ | ||
package cgfsmon2 | ||
|
||
import ( | ||
"github.com/black-desk/cgtproxy/pkg/cgtproxy/config" | ||
"github.com/black-desk/cgtproxy/pkg/types" | ||
. "github.com/black-desk/lib/go/errwrap" | ||
"github.com/rjeczalik/notify" | ||
"go.uber.org/zap" | ||
) | ||
|
||
type CGroupFSMonitor struct { | ||
eventsOut chan types.CGroupEvent | ||
eventsIn chan notify.EventInfo | ||
|
||
root config.CGroupRoot | ||
log *zap.SugaredLogger | ||
} | ||
|
||
func New(opts ...Opt) (ret *CGroupFSMonitor, err error) { | ||
defer Wrap(&err, "create filesystem watcher") | ||
|
||
w := &CGroupFSMonitor{} | ||
|
||
w.eventsOut = make(chan types.CGroupEvent) | ||
w.eventsIn = make(chan notify.EventInfo) | ||
|
||
for i := range opts { | ||
w, err = opts[i](w) | ||
if err != nil { | ||
return | ||
} | ||
} | ||
|
||
if w.log == nil { | ||
w.log = zap.NewNop().Sugar() | ||
} | ||
|
||
if w.root == "" { | ||
err = ErrCGroupRootNotFound | ||
return | ||
} | ||
|
||
ret = w | ||
|
||
w.log.Debugw("Create a new filesystem watcher.") | ||
|
||
return | ||
} | ||
|
||
type Opt func(w *CGroupFSMonitor) (ret *CGroupFSMonitor, err error) | ||
|
||
func WithCgroupRoot(root config.CGroupRoot) Opt { | ||
return func(w *CGroupFSMonitor) (ret *CGroupFSMonitor, err error) { | ||
if root == "" { | ||
err = ErrCGroupRootNotFound | ||
return | ||
} | ||
|
||
w.root = root | ||
ret = w | ||
return | ||
} | ||
} | ||
|
||
func WithLogger(log *zap.SugaredLogger) Opt { | ||
return func(w *CGroupFSMonitor) (ret *CGroupFSMonitor, err error) { | ||
if log == nil { | ||
err = ErrLoggerMissing | ||
return | ||
} | ||
|
||
w.log = log | ||
ret = w | ||
return | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,82 @@ | ||
package cgfsmon2 | ||
|
||
import ( | ||
"context" | ||
"errors" | ||
"io/fs" | ||
"path/filepath" | ||
"strings" | ||
|
||
"github.com/black-desk/cgtproxy/pkg/types" | ||
) | ||
|
||
func (m *CGroupFSMonitor) walkFn(ctx context.Context) func(path string, d fs.DirEntry, err error) error { | ||
return func(path string, d fs.DirEntry, err error) error { | ||
if err != nil { | ||
if errors.Is(err, fs.ErrNotExist) { | ||
m.log.Debug( | ||
"Cgroup had been removed.", | ||
"path", path, | ||
) | ||
err = nil | ||
} | ||
m.log.Errorw( | ||
"Errors occurred while first time going through cgroupfs.", | ||
"path", path, | ||
"error", err, | ||
) | ||
err = nil | ||
} | ||
|
||
if !d.IsDir() { | ||
return nil | ||
} | ||
|
||
cgEvent := &types.CGroupEvent{ | ||
Path: path, | ||
EventType: types.CgroupEventTypeNew, | ||
} | ||
|
||
err = m.send(ctx, cgEvent) | ||
if err != nil { | ||
return err | ||
} | ||
|
||
return nil | ||
} | ||
} | ||
|
||
func (m *CGroupFSMonitor) walk(ctx context.Context, path string) { | ||
err := filepath.WalkDir(path, m.walkFn(ctx)) | ||
if err == nil { | ||
return | ||
} | ||
|
||
return | ||
} | ||
|
||
func (m *CGroupFSMonitor) send(ctx context.Context, cgEvent *types.CGroupEvent) (err error) { | ||
path := strings.TrimRight(cgEvent.Path, "/") | ||
cgEvent.Path = path | ||
|
||
if cgEvent.Path == string(m.root) { | ||
// NOTE: Ignore cgroup root. | ||
return nil | ||
} | ||
|
||
m.log.Debugw("New cgroup envent.", | ||
"event", cgEvent, | ||
) | ||
|
||
select { | ||
case <-ctx.Done(): | ||
err = ctx.Err() | ||
return | ||
case m.eventsOut <- *cgEvent: | ||
m.log.Debugw("Cgroup event sent.", | ||
"path", path, | ||
) | ||
} | ||
|
||
return | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,55 @@ | ||
package cgfsmon2 | ||
|
||
import ( | ||
"context" | ||
|
||
"github.com/black-desk/cgtproxy/pkg/types" | ||
. "github.com/black-desk/lib/go/errwrap" | ||
"github.com/rjeczalik/notify" | ||
) | ||
|
||
func (w *CGroupFSMonitor) Events() <-chan types.CGroupEvent { | ||
return w.eventsOut | ||
} | ||
|
||
func (w *CGroupFSMonitor) Run(ctx context.Context) (err error) { | ||
defer Wrap(&err, "running filesystem watcher") | ||
defer close(w.eventsOut) | ||
defer notify.Stop(w.eventsIn) | ||
defer close(w.eventsIn) | ||
|
||
err = notify.Watch(string(w.root)+"/...", w.eventsIn, notify.Create, notify.Remove) | ||
if err != nil { | ||
return | ||
} | ||
|
||
w.log.Info("Going through cgroupfs first time...") | ||
w.walk(ctx, string(w.root)) | ||
w.log.Info("Going through cgroupfs first time...Done.") | ||
|
||
LOOP: | ||
for { | ||
select { | ||
case <-ctx.Done(): | ||
break LOOP | ||
case event := <-w.eventsIn: | ||
eventType := types.CgroupEventTypeNew | ||
if event.Event() == notify.InDelete { | ||
eventType = types.CgroupEventTypeDelete | ||
} | ||
|
||
err = w.send(ctx, &types.CGroupEvent{ | ||
Path: event.Path(), | ||
EventType: eventType, | ||
}) | ||
} | ||
} | ||
|
||
<-ctx.Done() | ||
err = ctx.Err() | ||
if err != nil { | ||
return | ||
} | ||
|
||
return | ||
} |