diff --git a/repos/gems/lib/mk/tresor.mk b/repos/gems/lib/mk/tresor.mk
index bcf420be6f..1e5417d84a 100644
--- a/repos/gems/lib/mk/tresor.mk
+++ b/repos/gems/lib/mk/tresor.mk
@@ -1,7 +1,6 @@
TRESOR_DIR := $(REP_DIR)/src/lib/tresor
SRC_CC += crypto.cc
-SRC_CC += request_pool.cc
SRC_CC += hash.cc
SRC_CC += trust_anchor.cc
SRC_CC += block_io.cc
@@ -9,7 +8,6 @@ SRC_CC += meta_tree.cc
SRC_CC += virtual_block_device.cc
SRC_CC += superblock_control.cc
SRC_CC += free_tree.cc
-SRC_CC += module.cc
SRC_CC += vbd_initializer.cc
SRC_CC += ft_initializer.cc
SRC_CC += sb_initializer.cc
diff --git a/repos/gems/lib/mk/vfs_tresor.mk b/repos/gems/lib/mk/vfs_tresor.mk
index 88ed1baf9e..549024bf5c 100644
--- a/repos/gems/lib/mk/vfs_tresor.mk
+++ b/repos/gems/lib/mk/vfs_tresor.mk
@@ -1,6 +1,6 @@
LIB_DIR := $(REP_DIR)/src/lib/vfs/tresor
-SRC_CC := vfs.cc splitter.cc
+SRC_CC := vfs.cc
INC_DIR += $(LIB_DIR)
diff --git a/repos/gems/run/tresor_tester.run b/repos/gems/run/tresor_tester.run
index 402ed36509..e864e69b25 100644
--- a/repos/gems/run/tresor_tester.run
+++ b/repos/gems/run/tresor_tester.run
@@ -238,7 +238,7 @@ append config {
-
+
-
-
-
-
-
-
+
+
+
+
+
+
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
-
+
-
+
-
-
-
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
-
-
+
+
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
-
+
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+
@@ -403,195 +400,195 @@ append config {
-
+
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
-
+
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
-
+
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
-
+
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
-
+
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
-
+
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
-
+
-
+
@@ -612,439 +609,439 @@ if {[benchmark_blk_count] > 0} {
append config {
-
+
-
-
-
+
+
+
-
-
-
+
+
+
-
-
-
+
+
+
-
-
-
+
+
+
-
+
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
-
+
-
+
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
-
+
}
@@ -1052,18 +1049,18 @@ if {[benchmark_blk_count] > 0} {
append config {
-
+
}
}
append config {
-
+
-
-
-
-
-
+
+
+
+
+
diff --git a/repos/gems/run/vfs_tresor.run b/repos/gems/run/vfs_tresor.run
index 10c81a8e0e..7cf48b2ee6 100644
--- a/repos/gems/run/vfs_tresor.run
+++ b/repos/gems/run/vfs_tresor.run
@@ -1,24 +1,26 @@
assert_spec linux
+set dd [installed_command dd]
+
create_boot_directory
-proc tresor_image_file { } {
- return "vfs_tresor_block.img"
-}
+proc tresor_image_name { } { return "vfs_tresor_block.img" }
-set use_interactively [expr ![get_cmd_switch --autopilot]]
+proc tresor_image_size_mb { } { return 4 }
-import_from_depot [depot_user]/pkg/[drivers_interactive_pkg] \
- [depot_user]/pkg/terminal \
- [depot_user]/src/ncurses \
+proc local_tresor_image { } { return bin/[tresor_image_name] }
+
+proc autopilot_tresor_image { } { return /tmp/[tresor_image_name].[exec id -un] }
+
+import_from_depot [depot_user]/src/ncurses \
[depot_user]/src/bash \
- [depot_user]/src/coreutils \
- [depot_user]/src/nitpicker
-
+ [depot_user]/src/coreutils
build {
- core lib/ld timer init
- server/lx_fs
+ core
+ timer
+ init
+ lib/ld
lib/vfs_tresor
lib/vfs_tresor_crypto_aes_cbc
lib/vfs_tresor_crypto_memcopy
@@ -26,17 +28,24 @@ build {
lib/vfs_import
lib/vfs_jitterentropy
lib/vfs_pipe
- lib/vfs lib/libc lib/posix lib/libcrypto
+ lib/vfs
+ lib/libc
+ lib/libm
+ lib/posix
+ lib/libcrypto
test/vfs_stress
test/libc
server/log_terminal
server/report_rom
server/fs_rom
+ server/lx_fs
+ server/vfs
app/tresor_init_trust_anchor
+ app/tresor_init
app/sequence
}
-set config {
+append config {
@@ -54,64 +63,20 @@ set config {
+
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- }
-
-append_if $use_interactively config {
-
-
-
-
-
-
-
-
-
-
- }
-
-append_if [expr !$use_interactively] config {
-
-
+
- }
+
-append config {
@@ -127,15 +92,9 @@ append config {
-
-
-
-
-
-
+
@@ -146,8 +105,7 @@ append config {
-
-
+
@@ -156,12 +114,37 @@ append config {
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
@@ -188,12 +171,12 @@ append config {
-
+
-
+
@@ -202,8 +185,6 @@ append config {
-
-
@@ -230,7 +211,7 @@ append config {
-
+
@@ -266,21 +247,23 @@ append config {
-
-
+
+
-
+
+
+
-
-
-
+
+
+
@@ -294,19 +277,28 @@ set shell_script "run/vfs_tresor.sh"
set repo "[repository_contains $shell_script]"
exec cp $repo/$shell_script bin/
+exec rm -rf [local_tresor_image]
+if { [get_cmd_switch --autopilot] } {
+
+ exec rm -rf [autopilot_tresor_image]
+ catch { exec $dd if=/dev/urandom of=[autopilot_tresor_image] bs=1M count=[tresor_image_size_mb] }
+ exec ln -sf -T [autopilot_tresor_image] [local_tresor_image]
+
+} else {
+
+ catch { exec $dd if=/dev/urandom of=[local_tresor_image] bs=1M count=[tresor_image_size_mb] }
+}
+
set boot_modules [build_artifacts]
-
-append boot_modules { vfs_tresor.sh encrypted_private_key superblock_hash }
-lappend boot_modules [tresor_image_file]
-
-set fd [open [run_dir]/genode/focus w]
-puts $fd " \" domain=\"default\"/>"
-close $fd
+append boot_modules { vfs_tresor.sh }
+lappend boot_modules [tresor_image_name]
build_boot_image $boot_modules
-if {$use_interactively} {
- run_genode_until forever
-} else {
- run_genode_until {.*--- Automated Tresor testing finished.*} 1800
+run_genode_until {.*"/bin/bash".* exited with exit value 0.*\n} 120
+
+if { [get_cmd_switch --autopilot] } {
+
+ exec rm -rf [local_tresor_image]
+ exec rm -rf [autopilot_tresor_image]
}
diff --git a/repos/gems/run/vfs_tresor.sh b/repos/gems/run/vfs_tresor.sh
index bfc4f955eb..3fea3fd2d0 100644
--- a/repos/gems/run/vfs_tresor.sh
+++ b/repos/gems/run/vfs_tresor.sh
@@ -55,33 +55,25 @@ test_read_compare_1() {
fi
}
-test_create_snapshot() {
+test_deinitialize() {
local tresor_dir="$1"
-
- echo "Create snapshot"
- echo true > $tresor_dir/control/create_snapshot
+ echo "Deinitialize"
+ local state="$(< $tresor_dir/control/deinitialize)"
+ echo true > $tresor_dir/control/deinitialize
}
-test_list_snapshots() {
+wait_for_deinitialize() {
local tresor_dir="$1"
-
- echo "List content of '$tresor_dir'"
- ls -l $tresor_dir/snapshots
-}
-
-test_discard_snapshot() {
- local tresor_dir="$1"
- local snap_id=$2
-
- echo "Discard snapshot with id: $snap_id"
- echo $snap_id > $tresor_dir/control/discard_snapshot
+ echo "Wait for deinitialize"
+ local state="$(< $tresor_dir/control/deinitialize)"
}
test_rekey_start() {
local tresor_dir="$1"
echo "Start rekeying"
- echo on > $tresor_dir/control/rekey
+ local state="$(< $tresor_dir/control/rekey)"
+ echo true > $tresor_dir/control/rekey
echo "Reykeying started"
}
@@ -137,16 +129,14 @@ wait_for_rekeying() {
echo "Wait for rekeying to finish..."
while : ; do
local done=0
- local file_content="$(< $tresor_dir/control/rekey_progress)"
+ local file_content="$(< $tresor_dir/control/rekey)"
# XXX remove later
echo "file_content: ${file_content}"
case "$file_content" in
- *at*)
- if [ "$verbose" = "yes" ]; then
- echo "Rekeying: $file_content"
- fi
+ *failed*)
+ done=1;
;;
- *idle*)
+ *succeeded*)
done=1;
;;
esac
@@ -163,16 +153,14 @@ wait_for_vbd_extension() {
echo "Wait for VBD extension to finish..."
while : ; do
local done=0
- local file_content="$(< $tresor_dir/control/extend_progress)"
+ local file_content="$(< $tresor_dir/control/extend)"
# XXX remove later
echo "file_content: ${file_content}"
case "$file_content" in
- *at*)
- if [ "$verbose" = "yes" ]; then
- echo "Extending VBD: $file_content"
- fi
+ *failed*)
+ done=1;
;;
- *idle*)
+ *succeeded*)
done=1;
;;
esac
@@ -189,16 +177,14 @@ wait_for_ft_extension() {
echo "Wait for FT extension to finish..."
while : ; do
local done=0
- local file_content="$(< $tresor_dir/control/extend_progress)"
+ local file_content="$(< $tresor_dir/control/extend)"
# XXX remove later
echo "file_content: ${file_content}"
case "$file_content" in
- *at*)
- if [ "$verbose" = "yes" ]; then
- echo "Extending FT: $file_content"
- fi
+ *failed*)
+ done=1;
;;
- *idle*)
+ *succeeded*)
done=1;
;;
esac
@@ -212,95 +198,37 @@ wait_for_ft_extension() {
main() {
local tresor_dir="/dev/tresor"
local data_file="$tresor_dir/current/data"
-
+ echo "list files..."
ls -l $tresor_dir
-
- for i in $(seq 3); do
-
- echo "--> Run $i:"
-
- test_read_seq_unaligned_512 "$data_file" "1048576"
-
- local pattern_file="/tmp/pattern"
- produce_pattern "$i" "4096" > $pattern_file
-
- test_write_1 "$data_file" "419"
- test_write_1 "$data_file" "63"
- test_write_1 "$data_file" "333"
-
- test_vbd_extension "$tresor_dir" "1000"
- test_read_compare_1 "$data_file" "63"
- test_write_1 "$data_file" "175"
- test_read_compare_1 "$data_file" "419"
- test_write_1 "$data_file" "91"
- test_read_compare_1 "$data_file" "175"
- test_read_compare_1 "$data_file" "91"
- test_read_compare_1 "$data_file" "333"
- wait_for_vbd_extension "$tresor_dir"
-
- test_write_1 "$data_file" "32"
- test_write_1 "$data_file" "77"
- test_write_1 "$data_file" "199"
-
- #test_ft_extension "$tresor_dir" "1000"
- test_read_compare_1 "$data_file" "32"
- test_write_1 "$data_file" "211"
- test_read_compare_1 "$data_file" "77"
- test_write_1 "$data_file" "278"
- test_read_compare_1 "$data_file" "199"
- test_read_compare_1 "$data_file" "278"
- test_read_compare_1 "$data_file" "211"
- #wait_for_ft_extension "$tresor_dir"
-
- test_write_1 "$data_file" "0"
- test_write_1 "$data_file" "8"
- test_write_1 "$data_file" "16"
- test_write_1 "$data_file" "490"
- test_write_1 "$data_file" "468"
-
- test_read_compare_1 "$data_file" "0"
- test_read_compare_1 "$data_file" "8"
- test_read_compare_1 "$data_file" "16"
- test_read_compare_1 "$data_file" "490"
-
- #test_rekey "$tresor_dir"
-
- test_rekey_start "$tresor_dir"
- test_write_1 "$data_file" "0"
- test_rekey_state "$tresor_dir"
- test_read_compare_1 "$data_file" "490"
- test_rekey_state "$tresor_dir"
- test_write_1 "$data_file" "16"
- test_rekey_state "$tresor_dir"
- test_read_compare_1 "$data_file" "468"
- test_rekey_state "$tresor_dir"
- test_read_compare_1 "$data_file" "8"
- test_rekey_state "$tresor_dir"
- test_read_compare_1 "$data_file" "16"
- test_rekey_state "$tresor_dir"
- test_read_compare_1 "$data_file" "0"
- test_write_1 "$data_file" "300"
- test_write_1 "$data_file" "240"
- test_write_1 "$data_file" "201"
- test_write_1 "$data_file" "328"
- wait_for_rekeying "$tresor_dir" "yes"
-
- echo "--> Run $i done"
-
- done
-
- echo "--> Read/Compare test"
- test_read_compare_1 "$data_file" "0"
- test_read_compare_1 "$data_file" "490"
- test_read_compare_1 "$data_file" "468"
- test_read_compare_1 "$data_file" "8"
- test_read_compare_1 "$data_file" "16"
- echo "--> Read/Compare test done"
-
- echo "--- Automated Tresor testing finished, shell is yours ---"
+ echo "produce pattern..."
+ local pattern_file="/tmp/pattern"
+ produce_pattern "1" "4096" > $pattern_file
+ echo "write..."
+ test_write_1 "$data_file" "20"
+ echo "read..."
+ test_read_compare_1 "$data_file" "20"
+ test_write_1 "$data_file" "20"
+ echo "extend VBD..."
+ test_vbd_extension "$tresor_dir" "100"
+ test_write_1 "$data_file" "2"
+ test_read_compare_1 "$data_file" "2"
+ wait_for_vbd_extension "$tresor_dir"
+ echo "extend FT..."
+ test_ft_extension "$tresor_dir" "100"
+ test_write_1 "$data_file" "2"
+ test_read_compare_1 "$data_file" "2"
+ wait_for_ft_extension "$tresor_dir"
+ echo "rekey..."
+ test_rekey_start "$tresor_dir"
+ test_write_1 "$data_file" "2"
+ test_read_compare_1 "$data_file" "2"
+ wait_for_rekeying "$tresor_dir" "no"
+ test_deinitialize "$tresor_dir"
+ wait_for_deinitialize "$tresor_dir"
+ echo "done!"
}
main "$@"
# just drop into shell
-# exit 0
+exit 0
diff --git a/repos/gems/run/vfs_tresor_init.run b/repos/gems/run/vfs_tresor_init.run
deleted file mode 100644
index 3007541865..0000000000
--- a/repos/gems/run/vfs_tresor_init.run
+++ /dev/null
@@ -1,153 +0,0 @@
-assert_spec linux
-
-proc tresor_image_file { } {
- return "vfs_tresor_block.img"
-}
-
-set image_size 32
-
-proc tresor_image_size_mb { } {
- global image_size
- return $image_size
-}
-
-build {
- core lib/ld init timer
- server/lx_block
- server/lx_fs
- server/vfs lib/vfs
- app/sequence
-
- app/tresor_init_trust_anchor
- app/tresor_init
- lib/vfs_tresor_crypto_aes_cbc
- lib/vfs_tresor_trust_anchor
- lib/vfs_jitterentropy
- lib/libc
- lib/libcrypto
-}
-
-create_boot_directory
-
-append config {
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-}
-
-install_config $config
-
-exec rm -rf bin/[tresor_image_file]
-exec truncate -s [tresor_image_size_mb]M bin/[tresor_image_file]
-
-build_boot_image [list {*}[build_artifacts] [tresor_image_file]]
-
-run_genode_until {.*child "initialize_tresor" exited with exit value 0.*\n} 240
-
-exec cp [run_dir]/genode/encrypted_private_key bin
-exec cp [run_dir]/genode/superblock_hash bin
diff --git a/repos/gems/src/app/file_vault/main.cc b/repos/gems/src/app/file_vault/main.cc
index 9df6d65696..cf9b7a7778 100644
--- a/repos/gems/src/app/file_vault/main.cc
+++ b/repos/gems/src/app/file_vault/main.cc
@@ -641,8 +641,28 @@ class File_vault::Main
size_t nr_of_ft_children,
size_t nr_of_ft_leafs);
- static bool tresor_control_file_yields_state_idle(Xml_node const &fs_query_listing,
- char const *file_name);
+ template
+ static bool listing_file_starts_with(Xml_node const &fs_query_listing,
+ char const *file_name,
+ String const &str)
+ {
+ bool result { false };
+ bool done { false };
+ fs_query_listing.with_optional_sub_node("dir", [&] (Xml_node const &node_0) {
+ node_0.for_each_sub_node("file", [&] (Xml_node const &node_1) {
+ if (done) {
+ return;
+ }
+ if (node_1.attribute_value("name", String<16>()) == file_name) {
+ node_1.with_raw_content([&] (char const *base, size_t size) {
+ result = String { Cstring {base, size} } == str;
+ done = true;
+ });
+ }
+ });
+ });
+ return result;
+ }
/***************************************************
@@ -699,28 +719,6 @@ void Main::_handle_ui_config()
}
-bool Main::tresor_control_file_yields_state_idle(Xml_node const &fs_query_listing,
- char const *file_name)
-{
- bool result { false };
- bool done { false };
- fs_query_listing.with_optional_sub_node("dir", [&] (Xml_node const &node_0) {
- node_0.for_each_sub_node("file", [&] (Xml_node const &node_1) {
- if (done) {
- return;
- }
- if (node_1.attribute_value("name", String<16>()) == file_name) {
- node_1.with_raw_content([&] (char const *base, size_t size) {
- result = String<5> { Cstring {base, size} } == "idle";
- done = true;
- });
- }
- });
- });
- return result;
-}
-
-
void Main::_update_sandbox_config()
{
Buffered_xml const config { _heap, "config", [&] (Xml_generator &xml) {
@@ -940,16 +938,20 @@ void Main::_handle_resizing_fs_query_listing(Xml_node const &node)
switch (_resizing_state) {
case Resizing_state::WAIT_TILL_DEVICE_IS_READY:
- if (tresor_control_file_yields_state_idle(node, "extend_progress")) {
+ if (listing_file_starts_with(node, "extend", String<10>("succeeded")) ||
+ listing_file_starts_with(node, "extend", String<5>("none"))) {
_resizing_state = Resizing_state::ISSUE_REQUEST_AT_DEVICE;
Signal_transmitter(_state_handler).submit();
- }
+
+ } else
+ error("failed to extend: tresor not ready");
+
break;
case Resizing_state::IN_PROGRESS_AT_DEVICE:
- if (tresor_control_file_yields_state_idle(node, "extend_progress")) {
+ if (listing_file_starts_with(node, "extend", String<10>("succeeded"))) {
switch (_resizing_type) {
case Resizing_type::EXPAND_CLIENT_FS:
@@ -972,7 +974,10 @@ void Main::_handle_resizing_fs_query_listing(Xml_node const &node)
}
_resizing_state = Resizing_state::DETERMINE_CLIENT_FS_SIZE;
Signal_transmitter(_state_handler).submit();
- }
+
+ } else
+ error("failed to extend: operation failed at tresor");
+
break;
default:
@@ -992,13 +997,16 @@ void Main::_handle_lock_fs_query_listing(Xml_node const &node)
switch (_state) {
case State::LOCK_WAIT_TILL_DEINIT_REQUEST_IS_DONE:
- if (tresor_control_file_yields_state_idle(node, "deinitialize")) {
+ if (listing_file_starts_with(node, "deinitialize", String<10>("succeeded"))) {
_set_state(State::UNLOCK_OBTAIN_PARAMETERS);
_setup_obtain_params_passphrase = Input_passphrase { };
_setup_obtain_params_select = Setup_obtain_params_select::PASSPHRASE_INPUT;
Signal_transmitter(_state_handler).submit();
- }
+
+ } else
+ error("failed to deinitialize: operation failed at tresor");
+
break;
default:
@@ -1024,20 +1032,27 @@ void Main::_handle_rekeying_fs_query_listing(Xml_node const &node)
switch (_rekeying_state) {
case Rekeying_state::WAIT_TILL_DEVICE_IS_READY:
- if (tresor_control_file_yields_state_idle(node, "rekey_progress")) {
+ if (listing_file_starts_with(node, "rekey", String<10>("succeeded")) ||
+ listing_file_starts_with(node, "rekey", String<5>("none"))) {
_rekeying_state = Rekeying_state::ISSUE_REQUEST_AT_DEVICE;
Signal_transmitter(_state_handler).submit();
- }
+
+ } else
+ error("failed to rekey: tresor not ready");
+
break;
case Rekeying_state::IN_PROGRESS_AT_DEVICE:
- if (tresor_control_file_yields_state_idle(node, "rekey_progress")) {
+ if (listing_file_starts_with(node, "rekey", String<10>("succeeded"))) {
_rekeying_state = Rekeying_state::INACTIVE;
Signal_transmitter(_state_handler).submit();
- }
+
+ } else
+ error("failed to rekey: operation failed at tresor");
+
break;
default:
@@ -1465,10 +1480,8 @@ void File_vault::Main::handle_sandbox_state()
update_dialog = true;
update_sandbox = true;
- } else {
-
+ } else
_unlock_retry_delay.schedule(Microseconds { 3000000 });
- }
});
break;
diff --git a/repos/gems/src/app/file_vault/sandbox.h b/repos/gems/src/app/file_vault/sandbox.h
index 0087da5a4d..6f1d788f68 100644
--- a/repos/gems/src/app/file_vault/sandbox.h
+++ b/repos/gems/src/app/file_vault/sandbox.h
@@ -299,7 +299,6 @@ namespace File_vault {
xml.node("tresor", [&] () {
xml.attribute("name", "tresor");
xml.attribute("verbose", "no");
- xml.attribute("debug", "no");
xml.attribute("block", File_path { "/", tresor_img_file_name });
xml.attribute("crypto", "/crypto");
xml.attribute("trust_anchor", "/trust_anchor");
@@ -531,7 +530,7 @@ namespace File_vault {
}
void gen_tresor_vfs_block_start_node(Xml_generator &xml,
- Child_state const &child)
+ Child_state const &child)
{
child.gen_start_node(xml, [&] () {
diff --git a/repos/gems/src/app/tresor_check/main.cc b/repos/gems/src/app/tresor_check/main.cc
index 2e00c3939a..523833162d 100644
--- a/repos/gems/src/app/tresor_check/main.cc
+++ b/repos/gems/src/app/tresor_check/main.cc
@@ -31,76 +31,44 @@ using namespace Tresor;
namespace Tresor_check { class Main; }
-class Tresor_check::Main : private Vfs::Env::User, private Tresor::Module_composition, public Tresor::Module, public Module_channel
+class Tresor_check::Main : private Vfs::Env::User
{
private:
- enum State { INIT, REQ_GENERATED, CHECK_SBS_SUCCEEDED };
+ enum State { INIT, CHECK_SB, CHECK_SB_SUCCEEDED };
Env &_env;
Heap _heap { _env.ram(), _env.rm() };
Attached_rom_dataspace _config_rom { _env, "config" };
Vfs::Simple_env _vfs_env { _env, _heap, _config_rom.xml().sub_node("vfs"), *this };
Signal_handler _sigh { _env.ep(), *this, &Main::_handle_signal };
- Trust_anchor _trust_anchor { _vfs_env, _config_rom.xml().sub_node("trust-anchor") };
- Crypto _crypto { _vfs_env, _config_rom.xml().sub_node("crypto") };
- Block_io _block_io { _vfs_env, _config_rom.xml().sub_node("block-io") };
+ Tresor::Path const _block_io_path { _config_rom.xml().sub_node("block-io").attribute_value("path", Tresor::Path()) };
+ Vfs::Vfs_handle &_block_io_file { open_file(_vfs_env, _block_io_path, Vfs::Directory_service::OPEN_MODE_RDWR) };
+ Block_io _block_io { _block_io_file };
Vbd_check _vbd_check { };
Ft_check _ft_check { };
Sb_check _sb_check { };
- bool _generated_req_success { };
- State _state { INIT };
-
- NONCOPYABLE(Main);
-
- void _generated_req_completed(State_uint state_uint) override
- {
- if (!_generated_req_success) {
- error("command pool: request failed because generated request failed)");
- _env.parent().exit(-1);
- return;
- }
- _state = (State)state_uint;
- }
-
- void wakeup_vfs_user() override { _sigh.local_submit(); }
+ Sb_check::Check _check_superblocks { };
void _wakeup_back_end_services() { _vfs_env.io().commit(); }
void _handle_signal()
{
- execute_modules();
+ while(_sb_check.execute(_check_superblocks, _vbd_check, _ft_check, _block_io));
+ if (_check_superblocks.complete())
+ _env.parent().exit(_check_superblocks.success() ? 0 : -1);
_wakeup_back_end_services();
}
+ /********************
+ ** Vfs::Env::User **
+ ********************/
+
+ void wakeup_vfs_user() override { _sigh.local_submit(); }
+
public:
- Main(Env &env) : Module_channel { COMMAND_POOL, 0 }, _env { env }
- {
- add_module(COMMAND_POOL, *this);
- add_module(CRYPTO, _crypto);
- add_module(TRUST_ANCHOR, _trust_anchor);
- add_module(BLOCK_IO, _block_io);
- add_module(VBD_CHECK, _vbd_check);
- add_module(FT_CHECK, _ft_check);
- add_module(SB_CHECK, _sb_check);
- add_channel(*this);
- _handle_signal();
- }
-
- void execute(bool &progress) override
- {
- switch(_state) {
- case INIT:
-
- generate_req(CHECK_SBS_SUCCEEDED, progress, _generated_req_success);
- _state = REQ_GENERATED;
- break;
-
- case CHECK_SBS_SUCCEEDED: _env.parent().exit(0); break;
- default: break;
- }
- }
+ Main(Env &env) : _env(env) { _handle_signal(); }
};
void Component::construct(Genode::Env &env) { static Tresor_check::Main main { env }; }
diff --git a/repos/gems/src/app/tresor_init/main.cc b/repos/gems/src/app/tresor_init/main.cc
index 2d818e8e04..008db35459 100644
--- a/repos/gems/src/app/tresor_init/main.cc
+++ b/repos/gems/src/app/tresor_init/main.cc
@@ -34,86 +34,116 @@ using namespace Tresor;
namespace Tresor_init { class Main; }
-class Tresor_init::Main : private Vfs::Env::User, private Tresor::Module_composition, public Tresor::Module, public Module_channel
+class Tresor_init::Main : private Vfs::Env::User, private Crypto_key_files_interface
{
private:
- enum State { INIT, REQ_GENERATED, INIT_SBS_SUCCEEDED };
+ struct Crypto_key
+ {
+ Key_id const key_id;
+ Vfs::Vfs_handle &encrypt_file;
+ Vfs::Vfs_handle &decrypt_file;
+ };
Env &_env;
Heap _heap { _env.ram(), _env.rm() };
Attached_rom_dataspace _config_rom { _env, "config" };
Vfs::Simple_env _vfs_env { _env, _heap, _config_rom.xml().sub_node("vfs"), *this };
Signal_handler _sigh { _env.ep(), *this, &Main::_handle_signal };
- Constructible _cfg { };
- Trust_anchor _trust_anchor { _vfs_env, _config_rom.xml().sub_node("trust-anchor") };
- Crypto _crypto { _vfs_env, _config_rom.xml().sub_node("crypto") };
- Block_io _block_io { _vfs_env, _config_rom.xml().sub_node("block-io") };
+ Configuration _cfg { _config_rom.xml() };
+ Tresor::Path const _crypto_path { _config_rom.xml().sub_node("crypto").attribute_value("path", Tresor::Path()) };
+ Tresor::Path const _block_io_path { _config_rom.xml().sub_node("block-io").attribute_value("path", Tresor::Path()) };
+ Tresor::Path const _trust_anchor_path { _config_rom.xml().sub_node("trust-anchor").attribute_value("path", Tresor::Path()) };
+ Vfs::Vfs_handle &_block_io_file { open_file(_vfs_env, _block_io_path, Vfs::Directory_service::OPEN_MODE_RDWR) };
+ Vfs::Vfs_handle &_crypto_add_key_file { open_file(_vfs_env, { _crypto_path, "/add_key" }, Vfs::Directory_service::OPEN_MODE_WRONLY) };
+ Vfs::Vfs_handle &_crypto_remove_key_file { open_file(_vfs_env, { _crypto_path, "/remove_key" }, Vfs::Directory_service::OPEN_MODE_WRONLY) };
+ Vfs::Vfs_handle &_ta_decrypt_file { open_file(_vfs_env, { _trust_anchor_path, "/decrypt" }, Vfs::Directory_service::OPEN_MODE_RDWR) };
+ Vfs::Vfs_handle &_ta_encrypt_file { open_file(_vfs_env, { _trust_anchor_path, "/encrypt" }, Vfs::Directory_service::OPEN_MODE_RDWR) };
+ Vfs::Vfs_handle &_ta_generate_key_file { open_file(_vfs_env, { _trust_anchor_path, "/generate_key" }, Vfs::Directory_service::OPEN_MODE_RDWR) };
+ Vfs::Vfs_handle &_ta_initialize_file { open_file(_vfs_env, { _trust_anchor_path, "/initialize" }, Vfs::Directory_service::OPEN_MODE_RDWR) };
+ Vfs::Vfs_handle &_ta_hash_file { open_file(_vfs_env, { _trust_anchor_path, "/hash" }, Vfs::Directory_service::OPEN_MODE_RDWR) };
+ Trust_anchor _trust_anchor { { _ta_decrypt_file, _ta_encrypt_file, _ta_generate_key_file, _ta_initialize_file, _ta_hash_file } };
+ Crypto _crypto { {*this, _crypto_add_key_file, _crypto_remove_key_file} };
+ Block_io _block_io { _block_io_file };
+ Constructible _crypto_keys[2] { };
Pba_allocator _pba_alloc { NR_OF_SUPERBLOCK_SLOTS };
Vbd_initializer _vbd_initializer { };
Ft_initializer _ft_initializer { };
Sb_initializer _sb_initializer { };
- bool _generated_req_success { };
- State _state { INIT };
+ Sb_initializer::Initialize _init_superblocks {{
+ Tree_configuration {
+ (Tree_level_index)(_cfg.vbd_nr_of_lvls() - 1),
+ (Tree_degree)_cfg.vbd_nr_of_children(),
+ _cfg.vbd_nr_of_leafs()
+ },
+ Tree_configuration {
+ (Tree_level_index)_cfg.ft_nr_of_lvls() - 1,
+ (Tree_degree)_cfg.ft_nr_of_children(),
+ _cfg.ft_nr_of_leafs()
+ },
+ Tree_configuration {
+ (Tree_level_index)_cfg.ft_nr_of_lvls() - 1,
+ (Tree_degree)_cfg.ft_nr_of_children(),
+ _cfg.ft_nr_of_leafs()
+ },
+ _pba_alloc
+ }};
- NONCOPYABLE(Main);
-
- void _generated_req_completed(State_uint state_uint) override
+ Constructible &_crypto_key(Key_id key_id)
{
- if (!_generated_req_success) {
- error("command pool: request failed because generated request failed)");
- _env.parent().exit(-1);
- return;
- }
- _state = (State)state_uint;
+ for (Constructible &key : _crypto_keys)
+ if (key.constructed() && key->key_id == key_id)
+ return key;
+ ASSERT_NEVER_REACHED;
}
- void wakeup_vfs_user() override { _sigh.local_submit(); }
-
void _wakeup_back_end_services() { _vfs_env.io().commit(); }
void _handle_signal()
{
- execute_modules();
+ while(_sb_initializer.execute(_init_superblocks, _block_io, _trust_anchor, _vbd_initializer, _ft_initializer));
+ if (_init_superblocks.complete())
+ _env.parent().exit(_init_superblocks.success() ? 0 : -1);
_wakeup_back_end_services();
}
+ /********************************
+ ** Crypto_key_files_interface **
+ ********************************/
+
+ void add_crypto_key(Key_id key_id) override
+ {
+ for (Constructible &key : _crypto_keys)
+ if (!key.constructed()) {
+ key.construct(key_id,
+ open_file(_vfs_env, { _crypto_path, "/keys/", key_id, "/encrypt" }, Vfs::Directory_service::OPEN_MODE_RDWR),
+ open_file(_vfs_env, { _crypto_path, "/keys/", key_id, "/decrypt" }, Vfs::Directory_service::OPEN_MODE_RDWR)
+ );
+ return;
+ }
+ ASSERT_NEVER_REACHED;
+ }
+
+ void remove_crypto_key(Key_id key_id) override
+ {
+ Constructible &crypto_key = _crypto_key(key_id);
+ _vfs_env.root_dir().close(&crypto_key->encrypt_file);
+ _vfs_env.root_dir().close(&crypto_key->decrypt_file);
+ crypto_key.destruct();
+ }
+
+ Vfs::Vfs_handle &encrypt_file(Key_id key_id) override { return _crypto_key(key_id)->encrypt_file; }
+ Vfs::Vfs_handle &decrypt_file(Key_id key_id) override { return _crypto_key(key_id)->decrypt_file; }
+
+ /********************
+ ** Vfs::Env::User **
+ ********************/
+
+ void wakeup_vfs_user() override { _sigh.local_submit(); }
+
public:
- Main(Env &env) : Module_channel { COMMAND_POOL, 0 }, _env { env }
- {
- add_module(COMMAND_POOL, *this);
- add_module(CRYPTO, _crypto);
- add_module(TRUST_ANCHOR, _trust_anchor);
- add_module(BLOCK_IO, _block_io);
- add_module(VBD_INITIALIZER, _vbd_initializer);
- add_module(FT_INITIALIZER, _ft_initializer);
- add_module(SB_INITIALIZER, _sb_initializer);
- add_channel(*this);
- _cfg.construct(_config_rom.xml());
- _handle_signal();
- }
-
- void execute(bool &progress) override
- {
- switch(_state) {
- case INIT:
-
- generate_req(
- INIT_SBS_SUCCEEDED, progress, (Tree_level_index)_cfg->vbd_nr_of_lvls() - 1,
- (Tree_degree)_cfg->vbd_nr_of_children(), _cfg->vbd_nr_of_leafs(),
- (Tree_level_index)_cfg->ft_nr_of_lvls() - 1,
- (Tree_degree)_cfg->ft_nr_of_children(), _cfg->ft_nr_of_leafs(),
- (Tree_level_index)_cfg->ft_nr_of_lvls() - 1,
- (Tree_degree)_cfg->ft_nr_of_children(), _cfg->ft_nr_of_leafs(), _pba_alloc,
- _generated_req_success);
- _state = REQ_GENERATED;
- break;
-
- case INIT_SBS_SUCCEEDED: _env.parent().exit(0); break;
- default: break;
- }
- }
+ Main(Env &env) : _env(env) { _handle_signal(); }
};
void Component::construct(Genode::Env &env) { static Tresor_init::Main main { env }; }
diff --git a/repos/gems/src/app/tresor_init_trust_anchor/component.cc b/repos/gems/src/app/tresor_init_trust_anchor/component.cc
index f15f8c0988..45a8704778 100644
--- a/repos/gems/src/app/tresor_init_trust_anchor/component.cc
+++ b/repos/gems/src/app/tresor_init_trust_anchor/component.cc
@@ -89,9 +89,8 @@ class Main : Vfs::Env::User
char const *name,
Vfs::File_system &vfs,
Genode::Allocator &alloc)
- :
- _vfs { vfs },
- _vfs_handle { nullptr }
+ :
+ _vfs(vfs), _vfs_handle(nullptr)
{
using Result = Vfs::Directory_service::Open_result;
@@ -207,9 +206,7 @@ class Main : Vfs::Env::User
public:
- Main(Env &env)
- :
- _env { env }
+ Main(Env &env) : _env(env)
{
Xml_node const &config { _config_rom.xml() };
diff --git a/repos/gems/src/app/tresor_tester/main.cc b/repos/gems/src/app/tresor_tester/main.cc
index e89b01457b..c63cc0d484 100644
--- a/repos/gems/src/app/tresor_tester/main.cc
+++ b/repos/gems/src/app/tresor_tester/main.cc
@@ -24,11 +24,10 @@
/* tresor includes */
#include
#include
-#include
+#include
#include
#include
#include
-#include
#include
#include
#include
@@ -40,192 +39,182 @@
namespace Tresor_tester {
+ enum { VERBOSE = 0 };
+
using namespace Genode;
using namespace Tresor;
using Salt = uint64_t;
+ template class Schedule;
class Log_node;
- class Benchmark_node;
+ class Start_benchmark_node;
class Benchmark;
- class Trust_anchor_node;
- class Request_node;
class Command;
+ class Initialize_trust_anchor_node;
class Snapshot_reference;
class Snapshot_reference_tree;
- class Client_data;
+ class Request_node;
class Main;
-
- template
- T read_attribute(Xml_node const &node, char const *attr)
- {
- T value { };
- ASSERT(node.has_attribute(attr));
- ASSERT(node.attribute(attr).value(value));
- return value;
- }
}
-
-struct Tresor_tester::Log_node
-{
- using String = Genode::String<128>;
-
- String const string;
-
- NONCOPYABLE(Log_node);
-
- Log_node(Xml_node const &node) : string { node.attribute_value("string", String { }) } { }
-};
-
-
-struct Tresor_tester::Benchmark_node
-{
- using Label = String<128>;
-
- enum Operation { START, STOP };
-
- Operation const op;
- bool const label_avail;
- Label const label;
-
- NONCOPYABLE(Benchmark_node);
-
- Operation read_op_attr(Xml_node const &node)
- {
- ASSERT(node.has_attribute("op"));
- if (node.attribute("op").has_value("start")) return START;
- if (node.attribute("op").has_value("stop")) return STOP;
- ASSERT_NEVER_REACHED;
- }
-
- Benchmark_node(Xml_node const &node)
- :
- op { read_op_attr(node) }, label_avail { op == START && node.has_attribute("label") },
- label { label_avail ? node.attribute_value("label", Label { }) : Label { } }
- { }
-
- Benchmark_node(Operation op, bool label_avail, Label label) : op(op), label_avail(label_avail), label(label) { }
-};
-
-
-class Tresor_tester::Benchmark
+template
+class Tresor_tester::Schedule : Noncopyable
{
private:
- enum State { STARTED, STOPPED };
-
- Genode::Env &_env;
- Timer::Connection _timer { _env };
- State _state { STOPPED };
- Microseconds _start_time { 0 };
- Number_of_blocks _num_virt_blks_read { 0 };
- Number_of_blocks _num_virt_blks_written { 0 };
- Benchmark_node const *_start_node_ptr { };
-
- NONCOPYABLE(Benchmark);
+ T *_tail { };
+ List _list { };
public:
- Benchmark(Genode::Env &env) : _env { env } { }
+ using Item = List::Element;
- void execute_cmd(Benchmark_node const &node)
+ void add_tail(T &request)
{
- switch (node.op) {
- case Benchmark_node::START:
+ _list.insert(&request, _tail);
+ _tail = &request;
+ }
- ASSERT(_state == STOPPED);
- _num_virt_blks_read = 0;
- _num_virt_blks_written = 0;
- _state = STARTED;
- _start_node_ptr = &node;
- _start_time = _timer.curr_time().trunc_to_plain_us();
- break;
+ bool empty() const { return !_list.first(); }
- case Benchmark_node::STOP:
+ template
+ void with_head(FN && fn)
+ {
+ if (_list.first())
+ fn(*_list.first());
+ }
- ASSERT(_state == STARTED);
- uint64_t const stop_time_us { _timer.curr_time().trunc_to_plain_us().value };
- log("");
- if (_start_node_ptr->label_avail)
- log("Benchmark result \"", _start_node_ptr->label, "\"");
- else
- log("Benchmark result");
+ void remove_head()
+ {
+ T *head = _list.first();
+ if (!head)
+ return;
- double const passed_time_sec { (double)(stop_time_us - _start_time.value) / (double)(1000 * 1000) };
- log(" Ran ", passed_time_sec, " seconds.");
+ _list.remove(head);
+ if (_tail == head)
+ _tail = _list.first();
+ }
- if (_num_virt_blks_read) {
+ template
+ void try_yield_head(CAN_YIELD_TO_FN && can_yield_to)
+ {
+ T *head = _list.first();
+ if (!head)
+ return;
- size_t const bytes_read { _num_virt_blks_read * Tresor::BLOCK_SIZE };
- double const mibyte_read { (double)bytes_read / (double)(1024 * 1024) };
- double const mibyte_per_sec_read {
- (double)bytes_read / (double)passed_time_sec / (double)(1024 * 1024) };
+ T *next = head->Item::_next;
+ if (!next || !can_yield_to(*next))
+ return;
- log(" Have read ", mibyte_read, " mebibyte in total.");
- log(" Have read ", mibyte_per_sec_read, " mebibyte per second.");
- }
+ remove_head();
+ _list.insert(head, next);
+ }
+};
- if (_num_virt_blks_written) {
+class Tresor_tester::Benchmark : Noncopyable
+{
+ public:
- size_t bytes_written { _num_virt_blks_written * Tresor::BLOCK_SIZE };
- double const mibyte_written { (double)bytes_written / (double)(1024 * 1024) };
- double const mibyte_per_sec_written {
- (double)bytes_written / (double)passed_time_sec / (double)(1024 * 1024) };
+ using Label = String<128>;
- log(" Have written ", mibyte_written, " mebibyte in total.");
- log(" Have written ", mibyte_per_sec_written, " mebibyte per second.");
- }
- log("");
- _state = STOPPED;
- break;
+ private:
+
+ Timer::Connection &_timer;
+ Label const _label;
+ Microseconds const _start_time;
+ Number_of_blocks _num_virt_blks_read { };
+ Number_of_blocks _num_virt_blks_written { };
+
+ /*
+ * Noncopyable
+ */
+ Benchmark(Benchmark const &) = delete;
+ Benchmark &operator = (Benchmark const &) = delete;
+
+ public:
+
+ Benchmark(Timer::Connection &timer, Label const &label)
+ :
+ _timer(timer), _label(label), _start_time(timer.curr_time().trunc_to_plain_us())
+ { }
+
+ ~Benchmark()
+ {
+ uint64_t const stop_time_us { _timer.curr_time().trunc_to_plain_us().value };
+ log("");
+ log("Benchmark result \"", _label, "\"");
+
+ double const passed_time_sec { (double)(stop_time_us - _start_time.value) / (double)(1000 * 1000) };
+ log(" Ran ", passed_time_sec, " seconds.");
+
+ if (_num_virt_blks_read) {
+
+ size_t const bytes_read { _num_virt_blks_read * Tresor::BLOCK_SIZE };
+ double const mibyte_read { (double)bytes_read / (double)(1024 * 1024) };
+ double const mibyte_per_sec_read {
+ (double)bytes_read / (double)passed_time_sec / (double)(1024 * 1024) };
+
+ log(" Have read ", mibyte_read, " mebibyte in total.");
+ log(" Have read ", mibyte_per_sec_read, " mebibyte per second.");
}
+ if (_num_virt_blks_written) {
+
+ size_t bytes_written { _num_virt_blks_written * Tresor::BLOCK_SIZE };
+ double const mibyte_written { (double)bytes_written / (double)(1024 * 1024) };
+ double const mibyte_per_sec_written {
+ (double)bytes_written / (double)passed_time_sec / (double)(1024 * 1024) };
+
+ log(" Have written ", mibyte_written, " mebibyte in total.");
+ log(" Have written ", mibyte_per_sec_written, " mebibyte per second.");
+ }
+ log("");
}
void raise_num_virt_blks_read() { _num_virt_blks_read++; }
void raise_num_virt_blks_written() { _num_virt_blks_written++; }
};
-
-struct Tresor_tester::Trust_anchor_node
+struct Tresor_tester::Start_benchmark_node : Noncopyable
{
- using Operation = Trust_anchor_request::Type;
+ Benchmark::Label const label;
- Operation const op;
+ Start_benchmark_node(Xml_node const &node) : label(node.attribute_value("label", Benchmark::Label())) { }
+};
+
+struct Tresor_tester::Log_node : Noncopyable
+{
+ using String = Genode::String<128>;
+
+ String const string;
+
+ Log_node(Xml_node const &node) : string(node.attribute_value("string", String())) { }
+};
+
+struct Tresor_tester::Initialize_trust_anchor_node : Noncopyable
+{
Passphrase const passphrase;
- NONCOPYABLE(Trust_anchor_node);
-
- Operation read_op_attr(Xml_node const &node)
- {
- ASSERT(node.has_attribute("op"));
- if (node.attribute("op").has_value("initialize"))
- return Operation::INITIALIZE;
- ASSERT_NEVER_REACHED;
- }
-
- Trust_anchor_node(Xml_node const &node)
+ Initialize_trust_anchor_node(Xml_node const &node)
:
- op { read_op_attr(node) },
- passphrase { op == Operation::INITIALIZE ? node.attribute_value("passphrase", Passphrase()) : Passphrase() }
+ passphrase(node.attribute_value("passphrase", Passphrase()))
{ }
};
-
-struct Tresor_tester::Request_node
+struct Tresor_tester::Request_node : Noncopyable
{
- using Operation = Tresor::Request::Operation;
+ enum Operation {
+ READ, WRITE, SYNC, CREATE_SNAPSHOT, DISCARD_SNAPSHOT, REKEY, EXTEND_VBD,
+ EXTEND_FREE_TREE, DEINITIALIZE, INITIALIZE };
Operation const op;
Virtual_block_address const vba;
- Number_of_blocks const count;
+ Number_of_blocks const num_blocks;
bool const sync;
bool const salt_avail;
Salt const salt;
Snapshot_id const snap_id;
- NONCOPYABLE(Request_node);
-
Operation read_op_attr(Xml_node const &node)
{
ASSERT(node.has_attribute("op"));
@@ -234,7 +223,7 @@ struct Tresor_tester::Request_node
if (node.attribute("op").has_value("sync")) return Operation::SYNC;
if (node.attribute("op").has_value("create_snapshot")) return Operation::CREATE_SNAPSHOT;
if (node.attribute("op").has_value("discard_snapshot")) return Operation::DISCARD_SNAPSHOT;
- if (node.attribute("op").has_value("extend_ft")) return Operation::EXTEND_FT;
+ if (node.attribute("op").has_value("extend_ft")) return Operation::EXTEND_FREE_TREE;
if (node.attribute("op").has_value("extend_vbd")) return Operation::EXTEND_VBD;
if (node.attribute("op").has_value("rekey")) return Operation::REKEY;
if (node.attribute("op").has_value("deinitialize")) return Operation::DEINITIALIZE;
@@ -243,156 +232,143 @@ struct Tresor_tester::Request_node
Request_node(Xml_node const &node)
:
- op { read_op_attr(node) },
- vba { has_vba() ? read_attribute(node, "vba") : 0 },
- count { has_count() ? read_attribute(node, "count") : 0 },
- sync { read_attribute(node, "sync") },
- salt_avail { has_salt() ? node.has_attribute("salt") : false },
- salt { has_salt() && salt_avail ? read_attribute(node, "salt") : 0 },
- snap_id { has_snap_id() ? read_attribute(node, "id") : 0 }
+ op(read_op_attr(node)),
+ vba(node.attribute_value("vba", (Virtual_block_address)0)),
+ num_blocks(node.attribute_value("num_blocks", (Number_of_blocks)0)),
+ sync(node.attribute_value("sync", false)),
+ salt_avail(node.has_attribute("salt")),
+ salt(node.attribute_value("salt", (Salt)0)),
+ snap_id(node.attribute_value("id", (Snapshot_id)0))
{ }
+};
- bool has_vba() const { return op == Operation::READ || op == Operation::WRITE || op == Operation::SYNC; }
+struct Tresor_tester::Command : Avl_node, Schedule::Item
+{
+ friend class Schedule;
- bool has_salt() const { return op == Operation::READ || op == Operation::WRITE; }
+ using Node_type = String<64>;
+ using Id = uint64_t;
- bool has_count() const
+ enum Type {
+ REQUEST, INIT_TRUST_ANCHOR, START_BENCHMARK, FINISH_BENCHMARK, CONSTRUCT, DESTRUCT, INITIALIZE, CHECK,
+ CHECK_SNAPSHOTS, LOG };
+
+ enum State { INIT, IN_PROGRESS, COMPLETE };
+
+ /*
+ * Noncopyable
+ */
+ Command(Command const &) = delete;
+ Command &operator = (Command const &) = delete;
+
+ Type const type;
+ Id const id;
+ State state { INIT };
+ Constructible request_node { };
+ Constructible init_trust_anchor_node { };
+ Constructible start_benchmark_node { };
+ Constructible log_node { };
+ Constructible initialize_config { };
+ Trust_anchor::Initialize *init_trust_anchor_ptr { };
+ Sb_initializer::Initialize *init_superblocks_ptr { };
+ Sb_check::Check *check_superblocks_ptr { };
+ Superblock_control::Initialize *init_sb_control_ptr { };
+ Superblock_control::Deinitialize *deinit_sb_control_ptr { };
+ Superblock_control::Create_snapshot *create_snap_ptr { };
+ Superblock_control::Discard_snapshot *discard_snap_ptr { };
+ Superblock_control::Write_vbas *write_vbas_ptr { };
+ Superblock_control::Read_vbas *read_vbas_ptr { };
+ Superblock_control::Rekey *rekey_ptr { };
+ Superblock_control::Extend_vbd *extend_vbd_ptr { };
+ Superblock_control::Extend_free_tree *extend_free_tree_ptr { };
+ Superblock_control::Synchronize *sync_ptr { };
+ Superblock::State sb_state { Superblock::INVALID };
+ Generation generation { };
+ bool rekey_finished { };
+ bool extend_vbd_finished { };
+ bool extend_free_tree_finished { };
+ bool restarted { };
+
+ char const *op_to_string() const
{
- return op == Operation::READ || op == Operation::WRITE || op == Operation::SYNC ||
- op == Operation::EXTEND_FT || op == Operation::EXTEND_VBD;
+ switch (type) {
+ case INITIALIZE: return "initialize tresor container";
+ case REQUEST:
+ switch(request_node->op) {
+ case Request_node::INITIALIZE: return "initialize superblock control";
+ case Request_node::DEINITIALIZE: return "deinitialize superblock control";
+ case Request_node::CREATE_SNAPSHOT: return "create snapshot";
+ case Request_node::DISCARD_SNAPSHOT: return "discard snapshot";
+ case Request_node::READ: return "read";
+ case Request_node::WRITE: return "write";
+ case Request_node::SYNC: return "sync";
+ case Request_node::REKEY: return "rekey";
+ case Request_node::EXTEND_VBD: return "extend virtual block device";
+ case Request_node::EXTEND_FREE_TREE: return "extend free tree";
+ }
+ ASSERT_NEVER_REACHED;
+ case INIT_TRUST_ANCHOR: return "initialize trust anchor";
+ case START_BENCHMARK: return "start benchmark";
+ case FINISH_BENCHMARK: return "finish benchmark";
+ case CONSTRUCT: return "construct";
+ case DESTRUCT: return "destruct";
+ case CHECK: return "check";
+ case CHECK_SNAPSHOTS: return "check_snapshots";
+ case LOG: return "log";
+ }
+ ASSERT_NEVER_REACHED;
}
- bool has_snap_id() const { return op == Operation::DISCARD_SNAPSHOT || op == Operation::CREATE_SNAPSHOT; }
+ static Type type_from_node(Xml_node const &node)
+ {
+ Xml_node::Type const nt = node.type();
+ if (nt == "initialize") { return INITIALIZE; }
+ if (nt == "request") { return REQUEST; }
+ if (nt == "initialize-trust-anchor") { return INIT_TRUST_ANCHOR; }
+ if (nt == "start-benchmark") { return START_BENCHMARK; }
+ if (nt == "finish-benchmark") { return FINISH_BENCHMARK; }
+ if (nt == "construct") { return CONSTRUCT; }
+ if (nt == "destruct") { return DESTRUCT; }
+ if (nt == "check") { return CHECK; }
+ if (nt == "check-snapshots") { return CHECK_SNAPSHOTS; }
+ if (nt == "log") { return LOG; }
+ ASSERT_NEVER_REACHED;
+ }
- void print(Genode::Output &out) const { Genode::print(out, "op ", Tresor::Request::op_to_string(op)); }
+ bool higher(Command *other_ptr) { return other_ptr->id > id; }
+
+ Command(Xml_node const &node, Id id) : type(type_from_node(node)), id(id)
+ {
+ switch (type) {
+ case INITIALIZE: initialize_config.construct(node); break;
+ case REQUEST: request_node.construct(node); break;
+ case INIT_TRUST_ANCHOR: init_trust_anchor_node.construct(node); break;
+ case START_BENCHMARK: start_benchmark_node.construct(node); break;
+ case LOG: log_node.construct(node); break;
+ default: break;
+ }
+ }
+
+ template
+ void with_command(Command::Id id, FUNC && func)
+ {
+ if (id != this->id) {
+ Command *cmd_ptr { Avl_node::child(id > this->id) };
+ ASSERT(cmd_ptr);
+ cmd_ptr->with_command(id, func);
+ } else
+ func(*this);
+ }
+
+ void print(Genode::Output &out) const { Genode::print(out, "id ", id, " op \"", op_to_string(), "\""); }
};
-
-class Tresor_tester::Command : public Module_channel
-{
- public:
-
- enum Type { INVALID, REQUEST, TRUST_ANCHOR, BENCHMARK, CONSTRUCT, DESTRUCT, INITIALIZE, CHECK, CHECK_SNAPSHOTS, LOG };
-
- enum State { PENDING, IN_PROGRESS, CREATE_SNAP_COMPLETED, DISCARD_SNAP_COMPLETED, COMPLETED };
-
- private:
-
- using Type_string = String<64>;
-
- Tresor_tester::Main &_main;
- Type _type { INVALID };
- Module_channel_id _id { 0 };
- State _state { PENDING };
- bool _success { false };
- Generation _gen { INVALID_GENERATION };
- bool _data_mismatch { false };
- Constructible _request_node { };
- Constructible _trust_anchor_node { };
- Constructible _benchmark_node { };
- Constructible _log_node { };
- Constructible _initialize { };
-
- NONCOPYABLE(Command);
-
- void _generated_req_completed(State_uint state_uint) override;
-
- static char const *_type_to_string(Type type)
- {
- switch (type) {
- case INITIALIZE: return "initialize";
- case INVALID: return "invalid";
- case REQUEST: return "request";
- case TRUST_ANCHOR: return "trust_anchor";
- case BENCHMARK: return "benchmark";
- case CONSTRUCT: return "construct";
- case DESTRUCT: return "destruct";
- case CHECK: return "check";
- case CHECK_SNAPSHOTS: return "check_snapshots";
- case LOG: return "log";
- }
- ASSERT_NEVER_REACHED;
- }
-
- static Type _type_from_string(Type_string str)
- {
- if (str == "initialize") { return INITIALIZE; }
- if (str == "request") { return REQUEST; }
- if (str == "trust-anchor") { return TRUST_ANCHOR; }
- if (str == "benchmark") { return BENCHMARK; }
- if (str == "construct") { return CONSTRUCT; }
- if (str == "destruct") { return DESTRUCT; }
- if (str == "check") { return CHECK; }
- if (str == "check-snapshots") { return CHECK_SNAPSHOTS; }
- if (str == "log") { return LOG; }
- ASSERT_NEVER_REACHED;
- }
-
- public:
-
- Command(Xml_node const &node, Tresor_tester::Main &main, Module_channel_id id)
- :
- Module_channel { COMMAND_POOL, id }, _main { main }, _type { _type_from_string(node.type()) }, _id { id }
- {
- switch (_type) {
- case INITIALIZE: _initialize.construct(node); break;
- case REQUEST: _request_node.construct(node); break;
- case TRUST_ANCHOR: _trust_anchor_node.construct(node); break;
- case BENCHMARK: _benchmark_node.construct(node); break;
- case LOG: _log_node.construct(node); break;
- default: break;
- }
- }
-
- bool may_have_data_mismatch() const
- {
- return _type == REQUEST && _request_node->op == Tresor::Request::READ && _request_node->salt_avail;
- }
-
- bool synchronize() const
- {
- switch (_type) {
- case REQUEST: return _request_node->sync;
- case INVALID: ASSERT_NEVER_REACHED;
- default: return true;
- }
- ASSERT_NEVER_REACHED;
- }
-
- void print(Genode::Output &out) const
- {
- Genode::print(out, "id ", _id, " type ", _type_to_string(_type));
- if (_type == REQUEST)
- Genode::print(out, " ", *_request_node);
- }
-
- Type type() const { return _type ; }
- State state() const { return _state ; }
- Module_channel_id id() const { return _id ; }
- bool success() const { return _success ; }
- bool data_mismatch() const { return _data_mismatch ; }
- Request_node const &request_node() const { return *_request_node ; }
- Trust_anchor_node const &trust_anchor_node() const { return *_trust_anchor_node; }
- Benchmark_node const &benchmark_node() const { return *_benchmark_node ; }
- Log_node const &log_node() const { return *_log_node ; }
- Tresor_init::Configuration const &initialize() const { return *_initialize ; }
-
- void state (State state) { _state = state; }
- void success (bool success) { _success = success; }
- void data_mismatch (bool data_mismatch) { _data_mismatch = data_mismatch; }
-
- void execute(bool &progress);
-};
-
-
-struct Tresor_tester::Snapshot_reference : public Genode::Avl_node
+struct Tresor_tester::Snapshot_reference : Avl_node
{
Snapshot_id const id;
Generation const gen;
- NONCOPYABLE(Snapshot_reference);
-
- Snapshot_reference(Snapshot_id id, Generation gen) : id { id }, gen { gen } { }
+ Snapshot_reference(Snapshot_id id, Generation gen) : id(id), gen(gen) { }
template
void with_ref(Snapshot_id target_id, FUNC && func) const
@@ -412,7 +388,6 @@ struct Tresor_tester::Snapshot_reference : public Genode::Avl_nodeid > id; }
};
-
struct Tresor_tester::Snapshot_reference_tree : public Avl_tree
{
template
@@ -425,61 +400,54 @@ struct Tresor_tester::Snapshot_reference_tree : public Avl_tree _signal_handler { _env.ep(), *this, &Main::_handle_signal };
- Benchmark _benchmark { _env };
- Module_channel_id _next_command_id { 0 };
- unsigned long _num_uncompleted_cmds { 0 };
+ Tresor::Path const _crypto_path { _config_rom.xml().sub_node("crypto").attribute_value("path", Tresor::Path()) };
+ Tresor::Path const _block_io_path { _config_rom.xml().sub_node("block-io").attribute_value("path", Tresor::Path()) };
+ Tresor::Path const _trust_anchor_path { _config_rom.xml().sub_node("trust-anchor").attribute_value("path", Tresor::Path()) };
+ Vfs::Vfs_handle &_block_io_file { open_file(_vfs_env, _block_io_path, Vfs::Directory_service::OPEN_MODE_RDWR) };
+ Vfs::Vfs_handle &_crypto_add_key_file { open_file(_vfs_env, { _crypto_path, "/add_key" }, Vfs::Directory_service::OPEN_MODE_WRONLY) };
+ Vfs::Vfs_handle &_crypto_remove_key_file { open_file(_vfs_env, { _crypto_path, "/remove_key" }, Vfs::Directory_service::OPEN_MODE_WRONLY) };
+ Vfs::Vfs_handle &_ta_decrypt_file { open_file(_vfs_env, { _trust_anchor_path, "/decrypt" }, Vfs::Directory_service::OPEN_MODE_RDWR) };
+ Vfs::Vfs_handle &_ta_encrypt_file { open_file(_vfs_env, { _trust_anchor_path, "/encrypt" }, Vfs::Directory_service::OPEN_MODE_RDWR) };
+ Vfs::Vfs_handle &_ta_generate_key_file { open_file(_vfs_env, { _trust_anchor_path, "/generate_key" }, Vfs::Directory_service::OPEN_MODE_RDWR) };
+ Vfs::Vfs_handle &_ta_initialize_file { open_file(_vfs_env, { _trust_anchor_path, "/initialize" }, Vfs::Directory_service::OPEN_MODE_RDWR) };
+ Vfs::Vfs_handle &_ta_hash_file { open_file(_vfs_env, { _trust_anchor_path, "/hash" }, Vfs::Directory_service::OPEN_MODE_RDWR) };
+ Timer::Connection _timer { _env };
+ Constructible _benchmark { };
+ Avl_tree _command_tree { };
+ Schedule _command_schedule { };
unsigned long _num_errors { 0 };
- Tresor::Block _blk_data { };
Snapshot_reference_tree _snap_refs { };
Constructible _free_tree { };
Constructible _vbd { };
Constructible _sb_control { };
- Constructible _request_pool { };
- Constructible _client_data { };
Constructible _meta_tree { };
- Trust_anchor _trust_anchor { _vfs_env, _config_rom.xml().sub_node("trust-anchor") };
- Crypto _crypto { _vfs_env, _config_rom.xml().sub_node("crypto") };
- Block_io _block_io { _vfs_env, _config_rom.xml().sub_node("block-io") };
+ Trust_anchor _trust_anchor { { _ta_decrypt_file, _ta_encrypt_file, _ta_generate_key_file, _ta_initialize_file, _ta_hash_file } };
+ Crypto _crypto { {*this, _crypto_add_key_file, _crypto_remove_key_file} };
+ Block_io _block_io { _block_io_file };
Pba_allocator _pba_alloc { NR_OF_SUPERBLOCK_SLOTS };
Vbd_initializer _vbd_initializer { };
Ft_initializer _ft_initializer { };
Sb_initializer _sb_initializer { };
- Sb_check _sb_check { };
Vbd_check _vbd_check { };
Ft_check _ft_check { };
- bool _generated_req_success { false };
-
- NONCOPYABLE(Main);
+ Sb_check _sb_check { };
+ Constructible _crypto_keys[2] { };
static void _generate_blk_data(Tresor::Block &blk_data, Virtual_block_address vba, Salt salt)
{
@@ -494,66 +462,16 @@ class Tresor_tester::Main : private Vfs::Env::User, private Module_composition,
}
}
- template
- void _with_first_processable_cmd(FUNC && func)
+ Constructible &_crypto_key(Key_id key_id)
{
- bool first_uncompleted_cmd { true };
- bool done { false };
- for_each_channel([&] (Command &cmd)
- {
- if (done)
- return;
-
- if (cmd.state() == Command::PENDING) {
- done = true;
- if (first_uncompleted_cmd || !cmd.synchronize())
- func(cmd);
- }
- if (cmd.state() == Command::IN_PROGRESS) {
- if (cmd.synchronize())
- done = true;
- else
- first_uncompleted_cmd = false;
- }
- });
- }
-
- void _try_end_program()
- {
- if (_num_uncompleted_cmds == 0) {
- if (_num_errors > 0) {
- for_each_channel([&] (Command &cmd) {
- if (cmd.state() != Command::COMPLETED)
- return;
-
- if (cmd.success() && (!cmd.may_have_data_mismatch() || !cmd.data_mismatch()))
- return;
-
- log("cmd failed: ", cmd);
- });
- _env.parent().exit(-1);
- } else
- _env.parent().exit(0);
- }
+ for (Constructible &key : _crypto_keys)
+ if (key.constructed() && key->key_id == key_id)
+ return key;
+ ASSERT_NEVER_REACHED;
}
void _wakeup_back_end_services() { _vfs_env.io().commit(); }
- void _handle_signal()
- {
- execute_modules();
- _try_end_program();
- _wakeup_back_end_services();
- }
-
- void wakeup_vfs_user() override { _signal_handler.local_submit(); }
-
- void execute(bool &progress) override
- {
- _with_first_processable_cmd([&] (Command &cmd) {
- cmd.execute(progress); });
- }
-
void _remove_snap_ref(Snapshot_reference &ref)
{
_snap_refs.remove(&ref);
@@ -561,50 +479,471 @@ class Tresor_tester::Main : private Vfs::Env::User, private Module_composition,
destroy(_heap, &ref);
}
- public:
-
- Main(Genode::Env &env) : _env { env }
+ void _reset_snap_refs()
{
- add_module(CRYPTO, _crypto);
- add_module(TRUST_ANCHOR, _trust_anchor);
- add_module(COMMAND_POOL, *this);
- add_module(BLOCK_IO, _block_io);
- add_module(VBD_INITIALIZER, _vbd_initializer);
- add_module(FT_INITIALIZER, _ft_initializer);
- add_module(SB_INITIALIZER, _sb_initializer);
- add_module(SB_CHECK, _sb_check);
- add_module(VBD_CHECK, _vbd_check);
- add_module(FT_CHECK, _ft_check);
- _config_rom.xml().sub_node("commands").for_each_sub_node([&] (Xml_node const &node) {
- add_channel(*new (_heap) Command(node, *this, _next_command_id++));
- _num_uncompleted_cmds++;
- });
- _handle_signal();
+ while (_snap_refs.first())
+ _remove_snap_ref(*_snap_refs.first());
}
- void mark_command_in_progress(Module_channel_id cmd_id)
+ void _remove_snap_refs_with_same_gen(Snapshot_id id)
{
- with_channel(cmd_id, [&] (Command &cmd) {
- ASSERT(cmd.state() == Command::PENDING);
- cmd.state(Command::IN_PROGRESS);
- });
+ Generation gen { _snap_id_to_gen(id) };
+ while (1) {
+ Snapshot_reference *ref_ptr { nullptr };
+ _snap_refs.for_each([&] (Snapshot_reference const &ref) {
+ if (!ref_ptr && ref.gen == gen)
+ ref_ptr = const_cast(&ref);
+ });
+ if (ref_ptr) {
+ _remove_snap_ref(*ref_ptr);
+ } else
+ break;
+ }
}
- void mark_command_completed(Module_channel_id cmd_id, bool success)
+ void _mark_command_complete(Command &cmd, bool success)
{
- with_channel(cmd_id, [&] (Command &cmd) {
- ASSERT(cmd.state() == Command::IN_PROGRESS);
- cmd.state(Command::COMPLETED);
- _num_uncompleted_cmds--;
- cmd.success(success);
- if (!cmd.success()) {
- warning("cmd ", cmd, " failed");
- _num_errors++;
+ cmd.state = Command::COMPLETE;
+ if (VERBOSE)
+ log("finished command: ", cmd);
+ if (!success) {
+ _num_errors++;
+ error("command failed: ", cmd);
+ }
+ }
+
+ void _mark_command_in_progress(Command &cmd, bool &progress)
+ {
+ cmd.state = Command::IN_PROGRESS;
+ progress = true;
+ if (VERBOSE && !cmd.restarted) {
+ log("started command: ", cmd);
+ cmd.restarted = true;
+ }
+ }
+
+ template
+ void _try_complete_command(Command &cmd, REQUEST &req, bool &progress)
+ {
+ if (!req.complete())
+ return;
+
+ _mark_command_complete(cmd, req.success());
+ destroy(_heap, &req);
+ progress = true;
+ return;
+ }
+
+ template
+ void _try_complete_multi_request_command(Command &cmd, REQUEST &req, bool cmd_finished, bool &progress)
+ {
+ if (!req.complete())
+ return;
+
+ if (!req.success()) {
+ _mark_command_complete(cmd, false);
+ destroy(_heap, &req);
+ progress = true;
+ return;
+ }
+ destroy(_heap, &req);
+ if (cmd_finished) {
+ _mark_command_complete(cmd, true);
+ return;
+ }
+ cmd.state = Command::INIT;
+ progress = true;
+ return;
+ }
+
+ bool _execute_command(Command &cmd)
+ {
+ bool progress = false;
+ switch (cmd.type) {
+ case Command::INIT_TRUST_ANCHOR:
+
+ switch(cmd.state) {
+ case Command::INIT:
+ {
+ Initialize_trust_anchor_node &node { *cmd.init_trust_anchor_node };
+ cmd.init_trust_anchor_ptr = new (_heap) Trust_anchor::Initialize({node.passphrase});
+ _mark_command_in_progress(cmd, progress);
+ break;
}
- });
+ case Command::IN_PROGRESS:
+ {
+ Trust_anchor::Initialize &req = *cmd.init_trust_anchor_ptr;
+ progress |= _trust_anchor.execute(req);
+ _try_complete_command(cmd, req, progress);
+ break;
+ }
+ default: break;
+ }
+ break;
+
+ case Command::INITIALIZE:
+
+ switch(cmd.state) {
+ case Command::INIT:
+ {
+ _reset_snap_refs();
+ Tresor_init::Configuration const &cfg { *cmd.initialize_config };
+ cmd.init_superblocks_ptr = new (_heap) Sb_initializer::Initialize({
+ Tree_configuration {
+ (Tree_level_index)(cfg.vbd_nr_of_lvls() - 1),
+ (Tree_degree)cfg.vbd_nr_of_children(),
+ cfg.vbd_nr_of_leafs()
+ },
+ Tree_configuration {
+ (Tree_level_index)cfg.ft_nr_of_lvls() - 1,
+ (Tree_degree)cfg.ft_nr_of_children(),
+ cfg.ft_nr_of_leafs()
+ },
+ Tree_configuration {
+ (Tree_level_index)cfg.ft_nr_of_lvls() - 1,
+ (Tree_degree)cfg.ft_nr_of_children(),
+ cfg.ft_nr_of_leafs()
+ },
+ _pba_alloc
+ });
+ _mark_command_in_progress(cmd, progress);
+ break;
+ }
+ case Command::IN_PROGRESS:
+ {
+ Sb_initializer::Initialize &req = *cmd.init_superblocks_ptr;
+ progress |= _sb_initializer.execute(req, _block_io, _trust_anchor, _vbd_initializer, _ft_initializer);
+ _try_complete_command(cmd, req, progress);
+ break;
+ }
+ default: break;
+ }
+ break;
+
+ case Command::CONSTRUCT:
+
+ switch(cmd.state) {
+ case Command::INIT:
+
+ _meta_tree.construct();
+ _free_tree.construct();
+ _vbd.construct();
+ _sb_control.construct();
+ cmd.init_sb_control_ptr = new (_heap) Superblock_control::Initialize({cmd.sb_state});
+ _mark_command_in_progress(cmd, progress);
+ break;
+
+ case Command::IN_PROGRESS:
+ {
+ Superblock_control::Initialize &req = *cmd.init_sb_control_ptr;
+ progress |= _sb_control->execute(req, _block_io, _crypto, _trust_anchor);
+ _try_complete_command(cmd, req, progress);
+ break;
+ }
+ default: break;
+ }
+ break;
+
+ case Command::DESTRUCT:
+
+ switch(cmd.state) {
+ case Command::INIT:
+
+ _meta_tree.destruct();
+ _free_tree.destruct();
+ _vbd.destruct();
+ _sb_control.destruct();
+ _mark_command_complete(cmd, true);
+ progress = true;
+ break;
+
+ default: break;
+ }
+ break;
+
+ case Command::START_BENCHMARK:
+
+ switch(cmd.state) {
+ case Command::INIT:
+
+ _benchmark.construct(_timer, cmd.start_benchmark_node->label);
+ _mark_command_complete(cmd, true);
+ progress = true;
+ break;
+
+ default: break;
+ }
+ break;
+
+ case Command::FINISH_BENCHMARK:
+
+ switch(cmd.state) {
+ case Command::INIT:
+
+ _benchmark.destruct();
+ _mark_command_complete(cmd, true);
+ progress = true;
+ break;
+
+ default: break;
+ }
+ break;
+
+ case Command::CHECK_SNAPSHOTS:
+
+ switch(cmd.state) {
+ case Command::INIT:
+ {
+ bool success { true };
+ Snapshots_info snap_info { _sb_control->snapshots_info() };
+ bool snap_gen_ok[MAX_NR_OF_SNAPSHOTS] { false };
+ _snap_refs.for_each([&] (Snapshot_reference const &snap_ref) {
+ bool snap_ref_ok { false };
+ for (Snapshot_index idx { 0 }; idx < MAX_NR_OF_SNAPSHOTS; idx++) {
+ if (snap_info.generations[idx] == snap_ref.gen) {
+ snap_ref_ok = true;
+ snap_gen_ok[idx] = true;
+ }
+ }
+ if (!snap_ref_ok) {
+ warning("snap (", snap_ref, ") not known to tresor");
+ success = false;
+ }
+ });
+ for (Snapshot_index idx { 0 }; idx < MAX_NR_OF_SNAPSHOTS; idx++) {
+ if (snap_info.generations[idx] != INVALID_GENERATION && !snap_gen_ok[idx]) {
+ warning("snap (idx ", idx, " gen ", snap_info.generations[idx], ") not known to tester");
+ success = false;
+ }
+ }
+ _mark_command_complete(cmd, success);
+ progress = true;
+ break;
+ }
+ default: break;
+ }
+ break;
+
+ case Command::REQUEST:
+
+ switch(cmd.state) {
+ case Command::INIT:
+ {
+ Request_node const &node { *cmd.request_node };
+ switch (node.op) {
+ case Request_node::WRITE:
+ cmd.write_vbas_ptr = new (_heap) Superblock_control::Write_vbas({node.vba, node.num_blocks, 0, cmd.id});
+ break;
+ case Request_node::READ:
+ cmd.read_vbas_ptr = new (_heap) Superblock_control::Read_vbas({node.vba, node.num_blocks, 0, cmd.id});
+ break;
+ case Request_node::SYNC:
+ cmd.sync_ptr = new (_heap) Superblock_control::Synchronize({});
+ break;
+ case Request_node::REKEY:
+ cmd.rekey_ptr = new (_heap) Superblock_control::Rekey({cmd.rekey_finished});
+ break;
+ case Request_node::EXTEND_VBD:
+ cmd.extend_vbd_ptr = new (_heap) Superblock_control::Extend_vbd({node.num_blocks, cmd.extend_vbd_finished});
+ break;
+ case Request_node::EXTEND_FREE_TREE:
+ cmd.extend_free_tree_ptr = new (_heap) Superblock_control::Extend_free_tree({node.num_blocks, cmd.extend_free_tree_finished});
+ break;
+ case Request_node::DEINITIALIZE:
+ cmd.deinit_sb_control_ptr = new (_heap) Superblock_control::Deinitialize({});
+ break;
+ case Request_node::CREATE_SNAPSHOT:
+ cmd.create_snap_ptr = new (_heap) Superblock_control::Create_snapshot({cmd.generation});
+ break;
+ case Request_node::DISCARD_SNAPSHOT:
+ cmd.discard_snap_ptr = new (_heap) Superblock_control::Discard_snapshot({_snap_id_to_gen(node.snap_id)});
+ break;
+ default: ASSERT_NEVER_REACHED;
+ }
+ _mark_command_in_progress(cmd, progress);
+ break;
+ }
+ case Command::IN_PROGRESS:
+ {
+ Request_node &node = *cmd.request_node;
+ switch (node.op) {
+ case Request_node::WRITE:
+ {
+ Superblock_control::Write_vbas &req = *cmd.write_vbas_ptr;
+ progress |= _sb_control->execute(req, *_vbd, *this, _block_io, *_free_tree, *_meta_tree, _crypto);
+ _try_complete_command(cmd, req, progress);
+ break;
+ }
+ case Request_node::READ:
+ {
+ Superblock_control::Read_vbas &req = *cmd.read_vbas_ptr;
+ progress |= _sb_control->execute(req, *_vbd, *this, _block_io, _crypto);
+ _try_complete_command(cmd, req, progress);
+ break;
+ }
+ case Request_node::SYNC:
+ {
+ Superblock_control::Synchronize &req = *cmd.sync_ptr;
+ progress |= _sb_control->execute(req, _block_io, _trust_anchor);
+ _try_complete_command(cmd, req, progress);
+ break;
+ }
+ case Request_node::REKEY:
+ {
+ Superblock_control::Rekey &req = *cmd.rekey_ptr;
+ progress |= _sb_control->execute(req, *_vbd, *_free_tree, *_meta_tree, _block_io, _crypto, _trust_anchor);
+ _try_complete_multi_request_command(cmd, req, cmd.rekey_finished, progress);
+ break;
+ }
+ case Request_node::EXTEND_VBD:
+ {
+ Superblock_control::Extend_vbd &req = *cmd.extend_vbd_ptr;
+ progress |= _sb_control->execute(req, *_vbd, *_free_tree, *_meta_tree, _block_io, _trust_anchor);
+ _try_complete_multi_request_command(cmd, req, cmd.extend_vbd_finished, progress);
+ break;
+ }
+ case Request_node::EXTEND_FREE_TREE:
+ {
+ Superblock_control::Extend_free_tree &req = *cmd.extend_free_tree_ptr;
+ progress |= _sb_control->execute(req, *_free_tree, *_meta_tree, _block_io, _trust_anchor);
+ _try_complete_multi_request_command(cmd, req, cmd.extend_free_tree_finished, progress);
+ break;
+ }
+ case Request_node::DEINITIALIZE:
+ {
+ Superblock_control::Deinitialize &req = *cmd.deinit_sb_control_ptr;
+ progress |= _sb_control->execute(req, _block_io, _crypto, _trust_anchor);
+ _try_complete_command(cmd, req, progress);
+ break;
+ }
+ case Request_node::CREATE_SNAPSHOT:
+ {
+ Superblock_control::Create_snapshot &req = *cmd.create_snap_ptr;
+ progress |= _sb_control->execute(req, _block_io, _trust_anchor);
+ if (req.complete() && req.success())
+ _snap_refs.insert(new (_heap) Snapshot_reference { cmd.request_node->snap_id, cmd.generation });
+ _try_complete_command(cmd, req, progress);
+ break;
+ }
+ case Request_node::DISCARD_SNAPSHOT:
+ {
+ Superblock_control::Discard_snapshot &req = *cmd.discard_snap_ptr;
+ progress |= _sb_control->execute(req, _block_io, _trust_anchor);
+ if (req.complete() && req.success())
+ _remove_snap_refs_with_same_gen(node.snap_id);
+ _try_complete_command(cmd, req, progress);
+ break;
+ }
+ default: ASSERT_NEVER_REACHED;
+ }
+ break;
+ }
+ default: break;
+ }
+ break;
+
+ case Command::LOG:
+
+ switch(cmd.state) {
+ case Command::INIT:
+
+ log("\n", cmd.log_node->string, "\n");
+ _mark_command_complete(cmd, true);
+ progress = true;
+ break;
+
+ default: break;
+ }
+ break;
+
+ case Command::CHECK:
+
+ switch(cmd.state) {
+ case Command::INIT:
+
+ cmd.check_superblocks_ptr = new (_heap) Sb_check::Check();
+ _mark_command_in_progress(cmd, progress);
+ break;
+
+ case Command::IN_PROGRESS:
+ {
+ Sb_check::Check &req = *cmd.check_superblocks_ptr;
+ progress |= _sb_check.execute(req, _vbd_check, _ft_check, _block_io);
+ _try_complete_command(cmd, req, progress);
+ break;
+ }
+ default: break;
+ }
+ break;
+
+ default: ASSERT_NEVER_REACHED;
+ }
+ return progress;
}
- Generation snap_id_to_gen(Snapshot_id id)
+ bool _execute_commands()
+ {
+ bool progress = false;
+ _command_schedule.with_head([&] (Command &head) {
+
+ progress |= _execute_command(head);
+ if (head.state == Command::COMPLETE) {
+ _command_schedule.remove_head();
+ return;
+ }
+ if (head.type != Command::REQUEST)
+ return;
+
+ Request_node::Operation op = head.request_node->op;
+ if (op != Request_node::REKEY &&
+ op != Request_node::EXTEND_VBD &&
+ op != Request_node::EXTEND_FREE_TREE)
+ return;
+
+ if (head.request_node->sync)
+ return;
+
+ if (head.state != Command::INIT)
+ return;
+
+ _command_schedule.try_yield_head([&] (Command &to_cmd) {
+
+ if (to_cmd.type != Command::REQUEST)
+ return false;
+
+ Request_node::Operation op = to_cmd.request_node->op;
+ return op == Request_node::READ ||
+ op == Request_node::WRITE ||
+ op == Request_node::SYNC ||
+ op == Request_node::DISCARD_SNAPSHOT;
+ });
+ });
+ return progress;
+ }
+
+ void _handle_signal()
+ {
+ while (_execute_commands());
+ if (_command_schedule.empty()) {
+ if (_num_errors) {
+ error(_num_errors, " command", _num_errors > 1 ? "s" : "", " failed!");
+ _env.parent().exit(-1);
+ } else {
+ log("All commands succeeded!");
+ _env.parent().exit(0);
+ }
+ }
+ _wakeup_back_end_services();
+ }
+
+ template
+ void _with_command(Command::Id id, FUNC && func)
+ {
+ ASSERT(_command_tree.first());
+ _command_tree.first()->with_command(id, func);
+ }
+
+ Generation _snap_id_to_gen(Snapshot_id id)
{
Generation gen { INVALID_GENERATION };
_snap_refs.with_ref(id, [&] (Snapshot_reference const &ref) {
@@ -613,230 +952,93 @@ class Tresor_tester::Main : private Vfs::Env::User, private Module_composition,
return gen;
}
- void add_snap_ref(Snapshot_id id, Generation gen) { _snap_refs.insert(new (_heap) Snapshot_reference { id, gen }); }
- void remove_snap_refs_with_same_gen(Snapshot_id id)
+ /********************
+ ** Vfs::Env::User **
+ ********************/
+
+ void wakeup_vfs_user() override { _signal_handler.local_submit(); }
+
+
+ /********************************
+ ** Crypto_key_files_interface **
+ ********************************/
+
+ void add_crypto_key(Key_id key_id) override
{
- Generation gen { snap_id_to_gen(id) };
- while (1) {
- Snapshot_reference *ref_ptr { nullptr };
- _snap_refs.for_each([&] (Snapshot_reference const &ref) {
- if (!ref_ptr && ref.gen == gen)
- ref_ptr = const_cast(&ref);
- });
- if (ref_ptr)
- _remove_snap_ref(*ref_ptr);
- else
- break;
- }
+ for (Constructible &key : _crypto_keys)
+ if (!key.constructed()) {
+ key.construct(key_id,
+ open_file(_vfs_env, { _crypto_path, "/keys/", key_id, "/encrypt" }, Vfs::Directory_service::OPEN_MODE_RDWR),
+ open_file(_vfs_env, { _crypto_path, "/keys/", key_id, "/decrypt" }, Vfs::Directory_service::OPEN_MODE_RDWR)
+ );
+ return;
+ }
+ ASSERT_NEVER_REACHED;
}
- void reset_snap_refs()
+ void remove_crypto_key(Key_id key_id) override
{
- while (_snap_refs.first())
- _remove_snap_ref(*_snap_refs.first());
+ Constructible &crypto_key = _crypto_key(key_id);
+ _vfs_env.root_dir().close(&crypto_key->encrypt_file);
+ _vfs_env.root_dir().close(&crypto_key->decrypt_file);
+ crypto_key.destruct();
}
- Pba_allocator &pba_alloc() { return _pba_alloc; }
+ Vfs::Vfs_handle &encrypt_file(Key_id key_id) override { return _crypto_key(key_id)->encrypt_file; }
+ Vfs::Vfs_handle &decrypt_file(Key_id key_id) override { return _crypto_key(key_id)->decrypt_file; }
- void generate_blk_data(Request_tag tresor_req_tag, Virtual_block_address vba, Tresor::Block &blk_data)
+
+ /***************************
+ ** Client_data_interface **
+ ***************************/
+
+ void obtain_data(Obtain_data_attr const &attr) override
{
- with_channel(tresor_req_tag, [&] (Command &cmd) {
- ASSERT(cmd.type() == Command::REQUEST);
- Request_node const &req_node { cmd.request_node() };
- if (req_node.salt_avail)
- _generate_blk_data(blk_data, vba, req_node.salt);
+ _with_command(attr.in_req_tag, [&] (Command &cmd) {
+ ASSERT(cmd.type == Command::REQUEST);
+ Request_node const &node { *cmd.request_node };
+ if (node.salt_avail)
+ _generate_blk_data(attr.out_blk, attr.in_vba, node.salt);
});
- _benchmark.raise_num_virt_blks_written();
+ if (_benchmark.constructed())
+ _benchmark->raise_num_virt_blks_written();
}
- void verify_blk_data(Request_tag tresor_req_tag, Virtual_block_address vba, Tresor::Block &blk_data)
+ void supply_data(Supply_data_attr const &attr) override
{
- with_channel(tresor_req_tag, [&] (Command &cmd) {
- ASSERT(cmd.type() == Command::REQUEST);
- Request_node const &req_node { cmd.request_node() };
- if (req_node.salt_avail) {
+ _with_command(attr.in_req_tag, [&] (Command &cmd) {
+ ASSERT(cmd.type == Command::REQUEST);
+ Request_node const &node { *cmd.request_node };
+ if (node.salt_avail) {
Tresor::Block gen_blk_data { };
- _generate_blk_data(gen_blk_data, vba, req_node.salt);
+ _generate_blk_data(gen_blk_data, attr.in_vba, node.salt);
- if (memcmp(&blk_data, &gen_blk_data, BLOCK_SIZE)) {
- cmd.data_mismatch(true);
- warning("client data mismatch: vba=", vba, " req_tag=", tresor_req_tag);
+ if (memcmp(&attr.in_blk, &gen_blk_data, BLOCK_SIZE)) {
+ warning("client data mismatch: vba=", attr.in_vba, " req_tag=", attr.in_req_tag);
_num_errors++;
}
}
});
- _benchmark.raise_num_virt_blks_read();
+ if (_benchmark.constructed())
+ _benchmark->raise_num_virt_blks_read();
}
- void construct_tresor_modules()
- {
- _free_tree.construct();
- _vbd.construct();
- _sb_control.construct();
- _request_pool.construct();
- _client_data.construct(*this);
- _meta_tree.construct();
- add_module(FREE_TREE, *_free_tree);
- add_module(VIRTUAL_BLOCK_DEVICE, *_vbd);
- add_module(SUPERBLOCK_CONTROL, *_sb_control);
- add_module(REQUEST_POOL, *_request_pool);
- add_module(CLIENT_DATA, *_client_data);
- add_module(META_TREE, *_meta_tree);
- }
+ public:
- void destruct_tresor_modules()
+ Main(Genode::Env &env) : _env(env)
{
- remove_module(META_TREE);
- remove_module(CLIENT_DATA);
- remove_module(REQUEST_POOL);
- remove_module(SUPERBLOCK_CONTROL);
- remove_module(VIRTUAL_BLOCK_DEVICE);
- remove_module(FREE_TREE);
- _meta_tree.destruct();
- _client_data.destruct();
- _request_pool.destruct();
- _sb_control.destruct();
- _vbd.destruct();
- _free_tree.destruct();
- }
-
- void check_snapshots(Command &cmd, bool &progress)
- {
- mark_command_in_progress(cmd.id());
- bool success { true };
- Snapshots_info snap_info { _sb_control->snapshots_info() };
- bool snap_gen_ok[MAX_NR_OF_SNAPSHOTS] { false };
- _snap_refs.for_each([&] (Snapshot_reference const &snap_ref) {
- bool snap_ref_ok { false };
- for (Snapshot_index idx { 0 }; idx < MAX_NR_OF_SNAPSHOTS; idx++) {
- if (snap_info.generations[idx] == snap_ref.gen) {
- snap_ref_ok = true;
- snap_gen_ok[idx] = true;
- }
- }
- if (!snap_ref_ok) {
- warning("snap (", snap_ref, ") not known to tresor");
- _num_errors++;
- success = false;
- }
+ Command::Id command_id { 0 };
+ _config_rom.xml().sub_node("commands").for_each_sub_node([&] (Xml_node const &node) {
+ Command *cmd_ptr = new (_heap) Command(node, command_id++);
+ _command_tree.insert(cmd_ptr);
+ _command_schedule.add_tail(*cmd_ptr);
});
- for (Snapshot_index idx { 0 }; idx < MAX_NR_OF_SNAPSHOTS; idx++) {
- if (snap_info.generations[idx] != INVALID_GENERATION && !snap_gen_ok[idx]) {
- warning("snap (idx ", idx, " gen ", snap_info.generations[idx], ") not known to tester");
- _num_errors++;
- success = false;
- }
- }
- mark_command_completed(cmd.id(), success);
- progress = true;
+ _handle_signal();
}
-
- Benchmark &benchmark() { return _benchmark; }
};
-void Tresor_tester::Client_data::_request_submitted(Module_request &mod_req)
-{
- Request &req { *static_cast(&mod_req) };
- switch (req._type) {
- case Request::OBTAIN_PLAINTEXT_BLK: _main.generate_blk_data(req._req_tag, req._vba, req._blk); break;
- case Request::SUPPLY_PLAINTEXT_BLK: _main.verify_blk_data(req._req_tag, req._vba, req._blk); break;
- }
- req._success = true;
-}
-
-
-void Tresor_tester::Command::_generated_req_completed(State_uint state_uint)
-{
- if (state_uint == CREATE_SNAP_COMPLETED)
- _main.add_snap_ref(request_node().snap_id, _gen);
-
- if (state_uint == DISCARD_SNAP_COMPLETED)
- _main.remove_snap_refs_with_same_gen(request_node().snap_id);
-
- _main.mark_command_completed(id(), _success);
-}
-
-
-void Tresor_tester::Command::execute(bool &progress)
-{
- switch (type()) {
- case REQUEST:
- {
- Request_node const &node { request_node() };
- State state { COMPLETED };
- _gen = INVALID_GENERATION;
- if (node.op == Request::DISCARD_SNAPSHOT) {
- _gen = _main.snap_id_to_gen(node.snap_id);
- state = DISCARD_SNAP_COMPLETED;
- }
- if (node.op == Request::CREATE_SNAPSHOT)
- state = CREATE_SNAP_COMPLETED;
-
- generate_req(
- state, progress, node.op, node.has_vba() ? node.vba : 0,
- 0, node.has_count() ? node.count : 0, 0, id(), _gen, _success);
-
- _main.mark_command_in_progress(id());
- break;
- }
- case Command::TRUST_ANCHOR:
- {
- Trust_anchor_node const &node { trust_anchor_node() };
- ASSERT(node.op == Trust_anchor_request::INITIALIZE);
- generate_req(COMPLETED, progress, node.passphrase, _success);
- _main.mark_command_in_progress(id());
- break;
- }
- case Command::INITIALIZE:
- {
- _main.reset_snap_refs();
- Tresor_init::Configuration const &cfg { initialize() };
- generate_req(COMPLETED, progress,
- (Tree_level_index)(cfg.vbd_nr_of_lvls() - 1),
- (Tree_degree)cfg.vbd_nr_of_children(), cfg.vbd_nr_of_leafs(),
- (Tree_level_index)cfg.ft_nr_of_lvls() - 1,
- (Tree_degree)cfg.ft_nr_of_children(), cfg.ft_nr_of_leafs(),
- (Tree_level_index)cfg.ft_nr_of_lvls() - 1,
- (Tree_degree)cfg.ft_nr_of_children(), cfg.ft_nr_of_leafs(), _main.pba_alloc(), _success);
- _main.mark_command_in_progress(id());
- break;
- }
- case Command::CHECK:
- generate_req(COMPLETED, progress, _success);
- _main.mark_command_in_progress(id());
- break;
- case LOG:
- log("\n", log_node().string, "\n");
- _main.mark_command_in_progress(id());
- _main.mark_command_completed(id(), true);
- progress = true;
- break;
- case BENCHMARK:
- _main.benchmark().execute_cmd(benchmark_node());
- _main.mark_command_in_progress(id());
- _main.mark_command_completed(id(), true);
- progress = true;
- break;
- case CONSTRUCT:
- _main.construct_tresor_modules();
- _main.mark_command_in_progress(id());
- _main.mark_command_completed(id(), true);
- progress = true;
- break;
- case DESTRUCT:
- _main.destruct_tresor_modules();
- _main.mark_command_in_progress(id());
- _main.mark_command_completed(id(), true);
- progress = true;
- break;
- case CHECK_SNAPSHOTS: _main.check_snapshots(*this, progress); break;
- default: break;
- }
-}
-
-
void Component::construct(Genode::Env &env) { static Tresor_tester::Main main(env); }
diff --git a/repos/gems/src/lib/tresor/block_io.cc b/repos/gems/src/lib/tresor/block_io.cc
index e1c0b6b2ee..9abc54eee4 100644
--- a/repos/gems/src/lib/tresor/block_io.cc
+++ b/repos/gems/src/lib/tresor/block_io.cc
@@ -12,199 +12,79 @@
*/
/* tresor includes */
-#include
#include
#include
using namespace Tresor;
-Block_io_request::Block_io_request(Module_id src_module_id, Module_channel_id src_chan_id, Type type,
- Request_offset client_req_offset, Request_tag client_req_tag, Key_id key_id,
- Physical_block_address pba, Virtual_block_address vba, Block &blk, Hash &hash,
- bool &success)
-:
- Module_request { src_module_id, src_chan_id, BLOCK_IO }, _type { type },
- _client_req_offset { client_req_offset }, _client_req_tag { client_req_tag },
- _key_id { key_id }, _pba { pba }, _vba { vba }, _blk { blk }, _hash { hash }, _success { success }
-{ }
-
-char const *Block_io_request::type_to_string(Type type)
+bool Block_io::Sync::execute(Vfs::Vfs_handle &file)
{
- switch (type) {
- case READ: return "read";
- case WRITE: return "write";
- case SYNC: return "sync";
- case READ_CLIENT_DATA: return "read_client_data";
- case WRITE_CLIENT_DATA: return "write_client_data";
- }
- ASSERT_NEVER_REACHED;
-}
+ bool progress = false;
+ switch (_helper.state) {
+ case INIT:
+ _file.construct(_helper.state, file);
+ _helper.state = SYNC;
+ progress = true;
+ break;
-void Block_io_channel::_generated_req_completed(State_uint state_uint)
-{
- if (!_generated_req_success) {
- error("block io: request (", *_req_ptr, ") failed because generated request failed)");
- _req_ptr->_success = false;
- _state = REQ_COMPLETE;
- _req_ptr = nullptr;
- return;
- }
- _state = (State)state_uint;
-}
-
-
-void Block_io_channel::_mark_req_failed(bool &progress, Error_string str)
-{
- error("request failed: failed to ", str);
- _req_ptr->_success = false;
- _state = REQ_COMPLETE;
- _req_ptr = nullptr;
- progress = true;
-}
-
-
-void Block_io_channel::_mark_req_successful(bool &progress)
-{
- Request &req { *_req_ptr };
- req._success = true;
- _state = REQ_COMPLETE;
- _req_ptr = nullptr;
- progress = true;
- if (VERBOSE_BLOCK_IO && (!VERBOSE_BLOCK_IO_PBA_FILTER || VERBOSE_BLOCK_IO_PBA == req._pba)) {
- switch (req._type) {
- case Request::READ:
- case Request::WRITE:
- log("block_io: ", req.type_to_string(req._type), " pba ", req._pba, " hash ", hash(req._blk));
- break;
- default: break;
- }
- }
-}
-
-
-void Block_io_channel::_read(bool &progress)
-{
- Request &req { *_req_ptr };
- switch (_state) {
- case REQ_SUBMITTED: _file.read(READ_OK, FILE_ERR, req._pba * BLOCK_SIZE, { (char *)&req._blk, BLOCK_SIZE }, progress); break;
- case READ_OK: _mark_req_successful(progress); break;
- case FILE_ERR: _mark_req_failed(progress, "file operation failed"); break;
+ case SYNC: _file->sync(SYNC_OK, FILE_ERR, progress); break;
+ case SYNC_OK: _helper.mark_succeeded(progress); break;
+ case FILE_ERR: _helper.mark_failed(progress, "file operation failed"); break;
default: break;
}
+ return progress;
}
-void Block_io_channel::_read_client_data(bool &progress)
+bool Block_io::Read::execute(Vfs::Vfs_handle &file)
{
+ bool progress = false;
+ switch (_helper.state) {
+ case INIT:
- Request &req { *_req_ptr };
- switch (_state) {
- case REQ_SUBMITTED: _file.read(READ_OK, FILE_ERR, req._pba * BLOCK_SIZE, { (char *)&_blk, BLOCK_SIZE }, progress); break;
+ _file.construct(_helper.state, file);
+ _helper.state = READ;
+ progress = true;
+ break;
+
+ case READ: _file->read(READ_OK, FILE_ERR, _attr.in_pba * BLOCK_SIZE, { (char *)&_attr.out_block, BLOCK_SIZE }, progress); break;
case READ_OK:
- calc_hash(_blk, req._hash);
- _generate_req(
- PLAINTEXT_BLK_SUPPLIED, progress, Crypto_request::DECRYPT_CLIENT_DATA, req._client_req_offset,
- req._client_req_tag, req._key_id, *(Key_value *)0, req._pba, req._vba, _blk);
- return;
-
- case PLAINTEXT_BLK_SUPPLIED: _mark_req_successful(progress); break;
- case FILE_ERR: _mark_req_failed(progress, "file operation failed"); break;
- default: break;
- }
-}
-
-
-void Block_io_channel::_write_client_data(bool &progress)
-{
- Request &req { *_req_ptr };
- switch (_state) {
- case REQ_SUBMITTED:
-
- _generate_req(
- CIPHERTEXT_BLK_OBTAINED, progress, Crypto_request::ENCRYPT_CLIENT_DATA, req._client_req_offset,
- req._client_req_tag, req._key_id, *(Key_value *)0, req._pba, req._vba, _blk);
+ _helper.mark_succeeded(progress);
+ if (VERBOSE_BLOCK_IO && (!VERBOSE_BLOCK_IO_PBA_FILTER || VERBOSE_BLOCK_IO_PBA == _attr.in_pba))
+ log("block_io: ", *this, " hash ", hash(_attr.out_block));
break;
- case CIPHERTEXT_BLK_OBTAINED:
+ case FILE_ERR: _helper.mark_failed(progress, "file operation failed"); break;
+ default: break;
+ }
+ return progress;
+}
- calc_hash(_blk, req._hash);
- _file.write(WRITE_OK, FILE_ERR, req._pba * BLOCK_SIZE, { (char *)&_blk, BLOCK_SIZE }, progress); break;
+
+bool Block_io::Write::execute(Vfs::Vfs_handle &file)
+{
+ bool progress = false;
+ switch (_helper.state) {
+ case INIT:
+
+ _file.construct(_helper.state, file);
+ _helper.state = WRITE;
+ progress = true;
break;
- case WRITE_OK: _mark_req_successful(progress); break;
- case FILE_ERR: _mark_req_failed(progress, "file operation failed"); break;
+ case WRITE: _file->write(WRITE_OK, FILE_ERR, _attr.in_pba * BLOCK_SIZE, { (char *)&_attr.in_block, BLOCK_SIZE }, progress); break;
+ case WRITE_OK:
+
+ _helper.mark_succeeded(progress);
+ if (VERBOSE_BLOCK_IO && (!VERBOSE_BLOCK_IO_PBA_FILTER || VERBOSE_BLOCK_IO_PBA == _attr.in_pba))
+ log("block_io: ", *this, " hash ", hash(_attr.in_block));
+ break;
+
+ case FILE_ERR: _helper.mark_failed(progress, "file operation failed"); break;
default: break;
}
-}
-
-
-void Block_io_channel::_write(bool &progress)
-{
-
- Request &req { *_req_ptr };
- switch (_state) {
- case REQ_SUBMITTED: _file.write(WRITE_OK, FILE_ERR, req._pba * BLOCK_SIZE, { (char *)&req._blk, BLOCK_SIZE }, progress); break;
- case WRITE_OK: _mark_req_successful(progress); break;
- case FILE_ERR: _mark_req_failed(progress, "file operation failed"); break;
- default: break;
- }
-}
-
-
-void Block_io_channel::_sync(bool &progress)
-{
- switch (_state) {
- case REQ_SUBMITTED: _file.sync(SYNC_OK, FILE_ERR, progress); break;
- case SYNC_OK: _mark_req_successful(progress); break;
- case FILE_ERR: _mark_req_failed(progress, "file operation failed"); break;
- default: break;
- }
-}
-
-
-void Block_io_channel::execute(bool &progress)
-{
- if (!_req_ptr)
- return;
-
- switch (_req_ptr->_type) {
- case Request::READ: _read(progress); break;
- case Request::WRITE: _write(progress); break;
- case Request::SYNC: _sync(progress); break;
- case Request::READ_CLIENT_DATA: _read_client_data(progress); break;
- case Request::WRITE_CLIENT_DATA: _write_client_data(progress); break;
- }
-}
-
-
-void Block_io::execute(bool &progress)
-{
- for_each_channel([&] (Channel &chan) {
- chan.execute(progress); });
-}
-
-
-void Block_io_channel::_request_submitted(Module_request &mod_req)
-{
- _req_ptr = static_cast(&mod_req);
- _state = REQ_SUBMITTED;
-}
-
-
-Block_io_channel::Block_io_channel(Module_channel_id id, Vfs::Env &vfs_env, Xml_node const &xml_node)
-:
- Module_channel { BLOCK_IO, id }, _vfs_env { vfs_env }, _path { xml_node.attribute_value("path", Tresor::Path()) }
-{ }
-
-
-Block_io::Block_io(Vfs::Env &vfs_env, Xml_node const &xml_node)
-{
- Module_channel_id id { 0 };
- for (Constructible &chan : _channels) {
- chan.construct(id++, vfs_env, xml_node);
- add_channel(*chan);
- }
+ return progress;
}
diff --git a/repos/gems/src/lib/tresor/crypto.cc b/repos/gems/src/lib/tresor/crypto.cc
index 8a2f7e2a64..22b40a8d98 100644
--- a/repos/gems/src/lib/tresor/crypto.cc
+++ b/repos/gems/src/lib/tresor/crypto.cc
@@ -13,317 +13,101 @@
/* tresor includes */
#include
-#include
#include
using namespace Tresor;
-Crypto_request::Crypto_request(Module_id src_module_id, Module_channel_id src_chan_id, Type type,
- Request_offset client_req_offset, Request_tag client_req_tag, Key_id key_id,
- Key_value const &key_plaintext, Physical_block_address pba, Virtual_block_address vba,
- Block &blk, bool &success)
-:
- Module_request { src_module_id, src_chan_id, CRYPTO }, _type { type }, _client_req_offset { client_req_offset },
- _client_req_tag { client_req_tag }, _pba { pba }, _vba { vba }, _key_id { key_id }, _key_plaintext { key_plaintext },
- _blk { blk }, _success { success }
-{ }
-
-
-void Crypto_request::print(Output &out) const
+bool Crypto::Add_key::execute(Crypto::Attr const &crypto_attr)
{
- Genode::print(out, type_to_string(_type));
- switch (_type) {
- case ADD_KEY:
- case REMOVE_KEY: Genode::print(out, " ", _key_id); break;
- case DECRYPT:
- case ENCRYPT:
- case DECRYPT_CLIENT_DATA:
- case ENCRYPT_CLIENT_DATA: Genode::print(out, " pba ", _pba); break;
- default: break;
- }
-}
+ bool progress { false };
+ switch (_helper.state) {
+ case INIT:
-
-char const *Crypto_request::type_to_string(Type type)
-{
- switch (type) {
- case ADD_KEY: return "add_key";
- case REMOVE_KEY: return "remove_key";
- case ENCRYPT_CLIENT_DATA: return "encrypt_client_data";
- case DECRYPT_CLIENT_DATA: return "decrypt_client_data";
- case ENCRYPT: return "encrypt";
- case DECRYPT: return "decrypt";
- }
- ASSERT_NEVER_REACHED;
-}
-
-
-void Crypto_channel::_generated_req_completed(State_uint state_uint)
-{
- if (!_generated_req_success) {
- error("crypto: request (", *_req_ptr, ") failed because generated request failed)");
- _req_ptr->_success = false;
- _state = REQ_COMPLETE;
- _req_ptr = nullptr;
- return;
- }
- _state = (State)state_uint;
-}
-
-
-Constructible &Crypto_channel::_key_dir(Key_id key_id)
-{
- for (Constructible &key_dir : _key_dirs)
- if (key_dir.constructed() && key_dir->key_id == key_id)
- return key_dir;
- ASSERT_NEVER_REACHED;
-}
-
-
-void Crypto_channel::_mark_req_failed(bool &progress, char const *str)
-{
- error("crypto: request (", *_req_ptr, ") failed at step \"", str, "\"");
- _req_ptr->_success = false;
- _state = REQ_COMPLETE;
- _req_ptr = nullptr;
- progress = true;
-}
-
-
-void Crypto_channel::_mark_req_successful(bool &progress)
-{
- Request &req { *_req_ptr };
- req._success = true;
- _state = REQ_COMPLETE;
- _req_ptr = nullptr;
- progress = true;
- if (VERBOSE_WRITE_VBA && req._type == Request::ENCRYPT_CLIENT_DATA)
- log(" encrypt leaf data: plaintext ", _blk, " hash ", hash(_blk),
- "\n update branch:\n ", Branch_lvl_prefix("leaf data: "), req._blk);
-
- if (VERBOSE_READ_VBA && req._type == Request::DECRYPT_CLIENT_DATA)
- log(" ", Branch_lvl_prefix("leaf data: "), req._blk,
- "\n decrypt leaf data: plaintext ", _blk, " hash ", hash(_blk));
-
- if (VERBOSE_CRYPTO) {
- switch (req._type) {
- case Request::DECRYPT_CLIENT_DATA:
- case Request::ENCRYPT_CLIENT_DATA:
- log("crypto: ", req.type_to_string(req._type), " pba ", req._pba, " vba ", req._vba,
- " plain ", _blk, " cipher ", req._blk);
- break;
- default: break;
- }
- }
- if (VERBOSE_BLOCK_IO && (!VERBOSE_BLOCK_IO_PBA_FILTER || VERBOSE_BLOCK_IO_PBA == req._pba)) {
- switch (req._type) {
- case Request::DECRYPT_CLIENT_DATA:
- log("block_io: read pba ", req._pba, " hash ", hash(req._blk), " (plaintext hash ", hash(_blk), ")");
- break;
- case Request::ENCRYPT_CLIENT_DATA:
- log("block_io: write pba ", req._pba, " hash ", hash(req._blk), " (plaintext hash ", hash(_blk), ")");
- break;
- default: break;
- }
- }
-}
-
-
-void Crypto_channel::_add_key(bool &progress)
-{
- Request &req { *_req_ptr };
- switch (_state) {
- case REQ_SUBMITTED:
-
- memcpy(_add_key_buf, &req._key_id, sizeof(Key_id));
- memcpy(_add_key_buf + sizeof(Key_id), &req._key_plaintext, KEY_SIZE);
- _add_key_file.write(WRITE_OK, FILE_ERR, 0, { _add_key_buf, sizeof(_add_key_buf) }, progress);
+ _file.construct(_helper.state, crypto_attr.add_key_file);
+ memcpy(_write_buf, &_attr.in_key.id, sizeof(Key_id));
+ memcpy(_write_buf + sizeof(Key_id), &_attr.in_key.value, sizeof(Key_value));
+ _helper.state = WRITE;
+ progress = true;
break;
- case WRITE_OK:
- {
- Constructible *key_dir_ptr { nullptr };
- for (Constructible &key_dir : _key_dirs)
- if (!key_dir.constructed())
- key_dir_ptr = &key_dir;
- if (!key_dir_ptr) {
- _mark_req_failed(progress, "find unused key dir");
- break;
- }
- key_dir_ptr->construct(*this, req._key_id);
- _mark_req_successful(progress);
- break;
- }
- case FILE_ERR: _mark_req_failed(progress, "file operation failed"); break;
- default: break;
- }
-}
-
-
-void Crypto_channel::_remove_key(bool &progress)
-{
- Request &req { *_req_ptr };
- switch (_state) {
- case REQ_SUBMITTED: _remove_key_file.write(WRITE_OK, FILE_ERR, 0, { (char *)&req._key_id, sizeof(Key_id) }, progress); break;
+ case WRITE: _file->write(WRITE_OK, FILE_ERR, 0, { _write_buf, sizeof(_write_buf) }, progress); break;
case WRITE_OK:
- _key_dir(req._key_id).destruct();
- _mark_req_successful(progress);
+ crypto_attr.key_files.add_crypto_key(_attr.in_key.id);
+ _helper.mark_succeeded(progress);
break;
- case FILE_ERR: _mark_req_failed(progress, "file operation failed"); break;
- default: return;
- }
-}
-
-
-void Crypto_channel::_encrypt_client_data(bool &progress)
-{
- Request &req { *_req_ptr };
- switch (_state) {
- case REQ_SUBMITTED:
-
- _generate_req(
- PLAINTEXT_BLK_OBTAINED, progress, Client_data_request::OBTAIN_PLAINTEXT_BLK,
- req._client_req_offset, req._client_req_tag, req._pba, req._vba, _blk);;
- break;
-
- case PLAINTEXT_BLK_OBTAINED:
-
- _key_dir(req._key_id)->encrypt_file.write(
- WRITE_OK, FILE_ERR, req._pba * BLOCK_SIZE, { (char *)&_blk, BLOCK_SIZE }, progress);
- break;
-
- case WRITE_OK:
-
- _key_dir(req._key_id)->encrypt_file.read(
- READ_OK, FILE_ERR, req._pba * BLOCK_SIZE, { (char *)&req._blk, BLOCK_SIZE }, progress);
- break;
-
- case READ_OK: _mark_req_successful(progress); break;
- case FILE_ERR: _mark_req_failed(progress, "file operation"); break;
+ case FILE_ERR: _helper.mark_failed(progress, "file operation failed"); break;
default: break;
}
+ return progress;
}
-void Crypto_channel::_encrypt(bool &progress)
+bool Crypto::Remove_key::execute(Crypto::Attr const &crypto_attr)
{
- Request &req { *_req_ptr };
- switch (_state) {
- case REQ_SUBMITTED:
+ bool progress { false };
+ switch (_helper.state) {
+ case INIT:
- _key_dir(req._key_id)->encrypt_file.write(
- WRITE_OK, FILE_ERR, req._pba * BLOCK_SIZE, { (char *)&req._blk, BLOCK_SIZE }, progress);
+ _file.construct(_helper.state, crypto_attr.remove_key_file);
+ _helper.state = WRITE;
+ progress = true;
break;
+ case WRITE: _file->write(WRITE_OK, FILE_ERR, 0, { (char *)&_attr.in_key_id, sizeof(Key_id) }, progress); break;
case WRITE_OK:
- _key_dir(req._key_id)->encrypt_file.read(
- READ_OK, FILE_ERR, req._pba * BLOCK_SIZE, { (char *)&req._blk, BLOCK_SIZE }, progress);
+ crypto_attr.key_files.remove_crypto_key(_attr.in_key_id);
+ _helper.mark_succeeded(progress);
break;
- case READ_OK: _mark_req_successful(progress); break;
- case FILE_ERR: _mark_req_failed(progress, "file operation"); break;
+ case FILE_ERR: _helper.mark_failed(progress, "file operation failed"); break;
default: break;
}
+ return progress;
}
-void Crypto_channel::_decrypt(bool &progress)
+bool Crypto::Encrypt::execute(Crypto::Attr const &crypto_attr)
{
- Request &req { *_req_ptr };
- switch (_state) {
- case REQ_SUBMITTED:
+ bool progress { false };
+ switch (_helper.state) {
+ case INIT:
- _key_dir(req._key_id)->decrypt_file.write(
- WRITE_OK, FILE_ERR, req._pba * BLOCK_SIZE, { (char *)&req._blk, BLOCK_SIZE }, progress);
+ _file.construct(_helper.state, crypto_attr.key_files.encrypt_file(_attr.in_key_id));
+ _offset = _attr.in_pba * BLOCK_SIZE;
+ _helper.state = WRITE;
+ progress = true;
break;
- case WRITE_OK:
-
- _key_dir(req._key_id)->decrypt_file.read(
- READ_OK, FILE_ERR, req._pba * BLOCK_SIZE, { (char *)&req._blk, BLOCK_SIZE }, progress);
- break;
-
- case READ_OK: _mark_req_successful(progress); break;
- case FILE_ERR: _mark_req_failed(progress, "file operation"); break;
+ case WRITE: _file->write(WRITE_OK, FILE_ERR, _offset, { (char *)&_attr.in_out_blk, BLOCK_SIZE }, progress); break;
+ case WRITE_OK: _file->read(READ_OK, FILE_ERR, _offset, { (char *)&_attr.in_out_blk, BLOCK_SIZE }, progress); break;
+ case READ_OK: _helper.mark_succeeded(progress); break;
+ case FILE_ERR: _helper.mark_failed(progress, "file-operation error"); break;
default: break;
}
+ return progress;
}
-void Crypto_channel::_decrypt_client_data(bool &progress)
+bool Crypto::Decrypt::execute(Crypto::Attr const &crypto_attr)
{
- Request &req { *_req_ptr };
- switch (_state) {
- case REQ_SUBMITTED:
+ bool progress { false };
+ switch (_helper.state) {
+ case INIT:
- _key_dir(req._key_id)->decrypt_file.write(
- WRITE_OK, FILE_ERR, req._pba * BLOCK_SIZE, { (char *)&req._blk, BLOCK_SIZE }, progress);
+ _file.construct(_helper.state, crypto_attr.key_files.decrypt_file(_attr.in_key_id));
+ _offset = _attr.in_pba * BLOCK_SIZE;
+ _helper.state = WRITE;
+ progress = true;
break;
- case WRITE_OK:
-
- _key_dir(req._key_id)->decrypt_file.read(
- READ_OK, FILE_ERR, req._pba * BLOCK_SIZE, { (char *)&_blk, BLOCK_SIZE }, progress);
- break;
-
- case READ_OK:
-
- _generate_req(
- PLAINTEXT_BLK_SUPPLIED, progress, Client_data_request::SUPPLY_PLAINTEXT_BLK,
- req._client_req_offset, req._client_req_tag, req._pba, req._vba, _blk);;
- break;
-
- case PLAINTEXT_BLK_SUPPLIED: _mark_req_successful(progress); break;
- case FILE_ERR: _mark_req_failed(progress, "file operation failed"); break;
+ case WRITE: _file->write(WRITE_OK, FILE_ERR, _offset, { (char *)&_attr.in_out_blk, BLOCK_SIZE }, progress); break;
+ case WRITE_OK: _file->read(READ_OK, FILE_ERR, _offset, { (char *)&_attr.in_out_blk, BLOCK_SIZE }, progress); break;
+ case READ_OK: _helper.mark_succeeded(progress); break;
+ case FILE_ERR: _helper.mark_failed(progress, "file-operation error"); break;
default: break;
}
-}
-
-
-void Crypto_channel::_request_submitted(Module_request &mod_req)
-{
- _req_ptr = static_cast(&mod_req);
- _state = REQ_SUBMITTED;
-}
-
-
-void Crypto_channel::execute(bool &progress)
-{
- if (!_req_ptr)
- return;
-
- switch (_req_ptr->_type) {
- case Request::ADD_KEY: _add_key(progress); break;
- case Request::REMOVE_KEY: _remove_key(progress); break;
- case Request::DECRYPT: _decrypt(progress); break;
- case Request::ENCRYPT: _encrypt(progress); break;
- case Request::DECRYPT_CLIENT_DATA: _decrypt_client_data(progress); break;
- case Request::ENCRYPT_CLIENT_DATA: _encrypt_client_data(progress); break;
- }
-}
-
-
-void Crypto::execute(bool &progress)
-{
- for_each_channel([&] (Channel &chan) {
- chan.execute(progress); });
-}
-
-
-Crypto_channel::Crypto_channel(Module_channel_id id, Vfs::Env &vfs_env, Xml_node const &xml_node)
-:
- Module_channel { CRYPTO, id }, _vfs_env { vfs_env }, _path { xml_node.attribute_value("path", Tresor::Path()) }
-{ }
-
-
-Crypto::Crypto(Vfs::Env &vfs_env, Xml_node const &xml_node)
-{
- Module_channel_id id { 0 };
- for (Constructible &chan : _channels) {
- chan.construct(id++, vfs_env, xml_node);
- add_channel(*chan);
- }
+ return progress;
}
diff --git a/repos/gems/src/lib/tresor/free_tree.cc b/repos/gems/src/lib/tresor/free_tree.cc
index 2b08554122..472a232d26 100644
--- a/repos/gems/src/lib/tresor/free_tree.cc
+++ b/repos/gems/src/lib/tresor/free_tree.cc
@@ -13,62 +13,22 @@
/* tresor includes */
#include
-#include
-#include
#include
using namespace Tresor;
-char const *Free_tree_request::type_to_string(Type type)
+bool Free_tree::Allocate_pbas::_can_alloc_pba_of(Type_2_node &node)
{
- switch (type) {
- case ALLOC_FOR_NON_RKG: return "alloc_for_non_rkg";
- case ALLOC_FOR_RKG_CURR_GEN_BLKS: return "alloc_for_rkg_curr_gen_blks";
- case ALLOC_FOR_RKG_OLD_GEN_BLKS: return "alloc_for_rkg_old_gen_blks";
- case EXTENSION_STEP: return "extension_step";
- }
- ASSERT_NEVER_REACHED;
-}
-
-
-Free_tree_request::Free_tree_request(Module_id src_module_id, Module_channel_id src_chan_id, Type type,
- Tree_root &ft, Tree_root &mt, Snapshots const &snapshots, Generation last_secured_gen,
- Generation curr_gen, Generation free_gen, Number_of_blocks num_required_pbas,
- Tree_walk_pbas &new_blocks, Type_1_node_walk const &old_blocks,
- Tree_level_index max_lvl, Virtual_block_address vba, Tree_degree vbd_degree,
- Virtual_block_address vbd_max_vba, bool rekeying, Key_id prev_key_id,
- Key_id curr_key_id, Virtual_block_address rekeying_vba, Physical_block_address &pba,
- Number_of_blocks &num_pbas, bool &success)
-
-:
- Module_request { src_module_id, src_chan_id, FREE_TREE }, _type { type }, _ft { ft }, _mt { mt },
- _curr_gen { curr_gen }, _free_gen { free_gen }, _num_required_pbas { num_required_pbas }, _new_blocks { new_blocks },
- _old_blocks { old_blocks }, _max_lvl { max_lvl }, _vba { vba }, _vbd_degree { vbd_degree }, _vbd_max_vba { vbd_max_vba },
- _rekeying { rekeying }, _prev_key_id { prev_key_id }, _curr_key_id { curr_key_id }, _rekeying_vba { rekeying_vba },
- _success { success }, _snapshots { snapshots }, _last_secured_gen { last_secured_gen }, _pba { pba }, _num_pbas { num_pbas }
-{ }
-
-
-void Free_tree::execute(bool &progress)
-{
- for_each_channel([&] (Channel &chan) {
- chan.execute(progress); });
-}
-
-
-bool Free_tree_channel::_can_alloc_pba_of(Type_2_node &node)
-{
- Request &req { *_req_ptr };
- if (node.pba == 0 || node.pba == INVALID_PBA || node.free_gen > req._last_secured_gen)
+ if (node.pba == 0 || node.pba == INVALID_PBA || node.free_gen > _attr.in_last_secured_gen)
return false;
if (!node.reserved)
return true;
- if (req._rekeying && node.last_key_id == req._prev_key_id && node.last_vba < req._rekeying_vba)
+ if (_attr.in_rekeying && node.last_key_id == _attr.in_prev_key_id && node.last_vba < _attr.in_rekeying_vba)
return true;
- for (Snapshot const &snap : req._snapshots.items)
+ for (Snapshot const &snap : _attr.in_snapshots.items)
if (snap.valid && node.free_gen > snap.gen && node.alloc_gen < snap.gen + 1)
return false;
@@ -76,62 +36,48 @@ bool Free_tree_channel::_can_alloc_pba_of(Type_2_node &node)
}
-void Free_tree_channel::_generated_req_completed(State_uint state_uint)
+void Free_tree::Allocate_pbas::_alloc_pba_of(Type_2_node &t2_node)
{
- if (!_generated_req_success) {
- error("free tree: request (", *_req_ptr, ") failed because generated request failed)");
- _req_ptr->_success = false;
- _state = REQ_COMPLETE;
- _req_ptr = nullptr;
- return;
- }
- _state = (State)state_uint;
-}
-
-
-void Free_tree_channel::_alloc_pba_of(Type_2_node &t2_node)
-{
- Request &req { *_req_ptr };
Tree_level_index vbd_lvl { 0 };
- for (; vbd_lvl <= req._max_lvl && req._new_blocks.pbas[vbd_lvl]; vbd_lvl++);
+ for (; vbd_lvl <= _attr.in_max_lvl && _attr.in_out_new_blocks.pbas[vbd_lvl]; vbd_lvl++);
- Virtual_block_address node_min_vba { vbd_node_min_vba(_vbd_degree_log_2, vbd_lvl, req._vba) };
- req._new_blocks.pbas[vbd_lvl] = t2_node.pba;
- t2_node.alloc_gen = req._old_blocks.nodes[vbd_lvl].gen;
- t2_node.free_gen = req._free_gen;
- Virtual_block_address rkg_vba { req._rekeying_vba };
- switch (req._type) {
- case Request::ALLOC_FOR_NON_RKG:
+ Virtual_block_address node_min_vba { vbd_node_min_vba(_vbd_degree_log_2, vbd_lvl, _attr.in_vba) };
+ _attr.in_out_new_blocks.pbas[vbd_lvl] = t2_node.pba;
+ t2_node.alloc_gen = _attr.in_old_blocks.nodes[vbd_lvl].gen;
+ t2_node.free_gen = _attr.in_free_gen;
+ Virtual_block_address rkg_vba { _attr.in_rekeying_vba };
+ switch (_attr.in_application) {
+ case NON_REKEYING:
t2_node.reserved = true;
- t2_node.pba = req._old_blocks.nodes[vbd_lvl].pba;
+ t2_node.pba = _attr.in_old_blocks.nodes[vbd_lvl].pba;
t2_node.last_vba = node_min_vba;
- if (req._rekeying) {
- if (req._vba < rkg_vba)
- t2_node.last_key_id = req._curr_key_id;
+ if (_attr.in_rekeying) {
+ if (_attr.in_vba < rkg_vba)
+ t2_node.last_key_id = _attr.in_curr_key_id;
else
- t2_node.last_key_id = req._prev_key_id;
+ t2_node.last_key_id = _attr.in_prev_key_id;
} else
- t2_node.last_key_id = req._curr_key_id;
+ t2_node.last_key_id = _attr.in_curr_key_id;
break;
- case Request::ALLOC_FOR_RKG_CURR_GEN_BLKS:
+ case REKEYING_IN_CURRENT_GENERATION:
t2_node.reserved = false;
- t2_node.pba = req._old_blocks.nodes[vbd_lvl].pba;
+ t2_node.pba = _attr.in_old_blocks.nodes[vbd_lvl].pba;
t2_node.last_vba = node_min_vba;
- t2_node.last_key_id = req._prev_key_id;
+ t2_node.last_key_id = _attr.in_prev_key_id;
break;
- case Request::ALLOC_FOR_RKG_OLD_GEN_BLKS:
+ case REKEYING_IN_OLDER_GENERATION:
{
t2_node.reserved = true;
- Virtual_block_address node_max_vba { vbd_node_max_vba(_vbd_degree_log_2, vbd_lvl, req._vba) };
- if (rkg_vba < node_max_vba && rkg_vba < req._vbd_max_vba) {
- t2_node.last_key_id = req._prev_key_id;
+ Virtual_block_address node_max_vba { vbd_node_max_vba(_vbd_degree_log_2, vbd_lvl, _attr.in_vba) };
+ if (rkg_vba < node_max_vba && rkg_vba < _attr.in_vbd_max_vba) {
+ t2_node.last_key_id = _attr.in_prev_key_id;
t2_node.last_vba = rkg_vba + 1;
- } else if (rkg_vba == node_max_vba || rkg_vba == req._vbd_max_vba) {
- t2_node.last_key_id = req._curr_key_id;
+ } else if (rkg_vba == node_max_vba || rkg_vba == _attr.in_vbd_max_vba) {
+ t2_node.last_key_id = _attr.in_curr_key_id;
t2_node.last_vba = node_min_vba;
} else
ASSERT_NEVER_REACHED;
@@ -142,78 +88,59 @@ void Free_tree_channel::_alloc_pba_of(Type_2_node &t2_node)
}
-void Free_tree_channel::_mark_req_failed(bool &progress, char const *str)
-{
- error(Request::type_to_string(_req_ptr->_type), " request failed, reason: \"", str, "\"");
- _req_ptr->_success = false;
- _state = REQ_COMPLETE;
- _req_ptr = nullptr;
- progress = true;
-}
-
-
-void Free_tree_channel::_mark_req_successful(bool &progress)
-{
- _req_ptr->_success = true;
- _state = REQ_COMPLETE;
- _req_ptr = nullptr;
- progress = true;
-}
-
-
-void Free_tree_channel::_start_tree_traversal(bool &progress)
-{
- Request &req { *_req_ptr };
- _num_pbas = 0;
- _lvl = req._ft.max_lvl;
- _node_idx[_lvl] = 0;
- _t1_blks[_lvl].nodes[_node_idx[_lvl]] = req._ft.t1_node();
- _generate_req(SEEK_DOWN, progress, req._ft.pba, _blk);
-}
-
-
-void Free_tree_channel::_traverse_curr_node(bool &progress)
+void Free_tree::Allocate_pbas::_traverse_curr_node(bool &progress)
{
if (_lvl) {
Type_1_node &t1_node { _t1_blks[_lvl].nodes[_node_idx[_lvl]] };
if (t1_node.pba)
- _generate_req(SEEK_DOWN, progress, t1_node.pba, _blk);
+ _read_block.generate(_helper, READ_BLK, SEEK_DOWN, progress, t1_node.pba, _blk);
else {
- _state = SEEK_LEFT_OR_UP;
+ _helper.state = SEEK_LEFT_OR_UP;
progress = true;
}
} else {
Type_2_node &t2_node { _t2_blk.nodes[_node_idx[_lvl]] };
- if (_num_pbas < _req_ptr->_num_required_pbas && _can_alloc_pba_of(t2_node)) {
+ if (_num_pbas < _attr.in_num_required_pbas && _can_alloc_pba_of(t2_node)) {
if (_apply_allocation)
_alloc_pba_of(t2_node);
_num_pbas++;
}
- _state = SEEK_LEFT_OR_UP;
+ _helper.state = SEEK_LEFT_OR_UP;
progress = true;
}
}
-void Free_tree_channel::_alloc_pbas(bool &progress)
+void Free_tree::Allocate_pbas::_start_tree_traversal(bool &progress)
{
- Request &req { *_req_ptr };
- switch (_state) {
- case REQ_SUBMITTED:
+ _num_pbas = 0;
+ _lvl = _attr.in_out_ft.max_lvl;
+ _node_idx[_lvl] = 0;
+ _t1_blks[_lvl].nodes[_node_idx[_lvl]] = _attr.in_out_ft.t1_node();
+ _read_block.generate(_helper, READ_BLK, SEEK_DOWN, progress, _attr.in_out_ft.pba, _blk);
+}
- _vbd_degree_log_2 = log2(req._vbd_degree);
+
+bool Free_tree::Allocate_pbas::execute(Block_io &block_io, Meta_tree &meta_tree)
+{
+ bool progress = false;
+ switch (_helper.state) {
+ case INIT:
+
+ _vbd_degree_log_2 = log2(_attr.in_vbd_degree);
_apply_allocation = false;
_start_tree_traversal(progress);
break;
+ case READ_BLK: progress |= _read_block.execute(block_io); break;
case SEEK_DOWN:
{
if (!check_hash(_blk, _t1_blks[_lvl].nodes[_node_idx[_lvl]].hash)) {
- _mark_req_failed(progress, "hash mismatch");
+ _helper.mark_failed(progress, "hash mismatch");
break;
}
_lvl--;
- _node_idx[_lvl] = req._ft.degree - 1;
+ _node_idx[_lvl] = _attr.in_out_ft.degree - 1;
if (_lvl)
_t1_blks[_lvl].decode_from_blk(_blk);
else
@@ -223,31 +150,31 @@ void Free_tree_channel::_alloc_pbas(bool &progress)
}
case SEEK_LEFT_OR_UP:
- if (_lvl < req._ft.max_lvl) {
- if (_node_idx[_lvl] && _num_pbas < _req_ptr->_num_required_pbas) {
+ if (_lvl < _attr.in_out_ft.max_lvl) {
+ if (_node_idx[_lvl] && _num_pbas < _attr.in_num_required_pbas) {
_node_idx[_lvl]--;
_traverse_curr_node(progress);
} else {
_lvl++;
Type_1_node &t1_node { _t1_blks[_lvl].nodes[_node_idx[_lvl]] };
if (_apply_allocation)
- if (t1_node.is_volatile(req._curr_gen)) {
- _state = WRITE_BLK;
+ if (t1_node.is_volatile(_attr.in_curr_gen)) {
+ _helper.state = ALLOC_PBA_SUCCEEDED;
progress = true;
} else
- _generate_req(WRITE_BLK, progress, req._mt, req._curr_gen, t1_node.pba);
+ _allocate_pba.generate(_helper, ALLOC_PBA, ALLOC_PBA_SUCCEEDED, progress, _attr.in_out_mt, _attr.in_curr_gen, t1_node.pba);
else {
- _state = SEEK_LEFT_OR_UP;
+ _helper.state = SEEK_LEFT_OR_UP;
progress = true;
}
}
} else {
if (_apply_allocation) {
- req._ft.t1_node(_t1_blks[_lvl].nodes[_node_idx[_lvl]]);
- _mark_req_successful(progress);
+ _attr.in_out_ft.t1_node(_t1_blks[_lvl].nodes[_node_idx[_lvl]]);
+ _helper.mark_succeeded(progress);
} else {
- if (_num_pbas < req._num_required_pbas)
- _mark_req_failed(progress, "not enough free pbas");
+ if (_num_pbas < _attr.in_num_required_pbas)
+ _helper.mark_failed(progress, "not enough free pbas");
else {
_apply_allocation = true;
_start_tree_traversal(progress);
@@ -256,68 +183,55 @@ void Free_tree_channel::_alloc_pbas(bool &progress)
}
break;
- case WRITE_BLK:
+ case ALLOC_PBA: progress |= _allocate_pba.execute(meta_tree, block_io); break;
+ case ALLOC_PBA_SUCCEEDED:
{
if (_lvl > 1)
_t1_blks[_lvl - 1].encode_to_blk(_blk);
else
_t2_blk.encode_to_blk(_blk);
Type_1_node &t1_node { _t1_blks[_lvl].nodes[_node_idx[_lvl]] };
- t1_node.gen = req._curr_gen;
+ t1_node.gen = _attr.in_curr_gen;
calc_hash(_blk, t1_node.hash);
- _generate_req(SEEK_LEFT_OR_UP, progress, t1_node.pba, _blk);
+ _write_block.generate(_helper, WRITE_BLK, SEEK_LEFT_OR_UP, progress, t1_node.pba, _blk);
break;
}
+ case WRITE_BLK: progress |= _write_block.execute(block_io); break;
default: break;
}
+ return progress;
}
-void Free_tree_channel::execute(bool &progress)
-{
- if (!_req_ptr)
- return;
-
- switch(_req_ptr->_type) {
- case Request::ALLOC_FOR_NON_RKG:
- case Request::ALLOC_FOR_RKG_CURR_GEN_BLKS:
- case Request::ALLOC_FOR_RKG_OLD_GEN_BLKS: _alloc_pbas(progress); break;
- case Request::EXTENSION_STEP: _extension_step(progress); break;
- }
-}
-
-
-void Free_tree_channel::_generate_write_blk_req(bool &progress)
+void Free_tree::Extend_tree::_generate_write_blk_req(bool &progress)
{
if (_lvl > 1)
_t1_blks[_lvl].encode_to_blk(_blk);
else
_t2_blk.encode_to_blk(_blk);
- _generate_req(WRITE_BLK_SUCCEEDED, progress, _new_pbas.pbas[_lvl], _blk);
+ _write_block.generate(_helper, WRITE_BLK, WRITE_BLK_SUCCEEDED, progress, _new_pbas.pbas[_lvl], _blk);
if (VERBOSE_FT_EXTENSION)
log(" lvl ", _lvl, " write to pba ", _new_pbas.pbas[_lvl]);
}
-void Free_tree_channel::_add_new_root_lvl()
+void Free_tree::Extend_tree::_add_new_root_lvl()
{
- Request &req { *_req_ptr };
- ASSERT(req._ft.max_lvl < TREE_MAX_LEVEL);
- req._ft.max_lvl++;
- _t1_blks[req._ft.max_lvl] = { };
- _t1_blks[req._ft.max_lvl].nodes[0] = req._ft.t1_node();
- _new_pbas.pbas[req._ft.max_lvl] = alloc_pba_from_range(req._pba, req._num_pbas);
- req._ft.t1_node({ _new_pbas.pbas[req._ft.max_lvl], req._curr_gen });
+ ASSERT(_attr.in_out_ft.max_lvl < TREE_MAX_LEVEL);
+ _attr.in_out_ft.max_lvl++;
+ _t1_blks[_attr.in_out_ft.max_lvl] = { };
+ _t1_blks[_attr.in_out_ft.max_lvl].nodes[0] = _attr.in_out_ft.t1_node();
+ _new_pbas.pbas[_attr.in_out_ft.max_lvl] = alloc_pba_from_range(_attr.in_out_first_pba, _attr.in_out_num_pbas);
+ _attr.in_out_ft.t1_node({ _new_pbas.pbas[_attr.in_out_ft.max_lvl], _attr.in_curr_gen });
if (VERBOSE_FT_EXTENSION)
- log(" set root: ", req._ft, "\n set lvl ", req._ft.max_lvl, " node 0: ",
- _t1_blks[req._ft.max_lvl].nodes[0]);
+ log(" set root: ", _attr.in_out_ft, "\n set lvl ", _attr.in_out_ft.max_lvl, " node 0: ",
+ _t1_blks[_attr.in_out_ft.max_lvl].nodes[0]);
}
-void Free_tree_channel::_add_new_branch_at(Tree_level_index dst_lvl, Tree_node_index dst_node_idx)
+void Free_tree::Extend_tree::_add_new_branch_at(Tree_level_index dst_lvl, Tree_node_index dst_node_idx)
{
- Request &req { *_req_ptr };
_num_leaves = 0;
_lvl = dst_lvl;
if (dst_lvl > 1) {
@@ -331,17 +245,17 @@ void Free_tree_channel::_add_new_branch_at(Tree_level_index dst_lvl, Tree_node_i
log(" reset lvl ", lvl);
}
}
- for (; _lvl && req._num_pbas; _lvl--) {
+ for (; _lvl && _attr.in_out_num_pbas; _lvl--) {
Tree_node_index node_idx = (_lvl == dst_lvl) ? dst_node_idx : 0;
if (_lvl > 1) {
- _new_pbas.pbas[_lvl - 1] = alloc_pba_from_range(req._pba, req._num_pbas);
- _t1_blks[_lvl].nodes[node_idx] = { _new_pbas.pbas[_lvl - 1], req._curr_gen };
+ _new_pbas.pbas[_lvl - 1] = alloc_pba_from_range(_attr.in_out_first_pba, _attr.in_out_num_pbas);
+ _t1_blks[_lvl].nodes[node_idx] = { _new_pbas.pbas[_lvl - 1], _attr.in_curr_gen };
if (VERBOSE_FT_EXTENSION)
log(" set _lvl d ", _lvl, " node ", node_idx, ": ", _t1_blks[_lvl].nodes[node_idx]);
} else {
- for (; node_idx < req._ft.degree && req._num_pbas; node_idx++) {
- _t2_blk.nodes[node_idx] = { alloc_pba_from_range(req._pba, req._num_pbas) };
+ for (; node_idx < _attr.in_out_ft.degree && _attr.in_out_num_pbas; node_idx++) {
+ _t2_blk.nodes[node_idx] = { alloc_pba_from_range(_attr.in_out_first_pba, _attr.in_out_num_pbas) };
_num_leaves++;
if (VERBOSE_FT_EXTENSION)
log(" set _lvl e ", _lvl, " node ", node_idx, ": ", _t2_blk.nodes[node_idx]);
@@ -353,80 +267,80 @@ void Free_tree_channel::_add_new_branch_at(Tree_level_index dst_lvl, Tree_node_i
}
-void Free_tree_channel::_extension_step(bool &progress)
+bool Free_tree::Extend_tree::execute(Block_io &block_io, Meta_tree &meta_tree)
{
- Request &req { *_req_ptr };
- switch (_state) {
- case REQ_SUBMITTED:
+ bool progress = false;
+ switch (_helper.state) {
+ case INIT:
_num_leaves = 0;
- _vba = req._ft.num_leaves;
+ _vba = _attr.in_out_ft.num_leaves;
_old_pbas = { };
_old_generations = { };
_new_pbas = { };
- _lvl = req._ft.max_lvl;
- _old_pbas.pbas[_lvl] = req._ft.pba;
- _old_generations.items[_lvl] = req._ft.gen;
- if (_vba <= tree_max_max_vba(req._ft.degree, req._ft.max_lvl)) {
+ _lvl = _attr.in_out_ft.max_lvl;
+ _old_pbas.pbas[_lvl] = _attr.in_out_ft.pba;
+ _old_generations.items[_lvl] = _attr.in_out_ft.gen;
+ if (_vba <= tree_max_max_vba(_attr.in_out_ft.degree, _attr.in_out_ft.max_lvl)) {
- _generate_req(READ_BLK_SUCCEEDED, progress, req._ft.pba, _blk);
+ _read_block.generate(_helper, READ_BLK, READ_BLK_SUCCEEDED, progress, _attr.in_out_ft.pba, _blk);
if (VERBOSE_FT_EXTENSION)
- log(" root (", req._ft, "): load to lvl ", _lvl);
+ log(" root (", _attr.in_out_ft, "): load to lvl ", _lvl);
} else {
_add_new_root_lvl();
- _add_new_branch_at(req._ft.max_lvl, 1);
+ _add_new_branch_at(_attr.in_out_ft.max_lvl, 1);
_generate_write_blk_req(progress);
if (VERBOSE_FT_EXTENSION)
- log(" pbas allocated: curr gen ", req._curr_gen);
+ log(" pbas allocated: curr gen ", _attr.in_curr_gen);
}
break;
+ case READ_BLK: progress |= _read_block.execute(block_io); break;
case READ_BLK_SUCCEEDED:
if (_lvl > 1) {
_t1_blks[_lvl].decode_from_blk(_blk);
- if (_lvl < req._ft.max_lvl) {
- Tree_node_index node_idx = t1_node_idx_for_vba(_vba, _lvl + 1, req._ft.degree);
+ if (_lvl < _attr.in_out_ft.max_lvl) {
+ Tree_node_index node_idx = tree_node_index(_vba, _lvl + 1, _attr.in_out_ft.degree);
if (!check_hash(_blk, _t1_blks[_lvl + 1].nodes[node_idx].hash))
- _mark_req_failed(progress, "hash mismatch");
+ _helper.mark_failed(progress, "hash mismatch");
} else
- if (!check_hash(_blk, req._ft.hash))
- _mark_req_failed(progress, "hash mismatch");
+ if (!check_hash(_blk, _attr.in_out_ft.hash))
+ _helper.mark_failed(progress, "hash mismatch");
- Tree_node_index node_idx = t1_node_idx_for_vba(_vba, _lvl, req._ft.degree);
+ Tree_node_index node_idx = tree_node_index(_vba, _lvl, _attr.in_out_ft.degree);
Type_1_node &t1_node = _t1_blks[_lvl].nodes[node_idx];
if (t1_node.valid()) {
_lvl--;
_old_pbas.pbas [_lvl] = t1_node.pba;
_old_generations.items[_lvl] = t1_node.gen;
- _generate_req(READ_BLK_SUCCEEDED, progress, t1_node.pba, _blk);
+ _read_block.generate(_helper, READ_BLK, READ_BLK_SUCCEEDED, progress, t1_node.pba, _blk);
if (VERBOSE_FT_EXTENSION)
log(" lvl ", _lvl + 1, " node ", node_idx, " (", t1_node, "): load to lvl ", _lvl);
} else {
_alloc_lvl = _lvl;
_add_new_branch_at(_lvl, node_idx);
- if (_old_generations.items[_alloc_lvl] == req._curr_gen) {
+ if (_old_generations.items[_alloc_lvl] == _attr.in_curr_gen) {
_alloc_pba = _old_pbas.pbas[_alloc_lvl];
- _state = ALLOC_PBA_SUCCEEDED;
+ _helper.state = ALLOC_PBA_SUCCEEDED;
progress = true;
} else {
_alloc_pba = _old_pbas.pbas[_alloc_lvl];
- _generate_req(
- ALLOC_PBA_SUCCEEDED, progress, Meta_tree_request::ALLOC_PBA, req._mt, req._curr_gen, _alloc_pba);
+ _allocate_pba.generate(_helper, ALLOC_PBA, ALLOC_PBA_SUCCEEDED, progress, _attr.in_out_mt, _attr.in_curr_gen, _alloc_pba);
}
}
} else {
_t2_blk.decode_from_blk(_blk);
- Tree_node_index t1_node_idx = t1_node_idx_for_vba(_vba, _lvl + 1, req._ft.degree);
+ Tree_node_index t1_node_idx = tree_node_index(_vba, _lvl + 1, _attr.in_out_ft.degree);
if (!check_hash(_blk, _t1_blks[_lvl + 1].nodes[t1_node_idx].hash))
- _mark_req_failed(progress, "hash mismatch");
+ _helper.mark_failed(progress, "hash mismatch");
- Tree_node_index t2_node_idx = t2_node_idx_for_vba(_vba, req._ft.degree);
+ Tree_node_index t2_node_idx = tree_node_index(_vba, _lvl, _attr.in_out_ft.degree);
if (_t2_blk.nodes[t2_node_idx].valid())
- _mark_req_failed(progress, "t2 node valid");
+ _helper.mark_failed(progress, "t2 node valid");
_add_new_branch_at(_lvl, t2_node_idx);
_alloc_lvl = _lvl;
@@ -434,41 +348,41 @@ void Free_tree_channel::_extension_step(bool &progress)
log(" alloc lvl ", _alloc_lvl);
_alloc_pba = _old_pbas.pbas[_alloc_lvl];
- _generate_req(
- ALLOC_PBA_SUCCEEDED, progress, Meta_tree_request::ALLOC_PBA, req._mt, req._curr_gen, _alloc_pba);
+ _allocate_pba.generate(_helper, ALLOC_PBA, ALLOC_PBA_SUCCEEDED, progress, _attr.in_out_mt, _attr.in_curr_gen, _alloc_pba);
}
break;
+ case ALLOC_PBA: progress |= _allocate_pba.execute(meta_tree, block_io); break;
case ALLOC_PBA_SUCCEEDED:
_new_pbas.pbas[_alloc_lvl] = _alloc_pba;
- if (_alloc_lvl < req._ft.max_lvl) {
+ if (_alloc_lvl < _attr.in_out_ft.max_lvl) {
_alloc_lvl++;
- if (_old_generations.items[_alloc_lvl] == req._curr_gen) {
+ if (_old_generations.items[_alloc_lvl] == _attr.in_curr_gen) {
_alloc_pba = _old_pbas.pbas[_alloc_lvl];
- _state = ALLOC_PBA_SUCCEEDED;
+ _helper.state = ALLOC_PBA_SUCCEEDED;
progress = true;
} else {
_alloc_pba = _old_pbas.pbas[_alloc_lvl];
- _generate_req(
- ALLOC_PBA_SUCCEEDED, progress, Meta_tree_request::ALLOC_PBA, req._mt, req._curr_gen, _alloc_pba);
+ _allocate_pba.generate(_helper, ALLOC_PBA, ALLOC_PBA_SUCCEEDED, progress, _attr.in_out_mt, _attr.in_curr_gen, _alloc_pba);
}
} else {
_generate_write_blk_req(progress);
if (VERBOSE_FT_EXTENSION)
- log(" pbas allocated: curr gen ", req._curr_gen);
+ log(" pbas allocated: curr gen ", _attr.in_curr_gen);
}
break;
+ case WRITE_BLK: progress |= _write_block.execute(block_io); break;
case WRITE_BLK_SUCCEEDED:
- if (_lvl < req._ft.max_lvl) {
+ if (_lvl < _attr.in_out_ft.max_lvl) {
if (_lvl > 1) {
- Tree_node_index node_idx = t1_node_idx_for_vba(_vba, _lvl + 1, req._ft.degree);
+ Tree_node_index node_idx = tree_node_index(_vba, _lvl + 1, _attr.in_out_ft.degree);
Type_1_node &t1_node { _t1_blks[_lvl + 1].nodes[node_idx] };
- t1_node = { _new_pbas.pbas[_lvl], req._curr_gen };
+ t1_node = { _new_pbas.pbas[_lvl], _attr.in_curr_gen };
calc_hash(_blk, t1_node.hash);
if (VERBOSE_FT_EXTENSION)
log(" set lvl ", _lvl + 1, " node ", node_idx, ": ", t1_node);
@@ -476,9 +390,9 @@ void Free_tree_channel::_extension_step(bool &progress)
_lvl++;
_generate_write_blk_req(progress);
} else {
- Tree_node_index node_idx = t1_node_idx_for_vba(_vba, _lvl + 1, req._ft.degree);
+ Tree_node_index node_idx = tree_node_index(_vba, _lvl + 1, _attr.in_out_ft.degree);
Type_1_node &t1_node = _t1_blks[_lvl + 1].nodes[node_idx];
- t1_node = { _new_pbas.pbas[_lvl], req._curr_gen };
+ t1_node = { _new_pbas.pbas[_lvl], _attr.in_curr_gen };
calc_hash(_blk, t1_node.hash);
if (VERBOSE_FT_EXTENSION)
log(" set lvl ", _lvl + 1, " t1_node ", node_idx, ": ", t1_node);
@@ -487,30 +401,14 @@ void Free_tree_channel::_extension_step(bool &progress)
_generate_write_blk_req(progress);
}
} else {
- req._ft.t1_node({ _new_pbas.pbas[_lvl], req._curr_gen });
- calc_hash(_blk, req._ft.hash);
- req._ft.num_leaves += _num_leaves;
- _mark_req_successful(progress);
+ _attr.in_out_ft.t1_node({ _new_pbas.pbas[_lvl], _attr.in_curr_gen });
+ calc_hash(_blk, _attr.in_out_ft.hash);
+ _attr.in_out_ft.num_leaves += _num_leaves;
+ _helper.mark_succeeded(progress);
}
break;
default: break;
}
-}
-
-
-void Free_tree_channel::_request_submitted(Module_request &mod_req)
-{
- _req_ptr = static_cast(&mod_req);
- _state = REQ_SUBMITTED;
-}
-
-
-Free_tree::Free_tree()
-{
- Module_channel_id id { 0 };
- for (Constructible &chan : _channels) {
- chan.construct(id++);
- add_channel(*chan);
- }
+ return progress;
}
diff --git a/repos/gems/src/lib/tresor/ft_check.cc b/repos/gems/src/lib/tresor/ft_check.cc
index ce24a19097..388b2a1634 100644
--- a/repos/gems/src/lib/tresor/ft_check.cc
+++ b/repos/gems/src/lib/tresor/ft_check.cc
@@ -13,73 +13,66 @@
/* tresor includes */
#include
-#include
#include
using namespace Tresor;
-Ft_check_request::Ft_check_request(Module_id src_mod, Module_channel_id src_chan, Tree_root const &ft, bool &success)
-:
- Module_request { src_mod, src_chan, FT_CHECK }, _ft { ft }, _success { success }
-{ }
-
-
-bool Ft_check_channel::_execute_node(Tree_level_index lvl, Tree_node_index node_idx, bool &progress)
+bool Ft_check::Check::_execute_node(Block_io &block_io, Tree_level_index lvl, Tree_node_index node_idx, bool &progress)
{
bool &check_node { _check_node[lvl][node_idx] };
if (check_node == false)
return false;
- Request &req { *_req_ptr };
- switch (_state) {
- case REQ_IN_PROGRESS:
+ switch (_helper.state) {
+ case IN_PROGRESS:
if (lvl == 1) {
Type_2_node const &node { _t2_blk.nodes[node_idx] };
if (!_num_remaining_leaves) {
if (node.valid()) {
- _mark_req_failed(progress, { "lvl ", lvl, " node ", node_idx, " (", node,
- ") valid but no leaves remaining" });
+ _helper.mark_failed(progress, { "lvl ", lvl, " node ", node_idx, " (", node,
+ ") valid but no leaves remaining" });
break;
}
check_node = false;
progress = true;
if (VERBOSE_CHECK)
- log(Level_indent { lvl, req._ft.max_lvl }, " lvl ", lvl, " node ", node_idx, " unused");
+ log(Level_indent { lvl, _attr.in_ft.max_lvl }, " lvl ", lvl, " node ", node_idx, " unused");
break;
}
_num_remaining_leaves--;
check_node = false;
progress = true;
if (VERBOSE_CHECK)
- log(Level_indent { lvl, req._ft.max_lvl }, " lvl ", lvl, " node ", node_idx, " done");
+ log(Level_indent { lvl, _attr.in_ft.max_lvl }, " lvl ", lvl, " node ", node_idx, " done");
} else {
Type_1_node const &node { _t1_blks.items[lvl].nodes[node_idx] };
if (!node.valid()) {
if (_num_remaining_leaves) {
- _mark_req_failed(progress, { "lvl ", lvl, " node ", node_idx, " invalid but ",
- _num_remaining_leaves, " leaves remaining" });
+ _helper.mark_failed(progress, { "lvl ", lvl, " node ", node_idx, " invalid but ",
+ _num_remaining_leaves, " leaves remaining" });
break;
}
check_node = false;
progress = true;
if (VERBOSE_CHECK)
- log(Level_indent { lvl, req._ft.max_lvl }, " lvl ", lvl, " node ", node_idx, " unused");
+ log(Level_indent { lvl, _attr.in_ft.max_lvl }, " lvl ", lvl, " node ", node_idx, " unused");
break;
}
- _generate_req(READ_BLK_SUCCEEDED, progress, node.pba, _blk);
+ _read_block.generate(_helper, READ_BLK, READ_BLK_SUCCEEDED, progress, node.pba, _blk);
if (VERBOSE_CHECK)
- log(Level_indent { lvl, req._ft.max_lvl }, " lvl ", lvl, " node ", node_idx,
+ log(Level_indent { lvl, _attr.in_ft.max_lvl }, " lvl ", lvl, " node ", node_idx,
" (", node, "): load to lvl ", lvl - 1);
}
break;
+ case READ_BLK: progress |= _read_block.execute(block_io); break;
case READ_BLK_SUCCEEDED:
{
Type_1_node const &node { _t1_blks.items[lvl].nodes[node_idx] };
if (node.gen != INITIAL_GENERATION && !check_hash(_blk, node.hash)) {
- _mark_req_failed(progress, { "lvl ", lvl, " node ", node_idx, " (", node, ") has bad hash" });
+ _helper.mark_failed(progress, { "lvl ", lvl, " node ", node_idx, " (", node, ") has bad hash" });
break;
}
if (lvl == 2)
@@ -89,11 +82,11 @@ bool Ft_check_channel::_execute_node(Tree_level_index lvl, Tree_node_index node_
for (bool &cn : _check_node[lvl - 1])
cn = true;
- _state = REQ_IN_PROGRESS;
+ _helper.state = IN_PROGRESS;
check_node = false;
progress = true;
if (VERBOSE_CHECK)
- log(Level_indent { lvl, req._ft.max_lvl }, " lvl ", lvl, " node ", node_idx, " has good hash");
+ log(Level_indent { lvl, _attr.in_ft.max_lvl }, " lvl ", lvl, " node ", node_idx, " has good hash");
break;
}
default: break;
@@ -102,81 +95,24 @@ bool Ft_check_channel::_execute_node(Tree_level_index lvl, Tree_node_index node_
}
-void Ft_check_channel::execute(bool &progress)
+bool Ft_check::Check::execute(Block_io &block_io)
{
- if (!_req_ptr)
- return;
-
- if (_state == REQ_SUBMITTED) {
- for (Tree_level_index lvl { 1 }; lvl <= _req_ptr->_ft.max_lvl + 1; lvl++)
- for (Tree_node_index node_idx { 0 }; node_idx < _req_ptr->_ft.degree; node_idx++)
+ bool progress = false;
+ if (_helper.state == INIT) {
+ for (Tree_level_index lvl { 1 }; lvl <= _attr.in_ft.max_lvl + 1; lvl++)
+ for (Tree_node_index node_idx { 0 }; node_idx < _attr.in_ft.degree; node_idx++)
_check_node[lvl][node_idx] = false;
- _num_remaining_leaves = _req_ptr->_ft.num_leaves;
- _t1_blks.items[_req_ptr->_ft.max_lvl + 1].nodes[0] = _req_ptr->_ft.t1_node();
- _check_node[_req_ptr->_ft.max_lvl + 1][0] = true;
- _state = REQ_IN_PROGRESS;
+ _num_remaining_leaves = _attr.in_ft.num_leaves;
+ _t1_blks.items[_attr.in_ft.max_lvl + 1].nodes[0] = _attr.in_ft.t1_node();
+ _check_node[_attr.in_ft.max_lvl + 1][0] = true;
+ _helper.state = IN_PROGRESS;
}
- for (Tree_level_index lvl { 1 }; lvl <= _req_ptr->_ft.max_lvl + 1; lvl++)
- for (Tree_node_index node_idx { 0 }; node_idx < _req_ptr->_ft.degree; node_idx++)
- if (_execute_node(lvl, node_idx, progress))
- return;
+ for (Tree_level_index lvl { 1 }; lvl <= _attr.in_ft.max_lvl + 1; lvl++)
+ for (Tree_node_index node_idx { 0 }; node_idx < _attr.in_ft.degree; node_idx++)
+ if (_execute_node(block_io, lvl, node_idx, progress))
+ return progress;
- _mark_req_successful(progress);
-}
-
-
-void Ft_check_channel::_generated_req_completed(State_uint state_uint)
-{
- if (!_generated_req_success) {
- error("ft check: request (", *_req_ptr, ") failed because generated request failed)");
- _req_ptr->_success = false;
- _state = REQ_COMPLETE;
- _req_ptr = nullptr;
- return;
- }
- _state = (State)state_uint;
-}
-
-
-void Ft_check_channel::_mark_req_failed(bool &progress, Error_string str)
-{
- error("ft check request (", *_req_ptr, ") failed: ", str);
- _req_ptr->_success = false;
- _state = REQ_COMPLETE;
- _req_ptr = nullptr;
- progress = true;
-}
-
-
-void Ft_check_channel::_mark_req_successful(bool &progress)
-{
- _req_ptr->_success = true;
- _state = REQ_COMPLETE;
- _req_ptr = nullptr;
- progress = true;
-}
-
-
-void Ft_check_channel::_request_submitted(Module_request &mod_req)
-{
- _req_ptr = static_cast(&mod_req);
- _state = REQ_SUBMITTED;
-}
-
-
-Ft_check::Ft_check()
-{
- Module_channel_id id { 0 };
- for (Constructible &chan : _channels) {
- chan.construct(id++);
- add_channel(*chan);
- }
-}
-
-
-void Ft_check::execute(bool &progress)
-{
- for_each_channel([&] (Channel &chan) {
- chan.execute(progress); });
+ _helper.mark_succeeded(progress);
+ return progress;
}
diff --git a/repos/gems/src/lib/tresor/ft_initializer.cc b/repos/gems/src/lib/tresor/ft_initializer.cc
index e092ba7a28..55da497e74 100644
--- a/repos/gems/src/lib/tresor/ft_initializer.cc
+++ b/repos/gems/src/lib/tresor/ft_initializer.cc
@@ -13,20 +13,67 @@
*/
/* tresor includes */
-#include
#include
#include
using namespace Tresor;
-Ft_initializer_request::Ft_initializer_request(Module_id src_mod, Module_channel_id src_chan,
- Tree_root &ft, Pba_allocator &pba_alloc, bool &success)
-:
- Module_request { src_mod, src_chan, FT_INITIALIZER }, _ft { ft }, _pba_alloc { pba_alloc }, _success { success }
-{ }
+void Ft_initializer::Initialize::_reset_level(Tree_level_index lvl, Node_state node_state)
+{
+ if (lvl == 1)
+ for (Tree_node_index idx = 0; idx < NUM_NODES_PER_BLK; idx++) {
+ _t2_blk.nodes[idx] = { };
+ _t2_node_states[idx] = node_state;
+ }
+ else
+ for (Tree_node_index idx = 0; idx < NUM_NODES_PER_BLK; idx++) {
+ _t1_blks.items[lvl].nodes[idx] = { };
+ _t1_node_states[lvl][idx] = node_state;
+ }
+}
-bool Ft_initializer_channel::_execute_t2_node(Tree_node_index node_idx, bool &progress)
+bool Ft_initializer::Initialize::execute(Block_io &block_io)
+{
+ bool progress = false;
+ switch (_helper.state) {
+ case INIT:
+
+ _num_remaining_leaves = _attr.in_tree_cfg.num_leaves;
+ for (Tree_level_index lvl = 0; lvl < TREE_MAX_LEVEL; lvl++)
+ _reset_level(lvl, DONE);
+
+ _t1_node_states[_attr.in_tree_cfg.max_lvl + 1][0] = INIT_BLOCK;
+ _helper.state = EXECUTE_NODES;
+ progress = true;
+ break;
+
+ case EXECUTE_NODES:
+
+ for (Tree_node_index node_idx = 0; node_idx < _attr.in_tree_cfg.degree; node_idx++)
+ if (_execute_t2_node(node_idx, progress))
+ return progress;
+
+ for (Tree_level_index lvl = 1; lvl <= _attr.in_tree_cfg.max_lvl + 1; lvl++)
+ for (Tree_node_index node_idx = 0; node_idx < _attr.in_tree_cfg.degree; node_idx++)
+ if (_execute_t1_node(lvl, node_idx, progress))
+ return progress;
+
+ if (_num_remaining_leaves)
+ _helper.mark_failed(progress, "leaves remaining");
+ else {
+ _attr.out_tree_root = _t1_blks.items[_attr.in_tree_cfg.max_lvl + 1].nodes[0];
+ _helper.mark_succeeded(progress);
+ }
+ break;
+
+ case WRITE_BLOCK: progress |= _write_block.execute(block_io); break;
+ default: break;;
+ }
+ return progress;
+}
+
+bool Ft_initializer::Initialize::_execute_t2_node(Tree_node_index node_idx, bool &progress)
{
Node_state &node_state { _t2_node_states[node_idx] };
Type_2_node &node { _t2_blk.nodes[node_idx] };
@@ -42,8 +89,8 @@ bool Ft_initializer_channel::_execute_t2_node(Tree_node_index node_idx, bool &pr
if (_num_remaining_leaves) {
node = { };
- if (!_req_ptr->_pba_alloc.alloc(node.pba)) {
- _mark_req_failed(progress, "allocate pba");
+ if (!_attr.in_out_pba_alloc.alloc(node.pba)) {
+ _helper.mark_failed(progress, "allocate pba");
break;
}
node_state = DONE;
@@ -60,13 +107,13 @@ bool Ft_initializer_channel::_execute_t2_node(Tree_node_index node_idx, bool &pr
}
break;
- case WRITE_BLK: ASSERT_NEVER_REACHED;
+ case WRITING_BLOCK: ASSERT_NEVER_REACHED;
}
return true;
}
-bool Ft_initializer_channel::_execute_t1_node(Tree_level_index lvl, Tree_node_index node_idx, bool &progress)
+bool Ft_initializer::Initialize::_execute_t1_node(Tree_level_index lvl, Tree_node_index node_idx, bool &progress)
{
Type_1_node &node { _t1_blks.items[lvl].nodes[node_idx] };
Node_state &node_state { _t1_node_states[lvl][node_idx] };
@@ -92,8 +139,8 @@ bool Ft_initializer_channel::_execute_t1_node(Tree_level_index lvl, Tree_node_in
case INIT_NODE:
{
node = { };
- if (!_req_ptr->_pba_alloc.alloc(node.pba)) {
- _mark_req_failed(progress, "allocate pba");
+ if (!_attr.in_out_pba_alloc.alloc(node.pba)) {
+ _helper.mark_failed(progress, "allocate pba");
break;
}
if (lvl == 2)
@@ -101,15 +148,13 @@ bool Ft_initializer_channel::_execute_t1_node(Tree_level_index lvl, Tree_node_in
else
_t1_blks.items[lvl - 1].encode_to_blk(_blk);
calc_hash(_blk, node.hash);
- generate_req(EXECUTE_NODES, progress, node.pba, _blk, _generated_req_success);
- _state = REQ_GENERATED;
- node_state = WRITE_BLK;
- progress = true;
+ _write_block.generate(_helper, WRITE_BLOCK, EXECUTE_NODES, progress, node.pba, _blk);
+ node_state = WRITING_BLOCK;
if (VERBOSE_FT_INIT)
log("[ft_init] node: ", lvl, " ", node_idx, " assign pba: ", node.pba);
break;
}
- case WRITE_BLK:
+ case WRITING_BLOCK:
node_state = DONE;
progress = true;
@@ -119,115 +164,3 @@ bool Ft_initializer_channel::_execute_t1_node(Tree_level_index lvl, Tree_node_in
}
return true;
}
-
-
-void Ft_initializer_channel::_generated_req_completed(State_uint state_uint)
-{
- if (!_generated_req_success) {
- error("ft initializer request (", *_req_ptr, ") failed because generated request failed");
- _req_ptr->_success = false;
- _state = REQ_COMPLETE;
- _req_ptr = nullptr;
- return;
- }
- _state = (State)state_uint;
-}
-
-
-void Ft_initializer_channel::_mark_req_failed(bool &progress, char const *str)
-{
- error("ft initializer request (", *_req_ptr, ") failed because: ", str);
- _req_ptr->_success = false;
- _state = REQ_COMPLETE;
- _req_ptr = nullptr;
- progress = true;
-}
-
-
-void Ft_initializer_channel::_mark_req_successful(bool &progress)
-{
- _req_ptr->_ft.t1_node(_t1_blks.items[_req_ptr->_ft.max_lvl + 1].nodes[0]);
- _req_ptr->_success = true;
- _state = REQ_COMPLETE;
- _req_ptr = nullptr;
- progress = true;
-}
-
-
-void Ft_initializer_channel::_reset_level(Tree_level_index lvl, Node_state node_state)
-{
- if (lvl == 1)
- for (Tree_node_index idx = 0; idx < NUM_NODES_PER_BLK; idx++) {
- _t2_blk.nodes[idx] = { };
- _t2_node_states[idx] = node_state;
- }
- else
- for (Tree_node_index idx = 0; idx < NUM_NODES_PER_BLK; idx++) {
- _t1_blks.items[lvl].nodes[idx] = { };
- _t1_node_states[lvl][idx] = node_state;
- }
-}
-
-
-void Ft_initializer_channel::execute(bool &progress)
-{
- if (!_req_ptr)
- return;
-
- Request &req { *_req_ptr };
- switch (_state) {
- case REQ_SUBMITTED:
-
- _num_remaining_leaves = req._ft.num_leaves;
- for (Tree_level_index lvl = 0; lvl < TREE_MAX_LEVEL; lvl++)
- _reset_level(lvl, DONE);
-
- _t1_node_states[req._ft.max_lvl + 1][0] = INIT_BLOCK;
- _state = EXECUTE_NODES;
- progress = true;
- return;
-
- case EXECUTE_NODES:
-
- for (Tree_node_index node_idx = 0; node_idx < req._ft.degree; node_idx++)
- if (_execute_t2_node(node_idx, progress))
- return;
-
- for (Tree_level_index lvl = 1; lvl <= req._ft.max_lvl + 1; lvl++)
- for (Tree_node_index node_idx = 0; node_idx < req._ft.degree; node_idx++)
- if (_execute_t1_node(lvl, node_idx, progress))
- return;
-
- if (_num_remaining_leaves)
- _mark_req_failed(progress, "leaves remaining");
- else
- _mark_req_successful(progress);
- return;
-
- default: return;
- }
-}
-
-
-void Ft_initializer_channel::_request_submitted(Module_request &mod_req)
-{
- _req_ptr = static_cast(&mod_req);
- _state = REQ_SUBMITTED;
-}
-
-
-Ft_initializer::Ft_initializer()
-{
- Module_channel_id id { 0 };
- for (Constructible &chan : _channels) {
- chan.construct(id++);
- add_channel(*chan);
- }
-}
-
-
-void Ft_initializer::execute(bool &progress)
-{
- for_each_channel([&] (Channel &chan) {
- chan.execute(progress); });
-}
diff --git a/repos/gems/src/lib/tresor/include/tresor/block_io.h b/repos/gems/src/lib/tresor/include/tresor/block_io.h
index 7da5c7cb3d..732c62aeb8 100644
--- a/repos/gems/src/lib/tresor/include/tresor/block_io.h
+++ b/repos/gems/src/lib/tresor/include/tresor/block_io.h
@@ -18,147 +18,132 @@
#include
#include
-namespace Tresor {
+namespace Tresor { class Block_io; }
- class Block_io;
- class Block_io_request;
- class Block_io_channel;
-}
-
-class Tresor::Block_io_request : public Module_request
-{
- friend class Block_io_channel;
-
- public:
-
- enum Type { READ, WRITE, SYNC, READ_CLIENT_DATA, WRITE_CLIENT_DATA };
-
- private:
-
- Type const _type;
- Request_offset const _client_req_offset;
- Request_tag const _client_req_tag;
- Key_id const _key_id;
- Physical_block_address const _pba;
- Virtual_block_address const _vba;
- Block &_blk;
- Hash &_hash;
- bool &_success;
-
- NONCOPYABLE(Block_io_request);
-
- public:
-
- Block_io_request(Module_id, Module_channel_id, Type, Request_offset, Request_tag, Key_id,
- Physical_block_address, Virtual_block_address, Block &, Hash &, bool &);
-
- static char const *type_to_string(Type);
-
- void print(Output &out) const override { Genode::print(out, type_to_string(_type), " pba ", _pba); }
-};
-
-class Tresor::Block_io_channel : public Module_channel
+class Tresor::Block_io : Noncopyable
{
private:
- using Request = Block_io_request;
+ Vfs::Vfs_handle &_file;
+ addr_t _user { };
- enum State {
- REQ_SUBMITTED, REQ_COMPLETE, CIPHERTEXT_BLK_OBTAINED, PLAINTEXT_BLK_SUPPLIED, REQ_GENERATED,
- READ_OK, WRITE_OK, SYNC_OK, FILE_ERR };
+ public:
- State _state { REQ_COMPLETE };
- Block _blk { };
- bool _generated_req_success { false };
- Block_io_request *_req_ptr { };
- Vfs::Env &_vfs_env;
- Tresor::Path const _path;
- Read_write_file _file { _state, _vfs_env, _path };
+ class Read;
+ class Write;
+ class Sync;
- NONCOPYABLE(Block_io_channel);
+ Block_io(Vfs::Vfs_handle &file) : _file(file) { }
- void _generated_req_completed(State_uint) override;
-
- template
- void _generate_req(State_uint state, bool &progress, ARGS &&... args)
+ template
+ bool execute(REQ &req)
{
- _state = REQ_GENERATED;
- generate_req(state, progress, args..., _generated_req_success);
+ if (!_user)
+ _user = (addr_t)&req;
+
+ if (_user != (addr_t)&req)
+ return false;
+
+ bool progress = req.execute(_file);
+ if (req.complete())
+ _user = 0;
+
+ return progress;
}
- void _request_submitted(Module_request &) override;
-
- bool _request_complete() override { return _state == REQ_COMPLETE; }
-
- void _read(bool &);
-
- void _write(bool &);
-
- void _read_client_data(bool &);
-
- void _write_client_data(bool &);
-
- void _sync(bool &);
-
- void _mark_req_failed(bool &, Error_string);
-
- void _mark_req_successful(bool &);
-
- public:
-
- Block_io_channel(Module_channel_id, Vfs::Env &, Xml_node const &);
-
- void execute(bool &);
+ static constexpr char const *name() { return "block_io"; }
};
-class Tresor::Block_io : public Module
+class Tresor::Block_io::Read : Noncopyable
{
+ public:
+
+ using Module = Block_io;
+
+ struct Attr
+ {
+ Physical_block_address const in_pba;
+ Block &out_block;
+ };
+
private:
- using Request = Block_io_request;
- using Channel = Block_io_channel;
+ enum State { INIT, COMPLETE, READ, READ_OK, FILE_ERR };
- Constructible _channels[1] { };
-
- NONCOPYABLE(Block_io);
+ Request_helper _helper;
+ Attr const _attr;
+ Constructible > _file { };
public:
- struct Read : Request
+ Read(Attr const &attr) : _helper(*this), _attr(attr) { }
+
+ void print(Output &out) const { Genode::print(out, "read pba ", _attr.in_pba); }
+
+ bool execute(Vfs::Vfs_handle &);
+
+ bool complete() const { return _helper.complete(); }
+ bool success() const { return _helper.success(); }
+};
+
+class Tresor::Block_io::Write : Noncopyable
+{
+ public:
+
+ using Module = Block_io;
+
+ struct Attr
{
- Read(Module_id m, Module_channel_id c, Physical_block_address a, Block &b, bool &s)
- : Request(m, c, Request::READ, 0, 0, 0, a, 0, b, *(Hash*)0, s) { }
+ Physical_block_address const in_pba;
+ Block const &in_block;
};
- struct Write : Request
- {
- Write(Module_id m, Module_channel_id c, Physical_block_address a, Block const &b, bool &s)
- : Request(m, c, Request::WRITE, 0, 0, 0, a, 0, *const_cast(&b), *(Hash*)0, s) { }
- };
+ private:
- struct Sync : Request
- {
- Sync(Module_id m, Module_channel_id c, bool &s)
- : Request(m, c, Request::SYNC, 0, 0, 0, 0, 0, *(Block*)0, *(Hash*)0, s) { }
- };
+ enum State { INIT, COMPLETE, WRITE, WRITE_OK, FILE_ERR };
- struct Write_client_data : Request
- {
- Write_client_data(Module_id m, Module_channel_id c, Physical_block_address p, Virtual_block_address v,
- Key_id k, Request_tag t, Request_offset o, Hash &h, bool &s)
- : Request(m, c, Request::WRITE_CLIENT_DATA, o, t, k, p, v, *(Block*)0, h, s) { }
- };
+ Request_helper _helper;
+ Attr const _attr;
+ Constructible > _file { };
- struct Read_client_data : Request
- {
- Read_client_data(Module_id m, Module_channel_id c, Physical_block_address p, Virtual_block_address v,
- Key_id k, Request_tag t, Request_offset o, Hash &h, bool &s)
- : Request(m, c, Request::READ_CLIENT_DATA, o, t, k, p, v, *(Block*)0, h, s) { }
- };
+ public:
- Block_io(Vfs::Env &, Xml_node const &);
+ Write(Attr const &attr) : _helper(*this), _attr(attr) { }
- void execute(bool &) override;
+ void print(Output &out) const { Genode::print(out, "write pba ", _attr.in_pba); }
+
+ bool execute(Vfs::Vfs_handle &);
+
+ bool complete() const { return _helper.complete(); }
+ bool success() const { return _helper.success(); }
+};
+
+class Tresor::Block_io::Sync : Noncopyable
+{
+ public:
+
+ using Module = Block_io;
+
+ struct Attr { };
+
+ private:
+
+ enum State { INIT, COMPLETE, SYNC, SYNC_OK, FILE_ERR };
+
+ Request_helper _helper;
+ Attr const _attr;
+ Constructible > _file { };
+
+ public:
+
+ Sync(Attr const &attr) : _helper(*this), _attr(attr) { }
+
+ void print(Output &out) const { Genode::print(out, "sync"); }
+
+ bool execute(Vfs::Vfs_handle &);
+
+ bool complete() const { return _helper.complete(); }
+ bool success() const { return _helper.success(); }
};
#endif /* _TRESOR__BLOCK_IO_H_ */
diff --git a/repos/gems/src/lib/tresor/include/tresor/client_data.h b/repos/gems/src/lib/tresor/include/tresor/client_data.h
deleted file mode 100644
index f7f7a53d09..0000000000
--- a/repos/gems/src/lib/tresor/include/tresor/client_data.h
+++ /dev/null
@@ -1,69 +0,0 @@
-/*
- * \brief Module that provides access to the client request data
- * \author Martin Stein
- * \date 2023-02-13
- */
-
-/*
- * Copyright (C) 2023 Genode Labs GmbH
- *
- * This file is part of the Genode OS framework, which is distributed
- * under the terms of the GNU Affero General Public License version 3.
- */
-
-#ifndef _TRESOR__CLIENT_DATA_H_
-#define _TRESOR__CLIENT_DATA_H_
-
-/* tresor includes */
-#include
-
-namespace Tresor { class Client_data_request; }
-
-namespace Vfs_tresor { class Client_data; }
-
-namespace Tresor_tester { class Client_data; }
-
-class Tresor::Client_data_request : public Module_request
-{
- friend class ::Vfs_tresor::Client_data;
- friend class ::Tresor_tester::Client_data;
-
- public:
-
- enum Type { OBTAIN_PLAINTEXT_BLK, SUPPLY_PLAINTEXT_BLK };
-
- private:
-
- Type const _type;
- Request_offset const _req_off;
- Request_tag const _req_tag;
- Physical_block_address const _pba;
- Virtual_block_address const _vba;
- Block &_blk;
- bool &_success;
-
- NONCOPYABLE(Client_data_request);
-
- public:
-
- Client_data_request(Module_id src_mod_id, Module_channel_id src_chan_id, Type type,
- Request_offset req_off, Request_tag req_tag, Physical_block_address pba,
- Virtual_block_address vba, Block &blk, bool &success)
- :
- Module_request { src_mod_id, src_chan_id, CLIENT_DATA }, _type { type }, _req_off { req_off },
- _req_tag { req_tag }, _pba { pba }, _vba { vba }, _blk { blk }, _success { success }
- { }
-
- static char const *type_to_string(Type type)
- {
- switch (type) {
- case OBTAIN_PLAINTEXT_BLK: return "obtain_plaintext_blk";
- case SUPPLY_PLAINTEXT_BLK: return "supply_plaintext_blk";
- }
- ASSERT_NEVER_REACHED;
- }
-
- void print(Output &out) const override { Genode::print(out, type_to_string(_type)); }
-};
-
-#endif /* _TRESOR__CLIENT_DATA_H_ */
diff --git a/repos/gems/src/lib/tresor/include/tresor/client_data_interface.h b/repos/gems/src/lib/tresor/include/tresor/client_data_interface.h
new file mode 100644
index 0000000000..9456ebcda7
--- /dev/null
+++ b/repos/gems/src/lib/tresor/include/tresor/client_data_interface.h
@@ -0,0 +1,47 @@
+/*
+ * \brief Interface for providing access to the client request data
+ * \author Martin Stein
+ * \date 2023-02-13
+ */
+
+/*
+ * Copyright (C) 2023 Genode Labs GmbH
+ *
+ * This file is part of the Genode OS framework, which is distributed
+ * under the terms of the GNU Affero General Public License version 3.
+ */
+
+#ifndef _TRESOR__CLIENT_DATA_INTERFACE_H_
+#define _TRESOR__CLIENT_DATA_INTERFACE_H_
+
+/* tresor includes */
+#include
+
+namespace Tresor { class Client_data_interface; }
+
+struct Tresor::Client_data_interface : Interface
+{
+ struct Obtain_data_attr
+ {
+ Request_offset const in_req_off;
+ Request_tag const in_req_tag;
+ Physical_block_address const in_pba;
+ Virtual_block_address const in_vba;
+ Block &out_blk;
+ };
+
+ virtual void obtain_data(Obtain_data_attr const &) = 0;
+
+ struct Supply_data_attr
+ {
+ Request_offset const in_req_off;
+ Request_tag const in_req_tag;
+ Physical_block_address const in_pba;
+ Virtual_block_address const in_vba;
+ Block const &in_blk;
+ };
+
+ virtual void supply_data(Supply_data_attr const &) = 0;
+};
+
+#endif /* _TRESOR__CLIENT_DATA_INTERFACE_H_ */
diff --git a/repos/gems/src/lib/tresor/include/tresor/crypto.h b/repos/gems/src/lib/tresor/include/tresor/crypto.h
index 0098ab9083..3eaaa2d519 100644
--- a/repos/gems/src/lib/tresor/include/tresor/crypto.h
+++ b/repos/gems/src/lib/tresor/include/tresor/crypto.h
@@ -21,155 +21,187 @@
namespace Tresor {
class Crypto;
- class Crypto_request;
- class Crypto_channel;
+ class Crypto_key_files_interface;
}
-class Tresor::Crypto_request : public Module_request
+struct Tresor::Crypto_key_files_interface : Interface
{
- friend class Crypto_channel;
+ virtual void add_crypto_key(Key_id) = 0;
- public:
+ virtual void remove_crypto_key(Key_id) = 0;
- enum Type { ADD_KEY, REMOVE_KEY, DECRYPT, ENCRYPT, DECRYPT_CLIENT_DATA, ENCRYPT_CLIENT_DATA };
+ virtual Vfs::Vfs_handle &encrypt_file(Key_id) = 0;
- private:
-
- Type const _type;
- Request_offset const _client_req_offset;
- Request_tag const _client_req_tag;
- Physical_block_address const _pba;
- Virtual_block_address const _vba;
- Key_id const _key_id;
- Key_value const &_key_plaintext;
- Block &_blk;
- bool &_success;
-
- NONCOPYABLE(Crypto_request);
-
- public:
-
- Crypto_request(Module_id, Module_channel_id, Type, Request_offset, Request_tag, Key_id,
- Key_value const &, Physical_block_address, Virtual_block_address, Block &, bool &);
-
- static const char *type_to_string(Type);
-
- void print(Output &) const override;
+ virtual Vfs::Vfs_handle &decrypt_file(Key_id) = 0;
};
-class Tresor::Crypto_channel : public Module_channel
+class Tresor::Crypto : Noncopyable
{
- private:
+ public:
- using Request = Crypto_request;
-
- enum State {
- REQ_SUBMITTED, REQ_COMPLETE, PLAINTEXT_BLK_OBTAINED, PLAINTEXT_BLK_SUPPLIED, REQ_GENERATED,
- READ_OK, WRITE_OK, FILE_ERR };
-
- struct Key_directory
+ struct Attr
{
- Crypto_channel &chan;
- Key_id key_id;
- Read_write_file encrypt_file { chan._state, chan._vfs_env, { chan._path, "/keys/", key_id, "/encrypt" } };
- Read_write_file decrypt_file { chan._state, chan._vfs_env, { chan._path, "/keys/", key_id, "/decrypt" } };
-
- NONCOPYABLE(Key_directory);
-
- Key_directory(Crypto_channel &chan, Key_id key_id) : chan { chan }, key_id { key_id } { }
+ Crypto_key_files_interface &key_files;
+ Vfs::Vfs_handle &add_key_file;
+ Vfs::Vfs_handle &remove_key_file;
};
- Vfs::Env &_vfs_env;
- Tresor::Path const _path;
- char _add_key_buf[sizeof(Key_id) + KEY_SIZE] { };
- Write_only_file _add_key_file { _state, _vfs_env, { _path, "/add_key" } };
- Write_only_file _remove_key_file { _state, _vfs_env, { _path, "/remove_key" } };
- Constructible _key_dirs[2] { };
- State _state { REQ_COMPLETE };
- bool _generated_req_success { false };
- Block _blk { };
- Request *_req_ptr { };
+ private:
- NONCOPYABLE(Crypto_channel);
+ Attr const _attr;
+ addr_t _user { };
- void _generated_req_completed(State_uint) override;
+ public:
- void _request_submitted(Module_request &) override;
+ class Encrypt;
+ class Decrypt;
+ class Add_key;
+ class Remove_key;
- bool _request_complete() override { return _state == REQ_COMPLETE; }
+ Crypto(Attr const &attr) : _attr(attr) { }
- template
- void _generate_req(State_uint state, bool &progress, ARGS &&... args)
+ template
+ bool execute(REQ &req)
{
- _state = REQ_GENERATED;
- generate_req(state, progress, args..., _generated_req_success);
+ if (!_user)
+ _user = (addr_t)&req;
+
+ if (_user != (addr_t)&req)
+ return false;
+
+ bool progress = req.execute(_attr);
+ if (req.complete())
+ _user = 0;
+
+ return progress;
}
- void _add_key(bool &);
-
- void _remove_key(bool &);
-
- void _decrypt(bool &);
-
- void _encrypt(bool &);
-
- void _encrypt_client_data(bool &);
-
- void _decrypt_client_data(bool &);
-
- void _mark_req_failed(bool &, char const *);
-
- void _mark_req_successful(bool &);
-
- Constructible &_key_dir(Key_id key_id);
-
- public:
-
- Crypto_channel(Module_channel_id, Vfs::Env &, Xml_node const &);
-
- void execute(bool &);
+ static constexpr char const *name() { return "crypto"; }
};
-class Tresor::Crypto : public Module
+class Tresor::Crypto::Encrypt : Noncopyable
{
+ public:
+
+ using Module = Crypto;
+
+ struct Attr
+ {
+ Key_id const in_key_id;
+ Physical_block_address const in_pba;
+ Block &in_out_blk;
+ };
+
private:
- using Request = Crypto_request;
- using Channel = Crypto_channel;
+ enum State { INIT, COMPLETE, WRITE, WRITE_OK, READ_OK, FILE_ERR };
- Constructible _channels[1] { };
-
- NONCOPYABLE(Crypto);
+ Request_helper _helper;
+ Attr const _attr;
+ off_t _offset { };
+ Constructible > _file { };
public:
- struct Add_key : Request
+ Encrypt(Attr const &attr) : _helper(*this), _attr(attr) { }
+
+ void print(Output &out) const { Genode::print(out, "encrypt pba ", _attr.in_pba); }
+
+ bool execute(Crypto::Attr const &);
+
+ bool complete() const { return _helper.complete(); }
+ bool success() const { return _helper.success(); }
+};
+
+class Tresor::Crypto::Decrypt : Noncopyable
+{
+ public:
+
+ using Module = Crypto;
+
+ struct Attr
{
- Add_key(Module_id src_mod, Module_channel_id src_chan, Key &key, bool &succ)
- : Request(src_mod, src_chan, Request::ADD_KEY, 0, 0, key.id, key.value, 0, 0, *(Block*)0, succ) { }
+ Key_id const in_key_id;
+ Physical_block_address const in_pba;
+ Block &in_out_blk;
};
- struct Remove_key : Request
- {
- Remove_key(Module_id src_mod, Module_channel_id src_chan, Key_id key, bool &succ)
- : Request(src_mod, src_chan, Request::REMOVE_KEY, 0, 0, key, *(Key_value*)0, 0, 0, *(Block*)0, succ) { }
- };
+ private:
- struct Decrypt : Request
- {
- Decrypt(Module_id src_mod, Module_channel_id src_chan, Key_id key, Physical_block_address pba, Block &blk, bool &succ)
- : Request(src_mod, src_chan, Request::DECRYPT, 0, 0, key, *(Key_value*)0, pba, 0, blk, succ) { }
- };
+ enum State { INIT, COMPLETE, WRITE, WRITE_OK, READ_OK, FILE_ERR };
- struct Encrypt : Request
- {
- Encrypt(Module_id src_mod, Module_channel_id src_chan, Key_id key, Physical_block_address pba, Block &blk, bool &succ)
- : Request(src_mod, src_chan, Request::ENCRYPT, 0, 0, key, *(Key_value*)0, pba, 0, blk, succ) { }
- };
+ Request_helper _helper;
+ Attr const _attr;
+ off_t _offset { };
+ Constructible > _file { };
- Crypto(Vfs::Env &, Xml_node const &);
+ public:
- void execute(bool &) override;
+ Decrypt(Attr const &attr) : _helper(*this), _attr(attr) { }
+
+ void print(Output &out) const { Genode::print(out, "decrypt pba ", _attr.in_pba); }
+
+ bool execute(Crypto::Attr const &);
+
+ bool complete() const { return _helper.complete(); }
+ bool success() const { return _helper.success(); }
+};
+
+class Tresor::Crypto::Add_key : Noncopyable
+{
+ public:
+
+ using Module = Crypto;
+
+ struct Attr { Key const &in_key; };
+
+ private:
+
+ enum State { INIT, COMPLETE, WRITE, WRITE_OK, FILE_ERR };
+
+ Request_helper _helper;
+ Attr const _attr;
+ char _write_buf[sizeof(Key_id) + sizeof(Key_value)] { };
+ Constructible > _file { };
+
+ public:
+
+ Add_key(Attr const &attr) : _helper(*this), _attr(attr) { }
+
+ void print(Output &out) const { Genode::print(out, "add key id ", _attr.in_key.id); }
+
+ bool execute(Crypto::Attr const &);
+
+ bool complete() const { return _helper.complete(); }
+ bool success() const { return _helper.success(); }
+};
+
+class Tresor::Crypto::Remove_key : Noncopyable
+{
+ public:
+
+ using Module = Crypto;
+
+ struct Attr { Key_id const in_key_id; };
+
+ private:
+
+ enum State { INIT, COMPLETE, WRITE, WRITE_OK, FILE_ERR };
+
+ Request_helper _helper;
+ Attr const _attr;
+ Constructible > _file { };
+
+ public:
+
+ Remove_key(Attr const &attr) : _helper(*this), _attr(attr) { }
+
+ void print(Output &out) const { Genode::print(out, "remove key id ", _attr.in_key_id); }
+
+ bool execute(Crypto::Attr const &);
+
+ bool complete() const { return _helper.complete(); }
+ bool success() const { return _helper.success(); }
};
#endif /* _TRESOR__CRYPTO_H_ */
diff --git a/repos/gems/src/lib/tresor/include/tresor/file.h b/repos/gems/src/lib/tresor/include/tresor/file.h
index 188865e87b..c8a3a4f305 100644
--- a/repos/gems/src/lib/tresor/include/tresor/file.h
+++ b/repos/gems/src/lib/tresor/include/tresor/file.h
@@ -33,8 +33,17 @@ namespace Tresor {
template class File;
template class Read_write_file;
template class Write_only_file;
+
+ inline Vfs::Vfs_handle &open_file(Vfs::Env &env, Tresor::Path const &path, Vfs::Directory_service::Open_mode mode)
+ {
+ using Open_result = Vfs::Directory_service::Open_result;
+ Vfs::Vfs_handle *handle { nullptr };
+ ASSERT(env.root_dir().open(path.string(), mode, &handle, env.alloc()) == Open_result::OPEN_OK);
+ return *handle;
+ }
}
+
template
class Tresor::File
{
@@ -43,34 +52,34 @@ class Tresor::File
using Read_result = Vfs::File_io_service::Read_result;
using Write_result = Vfs::File_io_service::Write_result;
using Sync_result = Vfs::File_io_service::Sync_result;
- using Open_result = Vfs::Directory_service::Open_result;
enum State { IDLE, SYNC_QUEUED, READ_QUEUED, READ_INITIALIZED, WRITE_INITIALIZED, WRITE_OFFSET_APPLIED };
- Vfs::Env &_env;
+ Vfs::Env *_env { };
+ Tresor::Path const *_path { };
HOST_STATE &_host_state;
State _state { IDLE };
Vfs::Vfs_handle &_handle;
Vfs::file_size _num_processed_bytes { 0 };
- Vfs::Vfs_handle &_open(Tresor::Path path, Vfs::Directory_service::Open_mode mode)
- {
- Vfs::Vfs_handle *handle { nullptr };
- ASSERT(_env.root_dir().open(path.string(), mode, &handle, _env.alloc()) == Open_result::OPEN_OK);
- return *handle;
- }
+ /*
+ * Noncopyable
+ */
+ File(File const &) = delete;
+ File &operator = (File const &) = delete;
public:
- File(HOST_STATE &host_state, Vfs::Vfs_handle &handle) : _host_state { host_state }, _handle { handle } { }
+ File(HOST_STATE &host_state, Vfs::Vfs_handle &handle) : _host_state(host_state), _handle(handle) { }
- File(HOST_STATE &host_state, Vfs::Env &env, Tresor::Path path, Vfs::Directory_service::Open_mode mode)
- : _env { env }, _host_state { host_state }, _handle { _open(path, mode) } { }
+ File(HOST_STATE &host_state, Vfs::Env &env, Tresor::Path const &path, Vfs::Directory_service::Open_mode mode)
+ : _env(&env), _path(&path), _host_state(host_state), _handle(open_file(*_env, *_path, mode)) { }
~File()
{
ASSERT(_state == IDLE);
- _env.root_dir().close(&_handle);
+ if (_env)
+ _env->root_dir().close(&_handle);
}
void read(HOST_STATE succeeded, HOST_STATE failed, Vfs::file_offset off, Byte_range_ptr dst, bool &progress)
@@ -116,7 +125,7 @@ class Tresor::File
default:
- error("read failed");
+ error("file: read failed");
_host_state = failed;
_state = IDLE;
progress = true;
@@ -167,7 +176,7 @@ class Tresor::File
default:
- error("write failed");
+ error("file: write failed");
_host_state = failed;
_state = IDLE;
progress = true;
@@ -204,7 +213,7 @@ class Tresor::File
default:
- error("sync failed");
+ error("file: sync failed");
_host_state = failed;
_state = IDLE;
progress = true;
@@ -218,15 +227,15 @@ class Tresor::File
template
struct Tresor::Read_write_file : public File
{
- Read_write_file(HOST_STATE &host_state, Vfs::Env &env, Tresor::Path path)
- : File { host_state, env, path, Vfs::Directory_service::OPEN_MODE_RDWR } { }
+ Read_write_file(HOST_STATE &host_state, Vfs::Env &env, Tresor::Path const &path)
+ : File(host_state, env, path, Vfs::Directory_service::OPEN_MODE_RDWR) { }
};
template
struct Tresor::Write_only_file : public File
{
- Write_only_file(HOST_STATE &host_state, Vfs::Env &env, Tresor::Path path)
- : File { host_state, env, path, Vfs::Directory_service::OPEN_MODE_WRONLY } { }
+ Write_only_file(HOST_STATE &host_state, Vfs::Env &env, Tresor::Path const &path)
+ : File(host_state, env, path, Vfs::Directory_service::OPEN_MODE_WRONLY) { }
};
#endif /* _TRESOR__FILE_H_ */
diff --git a/repos/gems/src/lib/tresor/include/tresor/free_tree.h b/repos/gems/src/lib/tresor/include/tresor/free_tree.h
index c2618e86be..3f9a434c36 100644
--- a/repos/gems/src/lib/tresor/include/tresor/free_tree.h
+++ b/repos/gems/src/lib/tresor/include/tresor/free_tree.h
@@ -16,80 +16,68 @@
/* tresor includes */
#include
+#include
+#include
-namespace Tresor {
+namespace Tresor { class Free_tree; }
- class Free_tree;
- class Free_tree_request;
- class Free_tree_channel;
-}
-
-class Tresor::Free_tree_request : public Module_request
+class Tresor::Free_tree : Noncopyable
{
- friend class Free_tree_channel;
-
public:
- enum Type { ALLOC_FOR_NON_RKG, ALLOC_FOR_RKG_CURR_GEN_BLKS, ALLOC_FOR_RKG_OLD_GEN_BLKS, EXTENSION_STEP };
+ class Allocate_pbas;
+ class Extend_tree;
- private:
+ template
+ bool execute(REQUEST &req, Block_io &block_io, Meta_tree &meta_tree) { return req.execute(block_io, meta_tree); }
- Type const _type;
- Tree_root &_ft;
- Tree_root &_mt;
- Generation const _curr_gen;
- Generation const _free_gen;
- Number_of_blocks const _num_required_pbas;
- Tree_walk_pbas &_new_blocks;
- Type_1_node_walk const &_old_blocks;
- Tree_level_index const _max_lvl;
- Virtual_block_address const _vba;
- Tree_degree const _vbd_degree;
- Virtual_block_address const _vbd_max_vba;
- bool const _rekeying;
- Key_id const _prev_key_id;
- Key_id const _curr_key_id;
- Virtual_block_address const _rekeying_vba;
- bool &_success;
- Snapshots const &_snapshots;
- Generation const _last_secured_gen;
- Physical_block_address &_pba;
- Number_of_blocks &_num_pbas;
-
- NONCOPYABLE(Free_tree_request);
-
- public:
-
- Free_tree_request(Module_id, Module_channel_id, Type, Tree_root &, Tree_root &, Snapshots const &,
- Generation, Generation, Generation, Number_of_blocks, Tree_walk_pbas &, Type_1_node_walk const &,
- Tree_level_index, Virtual_block_address, Tree_degree, Virtual_block_address,
- bool, Key_id, Key_id, Virtual_block_address, Physical_block_address &, Number_of_blocks &, bool &);
-
- static char const *type_to_string(Type);
-
- void print(Output &out) const override { Genode::print(out, type_to_string(_type)); }
+ static constexpr char const *name() { return "free_tree"; }
};
-
-class Tresor::Free_tree_channel : public Module_channel
+class Tresor::Free_tree::Allocate_pbas : Noncopyable
{
+ public:
+
+ using Module = Free_tree;
+
+ enum Application { NON_REKEYING, REKEYING_IN_CURRENT_GENERATION, REKEYING_IN_OLDER_GENERATION };
+
+ struct Attr
+ {
+ Tree_root &in_out_ft;
+ Tree_root &in_out_mt;
+ Snapshots const &in_snapshots;
+ Generation const in_last_secured_gen;
+ Generation const in_curr_gen;
+ Generation const in_free_gen;
+ Number_of_blocks const in_num_required_pbas;
+ Tree_walk_pbas &in_out_new_blocks;
+ Type_1_node_walk const &in_old_blocks;
+ Tree_level_index const in_max_lvl;
+ Virtual_block_address const in_vba;
+ Tree_degree const in_vbd_degree;
+ Virtual_block_address const in_vbd_max_vba;
+ bool const in_rekeying;
+ Key_id const in_prev_key_id;
+ Key_id const in_curr_key_id;
+ Virtual_block_address const in_rekeying_vba;
+ Application const in_application;
+ };
+
private:
- using Request = Free_tree_request;
-
enum State {
- REQ_SUBMITTED, REQ_GENERATED, SEEK_DOWN, SEEK_LEFT_OR_UP, WRITE_BLK, READ_BLK_SUCCEEDED,
- ALLOC_PBA_SUCCEEDED, WRITE_BLK_SUCCEEDED, REQ_COMPLETE };
+ INIT, COMPLETE, SEEK_DOWN, SEEK_LEFT_OR_UP, READ_BLK, READ_BLK_SUCCEEDED,
+ ALLOC_PBA, ALLOC_PBA_SUCCEEDED, WRITE_BLK, WRITE_BLK_SUCCEEDED };
- Request *_req_ptr { nullptr };
- State _state { REQ_COMPLETE };
+ using Helper = Request_helper;
+
+ Helper _helper;
+ Attr const _attr;
Virtual_block_address _vba { };
Tree_walk_pbas _old_pbas { };
Tree_walk_pbas _new_pbas { };
Tree_walk_generations _old_generations { };
- Number_of_leaves _num_leaves { 0 };
- Physical_block_address _alloc_pba { 0 };
- Tree_level_index _alloc_lvl { 0 };
Number_of_blocks _num_pbas { 0 };
Block _blk { };
Tree_node_index _node_idx[TREE_MAX_NR_OF_LEVELS] { };
@@ -98,36 +86,71 @@ class Tresor::Free_tree_channel : public Module_channel
Type_2_node_block _t2_blk { };
Tree_degree_log_2 _vbd_degree_log_2 { 0 };
Tree_level_index _lvl { 0 };
- bool _generated_req_success { false };
-
- NONCOPYABLE(Free_tree_channel);
-
- void _generated_req_completed(State_uint) override;
-
- template
- void _generate_req(State_uint state, bool &progress, ARGS &&... args)
- {
- _state = REQ_GENERATED;
- generate_req(state, progress, args..., _generated_req_success);
- }
-
- void _request_submitted(Module_request &) override;
-
- bool _request_complete() override { return _state == REQ_COMPLETE; }
-
- void _mark_req_failed(bool &, char const *);
-
- bool _can_alloc_pba_of(Type_2_node &);
+ Generatable_request _read_block { };
+ Generatable_request _write_block { };
+ Generatable_request _allocate_pba { };
void _alloc_pba_of(Type_2_node &);
- void _traverse_curr_node(bool &);
+ bool _can_alloc_pba_of(Type_2_node &);
- void _mark_req_successful(bool &);
+ void _traverse_curr_node(bool &);
void _start_tree_traversal(bool &);
- void _advance_to_next_node();
+ public:
+
+ Allocate_pbas(Attr const &attr) : _helper(*this), _attr(attr) { }
+
+ ~Allocate_pbas() { }
+
+ void print(Output &out) const { Genode::print(out, "allocate pbas"); }
+
+ bool execute(Block_io &, Meta_tree &);
+
+ bool complete() const { return _helper.complete(); }
+ bool success() const { return _helper.success(); }
+};
+
+class Tresor::Free_tree::Extend_tree : Noncopyable
+{
+ public:
+
+ using Module = Free_tree;
+
+ struct Attr
+ {
+ Generation const in_curr_gen;
+ Tree_root &in_out_ft;
+ Tree_root &in_out_mt;
+ Physical_block_address &in_out_first_pba;
+ Number_of_blocks &in_out_num_pbas;
+ };
+
+ private:
+
+ enum State {
+ INIT, COMPLETE, READ_BLK, READ_BLK_SUCCEEDED, ALLOC_PBA, ALLOC_PBA_SUCCEEDED, WRITE_BLK,
+ WRITE_BLK_SUCCEEDED };
+
+ using Helper = Request_helper;
+
+ Helper _helper;
+ Attr const _attr;
+ Number_of_leaves _num_leaves { 0 };
+ Virtual_block_address _vba { };
+ Tree_walk_pbas _old_pbas { };
+ Tree_walk_generations _old_generations { };
+ Tree_walk_pbas _new_pbas { };
+ Tree_level_index _lvl { 0 };
+ Block _blk { };
+ Type_1_node_block _t1_blks[TREE_MAX_NR_OF_LEVELS] { };
+ Type_2_node_block _t2_blk { };
+ Tree_level_index _alloc_lvl { 0 };
+ Physical_block_address _alloc_pba { 0 };
+ Generatable_request _read_block { };
+ Generatable_request _write_block { };
+ Generatable_request _allocate_pba { };
void _add_new_branch_at(Tree_level_index, Tree_node_index);
@@ -135,41 +158,18 @@ class Tresor::Free_tree_channel : public Module_channel
void _generate_write_blk_req(bool &);
- void _extension_step(bool &);
-
- void _alloc_pbas(bool &);
-
public:
- Free_tree_channel(Module_channel_id id) : Module_channel { FREE_TREE, id } { }
+ Extend_tree(Attr const &attr) : _helper(*this), _attr(attr) { }
- void execute(bool &);
-};
+ ~Extend_tree() { }
-class Tresor::Free_tree : public Module
-{
- private:
+ void print(Output &out) const { Genode::print(out, "extend tree"); }
- using Channel = Free_tree_channel;
- using Request = Free_tree_request;
+ bool execute(Block_io &, Meta_tree &);
- Constructible _channels[1] { };
-
- NONCOPYABLE(Free_tree);
-
- void execute(bool &) override;
-
- public:
-
- struct Extension_step : Request
- {
- Extension_step(Module_id mod_id, Module_channel_id chan_id, Generation curr_gen, Tree_root &ft, Tree_root &mt,
- Physical_block_address &pba, Number_of_blocks &num_pbas, bool &succ)
- : Request(mod_id, chan_id, Request::EXTENSION_STEP, ft, mt, *(Snapshots *)0, 0, curr_gen, 0, 0, *(Tree_walk_pbas*)0,
- *(Type_1_node_walk*)0, 0, 0, 0, 0, 0, 0, 0, 0, pba, num_pbas, succ) { }
- };
-
- Free_tree();
+ bool complete() const { return _helper.complete(); }
+ bool success() const { return _helper.success(); }
};
#endif /* _TRESOR__FREE_TREE_H_ */
diff --git a/repos/gems/src/lib/tresor/include/tresor/ft_check.h b/repos/gems/src/lib/tresor/include/tresor/ft_check.h
index a8168311e7..2db3e92627 100644
--- a/repos/gems/src/lib/tresor/include/tresor/ft_check.h
+++ b/repos/gems/src/lib/tresor/include/tresor/ft_check.h
@@ -16,95 +16,54 @@
/* tresor includes */
#include
+#include
-namespace Tresor {
+namespace Tresor { class Ft_check; }
- class Ft_check;
- class Ft_check_request;
- class Ft_check_channel;
-}
-
-
-class Tresor::Ft_check_request : public Module_request
+struct Tresor::Ft_check : Noncopyable
{
- friend class Ft_check_channel;
+ class Check : Noncopyable
+ {
+ public:
- private:
+ using Module = Ft_check;
- Tree_root const &_ft;
- bool &_success;
+ struct Attr { Tree_root const &in_ft; };
- NONCOPYABLE(Ft_check_request);
+ private:
- public:
+ enum State { INIT, IN_PROGRESS, COMPLETE, READ_BLK, READ_BLK_SUCCEEDED };
- Ft_check_request(Module_id, Module_channel_id, Tree_root const &, bool &);
+ using Helper = Request_helper;
- void print(Output &out) const override { Genode::print(out, "check ", _ft); }
-};
+ Helper _helper;
+ Attr const _attr;
+ Type_1_node_block_walk _t1_blks { };
+ Type_2_node_block _t2_blk { };
+ bool _check_node[TREE_MAX_NR_OF_LEVELS + 1][NUM_NODES_PER_BLK] { };
+ Number_of_leaves _num_remaining_leaves { 0 };
+ Block _blk { };
+ Generatable_request _read_block { };
+ bool _execute_node(Block_io &, Tree_level_index, Tree_node_index, bool &);
-class Tresor::Ft_check_channel : public Module_channel
-{
- private:
+ public:
- using Request = Ft_check_request;
+ Check(Attr const &attr) : _helper(*this), _attr(attr) { }
- enum State : State_uint { REQ_SUBMITTED, REQ_IN_PROGRESS, REQ_COMPLETE, REQ_GENERATED, READ_BLK_SUCCEEDED };
+ void print(Output &out) const { Genode::print(out, "check ", _attr.in_ft); }
- State _state { REQ_COMPLETE };
- Type_1_node_block_walk _t1_blks { };
- Type_2_node_block _t2_blk { };
- bool _check_node[TREE_MAX_NR_OF_LEVELS + 1][NUM_NODES_PER_BLK] { };
- Number_of_leaves _num_remaining_leaves { 0 };
- Request *_req_ptr { };
- Block _blk { };
- bool _generated_req_success { false };
+ bool execute(Block_io &);
- NONCOPYABLE(Ft_check_channel);
+ bool complete() const { return _helper.complete(); }
+ bool success() const { return _helper.success(); }
+ };
- void _generated_req_completed(State_uint) override;
+ Ft_check() { }
- void _request_submitted(Module_request &) override;
+ bool execute(Check &req, Block_io &block_io) { return req.execute(block_io); }
- bool _request_complete() override { return _state == REQ_COMPLETE; }
-
- void _mark_req_failed(bool &, Error_string);
-
- void _mark_req_successful(bool &);
-
- bool _execute_node(Tree_level_index, Tree_node_index, bool &);
-
- template
- void _generate_req(State_uint state, bool &progress, ARGS &&... args)
- {
- _state = REQ_GENERATED;
- generate_req(state, progress, args..., _generated_req_success);
- }
-
- public:
-
- Ft_check_channel(Module_channel_id id) : Module_channel { FT_CHECK, id } { }
-
- void execute(bool &);
-};
-
-
-class Tresor::Ft_check : public Module
-{
- private:
-
- using Channel = Ft_check_channel;
-
- Constructible _channels[1] { };
-
- NONCOPYABLE(Ft_check);
-
- public:
-
- Ft_check();
-
- void execute(bool &) override;
+ static constexpr char const *name() { return "ft_check"; }
};
#endif /* _TRESOR__FT_CHECK_H_ */
diff --git a/repos/gems/src/lib/tresor/include/tresor/ft_initializer.h b/repos/gems/src/lib/tresor/include/tresor/ft_initializer.h
index 6b07ff3a2e..e79ccd51e8 100644
--- a/repos/gems/src/lib/tresor/include/tresor/ft_initializer.h
+++ b/repos/gems/src/lib/tresor/include/tresor/ft_initializer.h
@@ -17,97 +17,68 @@
/* tresor includes */
#include
+#include
-namespace Tresor {
+namespace Tresor { class Ft_initializer; }
- class Ft_initializer;
- class Ft_initializer_request;
- class Ft_initializer_channel;
-}
-
-
-class Tresor::Ft_initializer_request : public Module_request
+class Tresor::Ft_initializer : Noncopyable
{
- friend class Ft_initializer_channel;
-
- private:
-
- Tree_root &_ft;
- Pba_allocator &_pba_alloc;
- bool &_success;
-
- NONCOPYABLE(Ft_initializer_request);
-
public:
- Ft_initializer_request(Module_id, Module_channel_id, Tree_root &, Pba_allocator &, bool &);
+ class Initialize : Noncopyable
+ {
+ public:
- void print(Output &out) const override { Genode::print(out, "init"); }
-};
+ using Module = Ft_initializer;
+ struct Attr
+ {
+ Tree_configuration const in_tree_cfg;
+ Type_1_node &out_tree_root;
+ Pba_allocator &in_out_pba_alloc;
+ };
-class Tresor::Ft_initializer_channel : public Module_channel
-{
- private:
+ private:
- using Request = Ft_initializer_request;
+ enum Node_state { DONE, INIT_BLOCK, INIT_NODE, WRITING_BLOCK };
- enum State { REQ_GENERATED, REQ_SUBMITTED, EXECUTE_NODES, REQ_COMPLETE };
+ enum State { INIT, COMPLETE, EXECUTE_NODES, WRITE_BLOCK };
- enum Node_state { DONE, INIT_BLOCK, INIT_NODE, WRITE_BLK };
+ using Helper = Request_helper;
- State _state { REQ_COMPLETE };
- Request *_req_ptr { };
- Type_2_node_block _t2_blk { };
- Type_1_node_block_walk _t1_blks { };
- Node_state _t1_node_states[TREE_MAX_NR_OF_LEVELS][NUM_NODES_PER_BLK] { };
- Node_state _t2_node_states[NUM_NODES_PER_BLK] { };
- Number_of_leaves _num_remaining_leaves { 0 };
- bool _generated_req_success { false };
- Block _blk { };
+ Helper _helper;
+ Attr const _attr;
+ Type_2_node_block _t2_blk { };
+ Type_1_node_block_walk _t1_blks { };
+ Node_state _t1_node_states[TREE_MAX_NR_OF_LEVELS][NUM_NODES_PER_BLK] { };
+ Node_state _t2_node_states[NUM_NODES_PER_BLK] { };
+ Number_of_leaves _num_remaining_leaves { 0 };
+ Block _blk { };
+ Generatable_request _write_block { };
- NONCOPYABLE(Ft_initializer_channel);
+ void _reset_level(Tree_level_index, Node_state);
- void _reset_level(Tree_level_index, Node_state);
+ bool _execute_t2_node(Tree_node_index, bool &);
- void _generated_req_completed(State_uint) override;
+ bool _execute_t1_node(Tree_level_index, Tree_node_index, bool &);
- bool _request_complete() override { return _state == REQ_COMPLETE; }
+ public:
- void _request_submitted(Module_request &) override;
+ Initialize(Attr const &attr) : _helper(*this), _attr(attr) { }
- bool _execute_t2_node(Tree_node_index, bool &);
+ ~Initialize() { }
- bool _execute_t1_node(Tree_level_index, Tree_node_index, bool &);
+ void print(Output &out) const { Genode::print(out, "initialize"); }
- void _mark_req_failed(bool &, char const *);
+ bool execute(Block_io &);
- void _mark_req_successful(bool &);
+ bool complete() const { return _helper.complete(); }
+ bool success() const { return _helper.success(); }
+ };
- public:
-
- Ft_initializer_channel(Module_channel_id id) : Module_channel { FT_INITIALIZER, id } { }
-
- void execute(bool &);
-};
-
-
-class Tresor::Ft_initializer : public Module
-{
- private:
-
- using Channel = Ft_initializer_channel;
-
- Constructible _channels[1] { };
-
- NONCOPYABLE(Ft_initializer);
-
- public:
-
- Ft_initializer();
-
- void execute(bool &) override;
+ bool execute(Initialize &req, Block_io &block_io) { return req.execute(block_io); }
+ static constexpr char const *name() { return "ft_initializer"; }
};
#endif /* _TRESOR__FT_INITIALIZER_H_ */
diff --git a/repos/gems/src/lib/tresor/include/tresor/meta_tree.h b/repos/gems/src/lib/tresor/include/tresor/meta_tree.h
index d529b56ce6..18619af7a5 100644
--- a/repos/gems/src/lib/tresor/include/tresor/meta_tree.h
+++ b/repos/gems/src/lib/tresor/include/tresor/meta_tree.h
@@ -1,5 +1,5 @@
/*
- * \brief Module for doing VBD COW allocations on the meta tree
+ * \brief Module for doing PBA allocations for the Free Tree via the Meta Tree
* \author Martin Stein
* \date 2023-02-13
*/
@@ -16,74 +16,49 @@
/* tresor includes */
#include
+#include
-namespace Tresor {
+namespace Tresor { class Meta_tree; }
- class Meta_tree;
- class Meta_tree_request;
- class Meta_tree_channel;
-}
-
-class Tresor::Meta_tree_request : public Module_request
+class Tresor::Meta_tree : Noncopyable
{
- friend class Meta_tree_channel;
-
public:
- enum Type { ALLOC_PBA };
+ class Allocate_pba;
- private:
+ bool execute(Allocate_pba &, Block_io &);
- Type const _type;
- Tree_root &_mt;
- Generation const _curr_gen;
- Physical_block_address &_pba;
- bool &_success;
-
- NONCOPYABLE(Meta_tree_request);
-
- public:
-
- Meta_tree_request(Module_id, Module_channel_id, Type, Tree_root &, Generation, Physical_block_address &, bool &);
-
- static char const *type_to_string(Type);
-
- void print(Output &out) const override { Genode::print(out, type_to_string(_type)); }
+ static constexpr char const *name() { return "meta_tree"; }
};
-class Tresor::Meta_tree_channel : public Module_channel
+class Tresor::Meta_tree::Allocate_pba : Noncopyable
{
+ public:
+
+ using Module = Meta_tree;
+
+ struct Attr
+ {
+ Tree_root &in_out_mt;
+ Generation const in_curr_gen;
+ Physical_block_address &in_out_pba;
+ };
+
private:
- using Request = Meta_tree_request;
+ enum State { INIT, COMPLETE, READ_BLK, SEEK_DOWN, SEEK_LEFT_OR_UP, WRITE_BLK, WRITE_BLK_SUCCEEDED };
- enum State { REQ_SUBMITTED, REQ_GENERATED, SEEK_DOWN, SEEK_LEFT_OR_UP, WRITE_BLK, COMPLETE };
+ using Helper = Request_helper;
- State _state { COMPLETE };
- Request *_req_ptr { nullptr };
+ Helper _helper;
+ Attr const _attr;
Block _blk { };
Tree_node_index _node_idx[TREE_MAX_NR_OF_LEVELS] { };
Type_1_node_block _t1_blks[TREE_MAX_NR_OF_LEVELS] { };
Type_2_node_block _t2_blk { };
Tree_level_index _lvl { 0 };
- bool _generated_req_success { false };
-
- NONCOPYABLE(Meta_tree_channel);
-
- void _generated_req_completed(State_uint) override;
-
- template
- void _generate_req(State_uint state, bool &progress, ARGS &&... args)
- {
- _state = REQ_GENERATED;
- generate_req(state, progress, args..., _generated_req_success);
- }
-
- void _request_submitted(Module_request &) override;
-
- bool _request_complete() override { return _state == COMPLETE; }
-
- void _mark_req_failed(bool &, char const *);
+ Generatable_request _read_block { };
+ Generatable_request _write_block { };
bool _can_alloc_pba_of(Type_2_node &);
@@ -91,38 +66,20 @@ class Tresor::Meta_tree_channel : public Module_channel
void _traverse_curr_node(bool &);
- void _mark_req_successful(bool &);
-
void _start_tree_traversal(bool &);
public:
- Meta_tree_channel(Module_channel_id id) : Module_channel { META_TREE, id } { }
+ Allocate_pba(Attr const &attr) : _helper(*this), _attr(attr) { }
- void execute(bool &);
-};
+ ~Allocate_pba() { }
-class Tresor::Meta_tree : public Module
-{
- private:
+ void print(Output &out) const { Genode::print(out, "allocate pba"); }
- using Channel = Meta_tree_channel;
+ bool execute(Block_io &);
- Constructible _channels[1] { };
-
- NONCOPYABLE(Meta_tree);
-
- void execute(bool &) override;
-
- public:
-
- struct Alloc_pba : Meta_tree_request
- {
- Alloc_pba(Module_id src_mod, Module_channel_id src_chan, Tree_root &mt, Generation gen, Physical_block_address &pba, bool &succ)
- : Meta_tree_request(src_mod, src_chan, Meta_tree_request::ALLOC_PBA, mt, gen, pba, succ) { }
- };
-
- Meta_tree();
+ bool complete() const { return _helper.complete(); }
+ bool success() const { return _helper.success(); }
};
#endif /* _TRESOR__META_TREE_H_ */
diff --git a/repos/gems/src/lib/tresor/include/tresor/module.h b/repos/gems/src/lib/tresor/include/tresor/module.h
deleted file mode 100644
index 9c960c32fb..0000000000
--- a/repos/gems/src/lib/tresor/include/tresor/module.h
+++ /dev/null
@@ -1,223 +0,0 @@
-/*
- * \brief Framework for component internal modularization
- * \author Martin Stein
- * \date 2023-02-13
- */
-
-/*
- * Copyright (C) 2023 Genode Labs GmbH
- *
- * This file is part of the Genode OS framework, which is distributed
- * under the terms of the GNU Affero General Public License version 3.
- */
-
-#ifndef _TRESOR__MODULE_H_
-#define _TRESOR__MODULE_H_
-
-/* base includes */
-#include
-
-/* tresor includes */
-#include
-#include
-#include
-
-namespace Tresor {
-
- using namespace Genode;
-
- using Module_id = uint64_t;
- using Module_channel_id = uint64_t;
-
- enum { INVALID_MODULE_ID = ~(Module_id)0, INVALID_MODULE_CHANNEL_ID = ~(Module_channel_id)0 };
-
- enum Module_id_enum : Module_id {
- CRYPTO = 0, CLIENT_DATA = 1, TRUST_ANCHOR = 2, COMMAND_POOL = 3, BLOCK_IO = 4, CACHE = 5, META_TREE = 6,
- FREE_TREE = 7, VIRTUAL_BLOCK_DEVICE = 8, SUPERBLOCK_CONTROL = 9, VBD_INITIALIZER = 10, FT_INITIALIZER = 11,
- SB_INITIALIZER = 12, REQUEST_POOL = 13, SB_CHECK = 14, VBD_CHECK = 15, FT_CHECK = 16, SPLITTER = 17, MAX_MODULE_ID = 17 };
-
- char const *module_name(Module_id module_id);
-
- class Module_request;
- class Module_channel;
- class Module;
- class Module_composition;
-}
-
-
-class Tresor::Module_request : public Interface
-{
- private:
-
- Module_id _src_module_id;
- Module_channel_id _src_chan_id;
- Module_id _dst_module_id;
- Module_channel_id _dst_chan_id { INVALID_MODULE_CHANNEL_ID };
-
- NONCOPYABLE(Module_request);
-
- public:
-
- Module_request(Module_id, Module_channel_id, Module_id);
-
- void dst_chan_id(Module_channel_id id) { _dst_chan_id = id; }
-
- Module_id src_module_id() const { return _src_module_id; }
- Module_channel_id src_chan_id() const { return _src_chan_id; }
- Module_id dst_module_id() const { return _dst_module_id; }
- Module_channel_id dst_chan_id() const { return _dst_chan_id; }
-
- virtual void print(Output &) const = 0;
-
- virtual ~Module_request() { }
-};
-
-
-class Tresor::Module_channel : private Avl_node
-{
- friend class Module;
- friend class Avl_node;
- friend class Avl_tree;
-
- public:
-
- using State_uint = uint64_t;
-
- private:
-
- enum { GEN_REQ_BUF_SIZE = 4000 };
-
- enum Generated_request_state { NONE, PENDING, IN_PROGRESS };
-
- Module_request *_req_ptr { nullptr };
- Module_id _module_id;
- Module_channel_id _id;
- Generated_request_state _gen_req_state { NONE };
- uint8_t _gen_req_buf[GEN_REQ_BUF_SIZE] { };
- State_uint _gen_req_complete_state { 0 };
-
- NONCOPYABLE(Module_channel);
-
- bool higher(Module_channel *ptr) { return ptr->_id > _id; }
-
- virtual void _generated_req_completed(State_uint) { ASSERT_NEVER_REACHED; }
-
- virtual void _request_submitted(Module_request &) { ASSERT_NEVER_REACHED; }
-
- virtual bool _request_complete() { ASSERT_NEVER_REACHED; }
-
- public:
-
- Module_channel(Module_id module_id, Module_channel_id id) : _module_id { module_id }, _id { id } { };
-
- template
- void generate_req(State_uint complete_state, bool &progress, ARGS &&... args)
- {
- ASSERT(_gen_req_state == NONE);
- static_assert(sizeof(REQUEST) <= GEN_REQ_BUF_SIZE);
- construct_at(_gen_req_buf, _module_id, _id, args...);
- _gen_req_state = PENDING;
- _gen_req_complete_state = complete_state;
- progress = true;
- }
-
- template
- void with_channel(Module_channel_id id, FUNC && func)
- {
- if (id != _id) {
- Module_channel *chan_ptr { Avl_node::child(id > _id) };
- ASSERT(chan_ptr);
- chan_ptr->with_channel(id, func);
- } else
- func(*static_cast(this));
- }
-
- void generated_req_completed();
-
- bool try_submit_request(Module_request &);
-
- Module_channel_id id() const { return _id; }
-
- virtual ~Module_channel() { }
-};
-
-
-class Tresor::Module : public Interface
-{
- private:
-
- Avl_tree _channels { };
-
- NONCOPYABLE(Module);
-
- public:
-
- template
- void with_channel(Module_channel_id id, FUNC && func)
- {
- ASSERT(_channels.first());
- _channels.first()->with_channel(id, func);
- }
-
- template
- void for_each_channel(FUNC && func)
- {
- _channels.for_each([&] (Module_channel const &const_chan) {
- func(*static_cast(const_cast(&const_chan))); });
- }
-
- template
- void for_each_generated_request(FUNC && handle_request)
- {
- for_each_channel([&] (Module_channel &chan) {
- if (chan._gen_req_state != Module_channel::PENDING)
- return;
-
- Module_request &req = *(Module_request *)chan._gen_req_buf;
- if (handle_request(req)) {
- chan._gen_req_state = Module_channel::IN_PROGRESS;
- return;
- }
- });
- }
-
- template
- void for_each_completed_request(FUNC && handle_request)
- {
- for_each_channel([&] (Module_channel &chan) {
- if (chan._req_ptr && chan._request_complete()) {
- handle_request(*chan._req_ptr);
- chan._req_ptr = nullptr;
- }
- });
- return;
- }
-
- bool try_submit_request(Module_request &);
-
- void add_channel(Module_channel &chan) { _channels.insert(&chan); }
-
- Module() { }
-
- virtual ~Module() { }
-
- virtual void execute(bool &) { }
-};
-
-
-class Tresor::Module_composition
-{
- private:
-
- Module *_module_ptrs[MAX_MODULE_ID + 1] { };
-
- public:
-
- void add_module(Module_id module_id, Module &mod);
-
- void remove_module(Module_id module_id);
-
- void execute_modules();
-};
-
-#endif /* _TRESOR__MODULE_H_ */
diff --git a/repos/gems/src/lib/tresor/include/tresor/noncopyable.h b/repos/gems/src/lib/tresor/include/tresor/noncopyable.h
deleted file mode 100644
index 1ff52ef79c..0000000000
--- a/repos/gems/src/lib/tresor/include/tresor/noncopyable.h
+++ /dev/null
@@ -1,21 +0,0 @@
-/*
- * \brief Macro to make a class non-copyable
- * \author Martin Stein
- * \date 2023-06-09
- */
-
-/*
- * Copyright (C) 2023 Genode Labs GmbH
- *
- * This file is part of the Genode OS framework, which is distributed
- * under the terms of the GNU Affero General Public License version 3.
- */
-
-#ifndef _TRESOR__NONCOPYABLE_H_
-#define _TRESOR__NONCOPYABLE_H_
-
-#define NONCOPYABLE(class_name) \
- class_name(class_name const &) = delete; \
- class_name &operator = (class_name const &) = delete; \
-
-#endif /* _TRESOR__NONCOPYABLE_H_ */
diff --git a/repos/gems/src/lib/tresor/include/tresor/request_pool.h b/repos/gems/src/lib/tresor/include/tresor/request_pool.h
deleted file mode 100644
index 93a1dd9969..0000000000
--- a/repos/gems/src/lib/tresor/include/tresor/request_pool.h
+++ /dev/null
@@ -1,180 +0,0 @@
-/*
- * \brief Module for scheduling requests for processing
- * \author Martin Stein
- * \date 2023-03-17
- */
-
-/*
- * Copyright (C) 2023 Genode Labs GmbH
- *
- * This file is part of the Genode OS framework, which is distributed
- * under the terms of the GNU Affero General Public License version 3.
- */
-
-#ifndef _TRESOR__REQUEST_POOL_H_
-#define _TRESOR__REQUEST_POOL_H_
-
-/* tresor includes */
-#include
-#include
-
-namespace Tresor {
-
- class Request;
- class Request_pool;
- class Request_pool_channel;
- class Request_pool_channel_queue;
-}
-
-class Tresor::Request : public Module_request
-{
- NONCOPYABLE(Request);
-
- friend class Request_pool_channel;
-
- public:
-
- enum Operation {
- READ, WRITE, SYNC, CREATE_SNAPSHOT, DISCARD_SNAPSHOT, REKEY, EXTEND_VBD,
- EXTEND_FT, RESUME_REKEYING, DEINITIALIZE, INITIALIZE, };
-
- private:
-
- Operation _op;
- Virtual_block_address const _vba;
- Request_offset const _offset;
- Number_of_blocks const _count;
- Key_id const _key_id;
- Request_tag const _tag;
- Generation &_gen;
- bool &_success;
-
- public:
-
- static char const *op_to_string(Operation);
-
- Request(Module_id, Module_channel_id, Operation, Virtual_block_address, Request_offset,
- Number_of_blocks, Key_id, Request_tag, Generation &, bool &);
-
- void print(Output &) const override;
-};
-
-class Tresor::Request_pool_channel : public Module_channel
-{
- private:
-
- enum State : State_uint {
- INVALID, REQ_SUBMITTED, REQ_RESUMED, REQ_GENERATED, REKEY_INIT_SUCCEEDED, PREPONED_REQUESTS_COMPLETE,
- TREE_EXTENSION_STEP_SUCCEEDED, FORWARD_TO_SB_CTRL_SUCCEEDED, ACCESS_VBA_AT_SB_CTRL_SUCCEEDED,
- REKEY_VBA_SUCCEEDED, INITIALIZE_SB_CTRL_SUCCEEDED, DEINITIALIZE_SB_CTRL_SUCCEEDED, REQ_COMPLETE };
-
- State _state { INVALID };
- Number_of_blocks _num_blks { 0 };
- Superblock::State _sb_state { Superblock::INVALID };
- uint32_t _num_requests_preponed { 0 };
- bool _request_finished { false };
- bool _generated_req_success { false };
- Request_pool_channel_queue &_chan_queue;
- Request *_req_ptr { nullptr };
-
- NONCOPYABLE(Request_pool_channel);
-
- void _generated_req_completed(State_uint) override;
-
- void _request_submitted(Module_request &req) override;
-
- bool _request_complete() override { return _state == REQ_COMPLETE; }
-
- void _access_vbas(bool &, Superblock_control_request::Type);
-
- void _forward_to_sb_ctrl(bool &, Superblock_control_request::Type);
-
- void _gen_sb_control_req(bool &, Superblock_control_request::Type, State, Virtual_block_address);
-
- void _rekey(bool &);
-
- void _mark_req_successful(bool &);
-
- void _reset();
-
- void _try_prepone_requests(bool &);
-
- void _extend_tree(Superblock_control_request::Type, bool &);
-
- void _initialize(bool &);
-
- void _resume_request(bool &, Request::Operation);
-
- public:
-
- Request_pool_channel(Module_channel_id id, Request_pool_channel_queue &chan_queue) : Module_channel { REQUEST_POOL, id }, _chan_queue { chan_queue } { }
-
- void execute(bool &);
-};
-
-
-class Tresor::Request_pool_channel_queue
-{
- NONCOPYABLE(Request_pool_channel_queue);
-
- public:
-
- enum { NUM_SLOTS = 16 };
-
- private:
-
- using Channel = Request_pool_channel;
- using Slot_index = uint64_t;
- using Number_of_slots = uint64_t;
-
- Slot_index _head { 0 };
- Slot_index _tail { 0 };
- Number_of_slots _num_used_slots { 0 };
- Channel *_slots[NUM_SLOTS] { 0 };
-
- public:
-
- Request_pool_channel_queue() { }
-
- bool empty() const { return _num_used_slots == 0; }
-
- bool full() const { return _num_used_slots >= NUM_SLOTS; }
-
- Channel &head() const;
-
- void enqueue(Channel &);
-
- void move_one_slot_towards_tail(Channel const &);
-
- bool is_tail(Channel const &) const;
-
- Channel &next(Channel const &) const;
-
- void dequeue(Channel const &);
-};
-
-
-class Tresor::Request_pool : public Module
-{
- NONCOPYABLE(Request_pool);
-
- private:
-
- using Channel = Request_pool_channel;
-
- enum { NUM_CHANNELS = Request_pool_channel_queue::NUM_SLOTS };
-
- bool _init_success { false };
- Generation _init_gen { INVALID_GENERATION };
- Request _init_req { INVALID_MODULE_ID, INVALID_MODULE_CHANNEL_ID, Request::INITIALIZE, 0, 0, 0, 0, 0, _init_gen, _init_success };
- Constructible _channels[NUM_CHANNELS] { };
- Request_pool_channel_queue _chan_queue { };
-
- public:
-
- void execute(bool &) override;
-
- Request_pool();
-};
-
-#endif /* _TRESOR__REQUEST_POOL_H_ */
diff --git a/repos/gems/src/lib/tresor/include/tresor/sb_check.h b/repos/gems/src/lib/tresor/include/tresor/sb_check.h
index 76dad0a18a..1cace44139 100644
--- a/repos/gems/src/lib/tresor/include/tresor/sb_check.h
+++ b/repos/gems/src/lib/tresor/include/tresor/sb_check.h
@@ -16,95 +16,60 @@
/* tresor includes */
#include
+#include
+#include
+#include
-namespace Tresor {
+namespace Tresor { class Sb_check; }
- class Sb_check;
- class Sb_check_request;
- class Sb_check_channel;
-}
-
-
-class Tresor::Sb_check_request : public Module_request
+struct Tresor::Sb_check : Noncopyable
{
- friend class Sb_check_channel;
+ class Check : Noncopyable
+ {
+ public:
- private:
+ using Module = Sb_check;
- bool &_success;
+ private:
- NONCOPYABLE(Sb_check_request);
+ enum State {
+ INIT, COMPLETE, READ_BLK, READ_BLK_SUCCEEDED, CHECK_VBD, CHECK_VBD_SUCCEEDED, CHECK_FT, CHECK_FT_SUCCEEDED,
+ CHECK_MT, CHECK_MT_SUCCEEDED};
- public:
+ using Helper = Request_helper