Skip to content
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.

Commit ef7998c

Browse files
committedDec 12, 2024·
phd: make in-memory backend test work for Alpine
1 parent ae0f618 commit ef7998c

File tree

1 file changed

+22
-20
lines changed

1 file changed

+22
-20
lines changed
 

‎phd-tests/tests/src/disk.rs

+22-20
Original file line numberDiff line numberDiff line change
@@ -145,19 +145,6 @@ async fn in_memory_backend_smoke_test(ctx: &Framework) {
145145

146146
#[phd_testcase]
147147
async fn in_memory_backend_migration_test(ctx: &Framework) {
148-
// This test verifies that live-migrating a disk with an in-memory backend
149-
// copies the backend's data from the source to the target. To do that, it
150-
// uses `dd` flags to (try to) force writes to be synchronized to disk
151-
// immediately and to force reads to bypass the guest OS's caches.
152-
//
153-
// Dynamic tracing of block backend activity shows that Alpine guests don't
154-
// reliably read from underlying storage even when `iflag=direct` is used.
155-
// This can cause this test to pass incorrectly. Unless and until a more
156-
// reliable way to bypass caches is found, skip this test on Alpine.
157-
if let GuestOsKind::Alpine = ctx.default_guest_os_kind().await? {
158-
phd_skip!("iflag=direct doesn't work as required on Alpine");
159-
}
160-
161148
// A blank disk is fine for this test: the rest of the test will address the
162149
// disk device directly instead of assuming it has a file system. This works
163150
// around #824 for Windows guests (which may not recognize the FAT
@@ -170,11 +157,17 @@ async fn in_memory_backend_migration_test(ctx: &Framework) {
170157
)
171158
.await?;
172159

173-
// Scribble random data into the first kilobyte of the data disk. Use
174-
// `oflag=sync` to force the guest OS to ensure this data is actually
175-
// persisted to the device (and not just held in an in-memory cache).
160+
// Scribble random data into the first kilobyte of the data disk, passing
161+
// the appropriate flags to ensure that the guest actually writes the data
162+
// to the disk (instead of just holding it in memory).
163+
let force_sync = if let GuestOsKind::Alpine = vm.guest_os_kind() {
164+
"conv=sync"
165+
} else {
166+
"oflag=sync"
167+
};
168+
176169
vm.run_shell_command(&format!(
177-
"dd if=/dev/random of={device_path} oflag=sync bs=1K count=1"
170+
"dd if=/dev/random of={device_path} {force_sync} bs=1K count=1"
178171
))
179172
.await?;
180173

@@ -197,15 +190,24 @@ async fn in_memory_backend_migration_test(ctx: &Framework) {
197190
.migrate_from(&vm, Uuid::new_v4(), MigrationTimeout::default())
198191
.await?;
199192

200-
// Read the scribbled data again. Use `iflag=direct` to try to get the guest
201-
// to read this data back from the physical device instead of its disk
202-
// cache.
193+
// Read the scribbled data back from the disk. On most guests, adding
194+
// `iflag=direct` to the `dd` invocation is sufficient to bypass the guest's
195+
// caches and read from the underlying disk. Alpine guests appear also to
196+
// need a procfs poke to drop page caches before they'll read from the disk.
197+
if let GuestOsKind::Alpine = vm.guest_os_kind() {
198+
target.run_shell_command("sync").await?;
199+
target.run_shell_command("echo 3 > /proc/sys/vm/drop_caches").await?;
200+
}
201+
203202
target
204203
.run_shell_command(&format!(
205204
"dd if={device_path} of=/tmp/after iflag=direct bs=1K"
206205
))
207206
.await?;
208207

208+
// The data that was scribbled before migrating should match what was read
209+
// back from the disk. If it doesn't, migration restored the original
210+
// (blank) disk contents, which is incorrect.
209211
let out = target
210212
.run_shell_command("diff --report-identical /tmp/before /tmp/after")
211213
.await?;

0 commit comments

Comments
 (0)
Please sign in to comment.