genode/repos/gems/run/fs_query.run
Martin Stein 16c4aacf34 vfs/dir_fs: allow opening empty dirs
Adapts Dir_file_system::open_composite_dirs in a way that it returns "success"
when the leaf node of the path is an empty directory but "lookup failed", as
usual, if one of the other directories on the way to the leaf node is empty.

I couldn't find a technical reason why we used to return "lookup failed" when
only the leaf node was empty.

The commit also adds a test for en empty root directory and empty
sub-directories to the fs_query run script.

Fixes #4198
2021-06-25 11:41:45 +02:00

275 lines
7.5 KiB
Plaintext

create_boot_directory
if {[get_cmd_switch --autopilot] && [have_board riscv_qemu]} {
puts "Autopilot mode is not supported on this platform."
exit 0
}
import_from_depot \
[depot_user]/src/[base_src] \
[depot_user]/src/coreutils \
[depot_user]/src/bash \
[depot_user]/src/init \
[depot_user]/src/libc \
[depot_user]/src/fs_rom \
[depot_user]/src/posix \
[depot_user]/src/report_rom \
[depot_user]/src/vfs \
[depot_user]/src/vfs_import
install_config {
<config>
<parent-provides>
<service name="ROM"/>
<service name="LOG"/>
<service name="RM"/>
<service name="CPU"/>
<service name="PD"/>
<service name="IRQ"/>
<service name="IO_MEM"/>
<service name="IO_PORT"/>
</parent-provides>
<default-route>
<any-service> <parent/> <any-child/> </any-service>
</default-route>
<default caps="100"/>
<start name="timer">
<resource name="RAM" quantum="1M"/>
<provides> <service name="Timer"/> </provides>
</start>
<start name="report_rom">
<resource name="RAM" quantum="1M"/>
<provides> <service name="Report"/> <service name="ROM"/> </provides>
<config verbose="yes"/>
</start>
<start name="report_rom_empty_vfs">
<binary name="report_rom"/>
<resource name="RAM" quantum="1M"/>
<provides> <service name="Report"/> <service name="ROM"/> </provides>
<config verbose="yes"/>
</start>
<start name="vfs">
<resource name="RAM" quantum="10M"/>
<provides><service name="File_system"/></provides>
<config>
<vfs>
<tar name="bash.tar"/>
<tar name="coreutils.tar"/>
<ram/>
<import>
<dir name="items">
<inline name="1">first</inline>
<inline name="2">second</inline>
<inline name="3"><third/></inline>
</dir>
<inline name="4">fourth</inline>
</import>
</vfs>
<default-policy root="/" writeable="yes"/>
</config>
</start>
<start name="vfs_rom">
<resource name="RAM" quantum="10M"/>
<binary name="fs_rom"/>
<provides> <service name="ROM"/> </provides>
<config/>
<route>
<service name="File_system"> <child name="vfs"/> </service>
<any-service> <parent/> </any-service>
</route>
</start>
<start name="fs_query_empty_vfs" caps="120">
<binary name="fs_query"/>
<resource name="RAM" quantum="2M"/>
<config>
<vfs/>
<query path="/non_existent_1"/>
<query path="/non_existent_1/non_existent_2"/>
<query path="/"/>
</config>
<route>
<service name="Report">
<child name="report_rom_empty_vfs"/>
</service>
<any-service> <parent/> <any-child/> </any-service>
</route>
</start>
<start name="fs_query" caps="120">
<resource name="RAM" quantum="2M"/>
<config>
<vfs>
<dir name="empty"/>
<dir name="fs"> <fs writeable="yes"/> </dir>
</vfs>
<query path="/fs/items/non_existent_1"/>
<query path="/fs/items" content="yes"/>
<query path="/fs/non_existent_2" content="yes"/>
<query path="/empty" content="yes"/>
</config>
<route>
<service name="Report">
<child name="report_rom"/>
</service>
<any-service> <parent/> <any-child/> </any-service>
</route>
</start>
<start name="test" caps="700">
<binary name="sequence"/>
<resource name="RAM" quantum="20M"/>
<config>
<start name="/bin/sleep" caps="500">
<config>
<libc stdin="/dev/null" stdout="/dev/log" stderr="/dev/log"/>
<vfs> <dir name="dev"> <log/> <null/> </dir> </vfs>
<arg value="/bin/sleep"/>
<arg value="0.5"/>
</config>
</start>
<start name="/bin/rm" caps="500">
<config>
<libc stdin="/dev/null" stdout="/dev/log" stderr="/dev/log"/>
<vfs>
<dir name="fs"> <fs writeable="yes"/> </dir>
<dir name="dev"> <log/> <null/> </dir>
</vfs>
<arg value="/bin/rm"/>
<arg value="/fs/items/2"/>
</config>
</start>
<start name="/bin/sleep" caps="500">
<config>
<libc stdin="/dev/null" stdout="/dev/log" stderr="/dev/log"/>
<vfs> <dir name="dev"> <log/> <null/> </dir> </vfs>
<arg value="/bin/sleep"/>
<arg value="0.5"/>
</config>
</start>
<start name="/bin/cp" caps="500">
<config>
<libc stdin="/dev/null" stdout="/dev/log" stderr="/dev/log" rtc="/dev/null"/>
<vfs>
<dir name="fs"> <fs writeable="yes"/> </dir>
<dir name="dev"> <log/> <null/> </dir>
</vfs>
<arg value="/bin/cp"/>
<arg value="/fs/4"/>
<arg value="/fs/items/"/>
</config>
</start>
<start name="/bin/sleep" caps="500">
<config>
<libc stdin="/dev/null" stdout="/dev/log" stderr="/dev/log"/>
<vfs> <dir name="dev"> <log/> <null/> </dir> </vfs>
<arg value="/bin/sleep"/>
<arg value="0.5"/>
</config>
</start>
<start name="/bin/bash" caps="500">
<config>
<libc stdin="/dev/null" stdout="/dev/log" stderr="/dev/log" rtc="/dev/null"/>
<vfs>
<dir name="fs"> <fs writeable="yes"/> </dir>
<dir name="dev"> <log/> <null/> </dir>
</vfs>
<arg value="/bin/bash"/>
<arg value="-c"/>
<arg value="echo updated > /fs/items/3"/>
</config>
</start>
<start name="/bin/bash" caps="500">
<config>
<libc stdin="/dev/null" stdout="/dev/log" stderr="/dev/log" rtc="/dev/null"/>
<vfs>
<dir name="fs"> <fs writeable="yes"/> </dir>
<dir name="dev"> <log/> <null/> </dir>
</vfs>
<arg value="/bin/bash"/>
<arg value="-c"/>
<arg value="echo updated > /fs/items/3"/>
</config>
</start>
<start name="/bin/sleep" caps="500">
<config>
<libc stdin="/dev/null" stdout="/dev/log" stderr="/dev/log"/>
<vfs> <dir name="dev"> <log/> <null/> </dir> </vfs>
<arg value="/bin/sleep"/>
<arg value="0.5"/>
</config>
</start>
</config>
<route>
<service name="File_system"> <child name="vfs"/> </service>
<service name="ROM" label_suffix=".lib.so"> <parent/> </service>
<service name="ROM" label_prefix="/bin"> <child name="vfs_rom"/> </service>
<any-service> <parent/> <any-child/> </any-service>
</route>
</start>
</config>
}
build { app/sequence app/fs_query }
build_boot_image { sequence fs_query }
append qemu_args " -nographic "
run_genode_until {.*child "test" exited with exit value 0.*\n} 50
set original_output $output
grep_output {\[init -> report_rom\].*}
set num_listings [regexp -all {report 'fs_query -> listing'} $output dummy]
# we expect at least four intermediate reports
if {$num_listings < 4} {
puts "Error: Test failed with too few reports generated"
exit 1
}
#
# We cannot reliably compare the full output because some file operations
# may trigger one or two reports depending on the timing of signal delivery.
# However, we can at least check the last report for validity.
#
regsub {.*report 'fs_query -> listing'} $output {} output
compare_output_to {
[init -> report_rom] <listing>
[init -> report_rom] <dir path="/fs/items">
[init -> report_rom] <file name="1" writeable="yes">first</file>
[init -> report_rom] <file name="3" writeable="yes">updated
[init -> report_rom] </file>
[init -> report_rom] <file name="4" writeable="yes">fourth</file>
[init -> report_rom] </dir>
[init -> report_rom] <dir path="/empty"/>
[init -> report_rom] </listing>
}
set output $original_output
grep_output {\[init -> report_rom_empty_vfs\].*}
compare_output_to {
[init -> report_rom_empty_vfs] report 'fs_query_empty_vfs -> listing'
[init -> report_rom_empty_vfs] <listing>
[init -> report_rom_empty_vfs] <dir path="/"/>
[init -> report_rom_empty_vfs] </listing>
}