Devmapper: consistency issue bugfixes#3436
Devmapper: consistency issue bugfixes#3436renzhengeek wants to merge 3 commits intocontainerd:masterfrom
Conversation
|
Build succeeded.
|
79fb413 to
3e2f3bf
Compare
|
Build succeeded.
|
3e2f3bf to
c21ab01
Compare
|
Build succeeded.
|
On extreme cases, like crash or underlaying disk disappear, this code path could be taken in deleting snapshot: 1. failed to activate thin device, then rollback follows; 2. failed to delete thin device; 3. succeed to remove device info in metadata. After recovery, it will fail to work: """ failed to create containerd container: failed to create snapshot \"vg0-mythinpool-snap-1083\" (dev: 59) from \"vg0-mythinpool-snap-19\" (dev: 6): 1 error occurred:\n\n* file exists" """ because dev:59 is free in database, but exists in kernel. Signed-off-by: Eric Ren <[email protected]>
c21ab01 to
cb7e03a
Compare
|
Build succeeded.
|
cb7e03a to
e27a829
Compare
|
Build succeeded.
|
|
Can you elaborate a bit on the story behind this patch. In which cases |
|
Hi,
As said in commit log, the result is blow, but what is missing in commit log is a reproducer, will represent one blow: “”“ """
"snap-id" is an auto-increase from upper snapshotter code. So, containerd will keep trying to create snapshot with this "snap-id", but only failed with "object already exists" error.
diff --git a/snapshots/devmapper/pool_device.go b/snapshots/devmapper/pool_device.go
index 680d8b1..7db66d8 100644
--- a/snapshots/devmapper/pool_device.go
+++ b/snapshots/devmapper/pool_device.go
@@ -22,6 +22,7 @@ import (
"context"
"path/filepath"
"strconv"
+ "fmt"
"github.com/hashicorp/go-multierror"
"github.com/pkg/errors"
@@ -90,6 +91,10 @@ func (p *PoolDevice) transition(ctx context.Context, deviceName string, tryingSt
result = multierror.Append(result, err)
}
+ //log.G(ctx).Fatalf("Inject fault: dev: %s, state: %v --> %v", deviceName, tryingState, successState)
+ msg := fmt.Sprintf("Inject fault: dev: %s, state: %v --> %v", deviceName, tryingState, successState)
+ panic(msg)
+
// If operation succeeded transition to success state, otherwise save error details
uerr = p.metadata.UpdateDevice(ctx, deviceName, func(deviceInfo *DeviceInfo) error {
if err == nil {
I know that my proposed fix is not very good:-/ Another idea occurs to my mind is, since the issue only happens when extreme cases, like machine crash and disk disappear, after which a container restart is likely required, so can we remove the problematic device info in place when reloading devmapper plugin? Thank you for looking at this issue! |
|
I also encountered the same problem. After repairing the disk and restarting the machine, the creation of the device still fails with the following error: The problem should occur in the
|
|
Hi,
The first patch is exactly trying to fix this problem. Thanks for confirming! |
6be89b9 to
1dde9a3
Compare
dmsetup remove with "--deferred" option may remove device in kernel latter than the time when its device info has been removed in database, causing the "file exists" error as previous commit. This error really happens in our extreme testing: power off server and disk disappear while k8s is creating/deleting pods. The fix reveals a testcase bug in "TestSnapshotterSuite/RemoveIntermediateSnapshot", for block device snapshot, we should umount the snapshot before removing it. Signed-off-by: Eric Ren <[email protected]>
All cases that crash/panic happens in between steps to perform creating/deleting snapshot will cause the error below after containerd starts again: """ time="2019-07-19T15:40:02.331427856+08:00" level=error msg="failed to create snapshot device from parent vg0-mythinpool-snap-1" error="failed to save initial metadata for snapshot "vg0-mythinpool-snap-4": object already exists" time="2019-07-19T15:40:02.331436436+08:00" level=debug msg="snapshotter error" error="1 error occurred: * failed to save initial metadata for snapshot "vg0-mythinpool-snap-4": object already exists" """ My thoughts were to move the aborted-state device into an orphan bucket, and remove the orphan devices when devmapper plugin is reloaded, making it configurable is a plus. However, removing an orphan device is not that easy without invasive change. This is corner case, so the devices in orphan buket is less enough for people to look and take actions such as: 1. stop containerd; 2. delete thin device if exists; 3. remove orphan devie info. Signed-off-by: Eric Ren <[email protected]>
1dde9a3 to
76d612c
Compare
|
Build succeeded.
|
Codecov Report
@@ Coverage Diff @@
## master #3436 +/- ##
==========================================
- Coverage 44.11% 44.08% -0.03%
==========================================
Files 124 124
Lines 13760 13768 +8
==========================================
Hits 6070 6070
- Misses 6759 6764 +5
- Partials 931 934 +3
Continue to review full report at Codecov.
|
|
I have a few ideas I'd like to experiment with. I'll update here or will post an additional PR. |
Hi, However, one problem I can think up is, when it needs manual handling, how can I find the faulty devices to look at and repair? We can develop handy tool to scan the database to find the "faulty" device, so please make it easy for such tool to distinguish "faulty" devices as possible :-) |
This should be straightforward. There is a table I think it's a good idea to develop a tool that would simplify devmapper database introspection and recovery. |
Hi,
These are several patches for problems we've seen in our testing.
In extreme test cases, like hard reboot and force unplug disk while k8s is actively working, we've seen 2 kind of errors as below because of inconsistency occurring between devmapper database and thin-pool, which cause errors to create snapshot/pod afterward:
Please help review and give feedback to improve the fixes, thanks!