Compare commits

...

1 Commits

Author SHA1 Message Date
8dd49393f2 Exit with code 1 instead of aborting when the OSD fails to open its devices
Blockstore errors at startup, such as a data device that cannot be opened,
escaped from the etcd callback that creates the blockstore, and configuration
errors escaped from osd_t construction. vitastor-osd then died with
"terminate called after throwing std::runtime_error" and a core dump. Print
the error and exit with code 1, so that a startup error can be told from a
crash. Other exceptions still abort.
2026-10-26 21:03:12 +03:00
5 changed files with 59 additions and 8 deletions

View File

@@ -1913,6 +1913,24 @@ jobs:
echo ""
done
test_osd_open_error:
runs-on: ubuntu-latest
needs: build
container: ${{env.TEST_IMAGE}}:${{github.sha}}
steps:
- name: Run test
id: test
timeout-minutes: 3
run: /root/vitastor/tests/test_osd_open_error.sh
- name: Print logs
if: always() && steps.test.outcome == 'failure'
run: |
for i in /root/vitastor/testdata/*.log /root/vitastor/testdata/*.txt; do
echo "-------- $i --------"
cat $i
echo ""
done
test_enospc:
runs-on: ubuntu-latest
needs: build

View File

@@ -236,7 +236,16 @@ void osd_t::init_blockstore(std::function<void()> on_init)
if (!json_is_true(this->config["disable_blockstore"]))
{
auto bs_cfg = json_to_string_map(this->config);
this->bs = bs_factory(bs_cfg);
try
{
this->bs = bs_factory(bs_cfg);
}
catch (std::exception & e)
{
fprintf(stderr, "[OSD %ju] %s\n", this->osd_num, e.what());
force_stop(1);
return;
}
// Pre-configure pool PG shards
for (auto & pool_item: st_cli->pool_config)
{

View File

@@ -67,13 +67,21 @@ int main(int narg, char *args[])
ring_loop_t *ringloop = new ring_loop_t(RINGLOOP_DEFAULT_SIZE);
epoll_manager_t *epmgr = new epoll_manager_t(ringloop);
auto st_cli = new etcd_state_client_http_t(epmgr->tfd);
osd = new osd_t(
config, ringloop, epmgr->tfd, std::unique_ptr<etcd_state_client_t>(st_cli),
[ringloop, tfd = epmgr->tfd](blockstore_config_t & cfg)
{
return blockstore_i::create(cfg, ringloop, tfd);
}
);
try
{
osd = new osd_t(
config, ringloop, epmgr->tfd, std::unique_ptr<etcd_state_client_t>(st_cli),
[ringloop, tfd = epmgr->tfd](blockstore_config_t & cfg)
{
return blockstore_i::create(cfg, ringloop, tfd);
}
);
}
catch (std::exception & e)
{
fprintf(stderr, "%s\n", e.what());
return 1;
}
osd->start();
while (1)
{

View File

@@ -149,6 +149,8 @@ OLD=1 ./test_resize_auto.sh
./test_osd_tags.sh
./test_osd_open_error.sh
./test_enospc.sh
SCHEME=xor ./test_enospc.sh
IMMEDIATE_COMMIT=1 ./test_enospc.sh

14
tests/test_osd_open_error.sh Executable file
View File

@@ -0,0 +1,14 @@
#!/bin/bash -ex
# An OSD that cannot open its data device must exit with code 1, not abort with a core dump
. `dirname $0`/common.sh
wait_etcd
code=0
build/src/osd/vitastor-osd --osd_num 1 --data_device ./testdata/bin/missing --etcd_address $ETCD_URL &> ./testdata/osd1.log || code=$?
grep -q 'Failed to open data device' ./testdata/osd1.log || format_error "OSD did not report the open error"
[[ $code -eq 1 ]] || format_error "OSD exited with code $code instead of 1"
format_green OK