-
Notifications
You must be signed in to change notification settings - Fork 324
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
[pkg] panic if no space is left #3636
Changes from 1 commit
6dc29de
0bbce28
d0d57a4
e4688a8
7c3bf2d
dc643c7
2d5eac7
0fd1091
9f3b564
2d38686
259f084
7919ab0
41f1a09
b3d8b12
b6bbdd2
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,73 @@ | ||
// Copyright (c) 2022 IoTeX Foundation | ||
// This is an alpha (internal) release and is not suitable for production. This source code is provided 'as is' and no | ||
// warranties are given as to title or non-infringement, merchantability or fitness for purpose and, to the extent | ||
// permitted by law, all liability for your use of the code is disclaimed. This source code is governed by Apache | ||
// License 2.0 that can be found in the LICENSE file. | ||
|
||
package fsnotify | ||
|
||
import ( | ||
"context" | ||
|
||
"github.com/fsnotify/fsnotify" | ||
"github.com/shirou/gopsutil/v3/disk" | ||
"go.uber.org/zap" | ||
|
||
"github.com/iotexproject/iotex-core/pkg/log" | ||
) | ||
|
||
// Watch creates dir watcher to hanlde events from os in loop | ||
func Watch(ctx context.Context, dirs ...string) { | ||
watcher, err := fsnotify.NewWatcher() | ||
if err != nil { | ||
log.L().Fatal("Failed to create fsnotify watcher.", zap.Error(err)) | ||
} | ||
defer watcher.Close() | ||
|
||
for _, dir := range dirs { | ||
if err = watcher.Add(dir); err != nil { | ||
log.L().Fatal("Failed to watch dir: "+dir, zap.Error(err)) | ||
} | ||
} | ||
log.S().Infof("Watch dirs: %+v", dirs) | ||
|
||
watchLoop(ctx, watcher) | ||
} | ||
|
||
// watchLoop receives events and errors from os | ||
func watchLoop(ctx context.Context, watcher *fsnotify.Watcher) { | ||
for { | ||
select { | ||
case <-ctx.Done(): | ||
return | ||
case ev, ok := <-watcher.Events: | ||
if !ok { | ||
log.L().Error("Failed to get watcher events.") | ||
continue | ||
} | ||
// check disk space per write operation | ||
if ev.Has(fsnotify.Write) { | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. fsnotify.Create needed too There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. It's still left enough space to run program even if |
||
checkDiskSpace(ctx) | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. all filesystem write ops trig a check, may inefficient |
||
} | ||
case err, ok := <-watcher.Errors: | ||
if !ok { | ||
log.L().Error("Failed to get watcher errors.") | ||
continue | ||
} | ||
log.L().Error("watch file error", zap.Error(err)) | ||
} | ||
} | ||
} | ||
|
||
// checkDiskSpace returns the disk usage info | ||
func checkDiskSpace(ctx context.Context) { | ||
usage, err := disk.Usage("/") | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. if os disk partition like this
and iotex-core run within /run, the check may not work There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. |
||
if err != nil { | ||
log.L().Error("Failed to get disk usage.", zap.Error(err)) | ||
return | ||
} | ||
// panic if no space or no inodes | ||
if usage.Free == 0 || usage.InodesFree == 0 { | ||
log.L().Fatal("No space in device.", zap.Float64("UsedPercent", usage.UsedPercent), zap.Float64("InodesUsedPercent", usage.InodesUsedPercent)) | ||
} | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,41 @@ | ||
// Copyright (c) 2022 IoTeX Foundation | ||
// This is an alpha (internal) release and is not suitable for production. This source code is provided 'as is' and no | ||
// warranties are given as to title or non-infringement, merchantability or fitness for purpose and, to the extent | ||
// permitted by law, all liability for your use of the code is disclaimed. This source code is governed by Apache | ||
// License 2.0 that can be found in the LICENSE file. | ||
|
||
package fsnotify | ||
|
||
import ( | ||
"context" | ||
"os" | ||
"testing" | ||
"time" | ||
|
||
"github.com/stretchr/testify/require" | ||
|
||
"github.com/iotexproject/iotex-core/testutil" | ||
) | ||
|
||
func TestWatch(t *testing.T) { | ||
var ( | ||
require = require.New(t) | ||
dir = t.TempDir() | ||
times int | ||
) | ||
|
||
ctx, cancel := context.WithCancel(context.Background()) | ||
go Watch(ctx, dir) | ||
|
||
f, err := os.CreateTemp(dir, "log") | ||
require.NoError(err) | ||
defer f.Close() | ||
|
||
require.NoError(testutil.WaitUntil(100*time.Millisecond, 1*time.Second, func() (b bool, e error) { | ||
err = os.WriteFile(f.Name(), []byte("test"), 0666) | ||
require.NoError(err) | ||
times++ | ||
return times >= 5, nil | ||
})) | ||
cancel() | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
when does an event come