diff --git a/mon/make-osd.sh b/mon/make-osd.sh index d68eda3a..61ca7735 100755 --- a/mon/make-osd.sh +++ b/mon/make-osd.sh @@ -21,8 +21,8 @@ OSD_NUM=$(vitastor-cli alloc-osd) echo Creating OSD $OSD_NUM on $DEV -OPT=$(vitastor-cli simple-offsets --format options $DEV | tr '\n' ' ') -META=$(vitastor-cli simple-offsets --format json $DEV | jq .data_offset) +OPT=$(vitastor-disk simple-offsets --format options $DEV | tr '\n' ' ') +META=$(vitastor-disk simple-offsets --format json $DEV | jq .data_offset) dd if=/dev/zero of=$DEV bs=1048576 count=$(((META+1048575)/1048576)) oflag=direct mkdir -p /var/log/vitastor diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index 1941311b..2831b9c7 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -131,7 +131,6 @@ add_library(vitastor_client SHARED vitastor_c.cpp cli_common.cpp cli_alloc_osd.cpp - cli_simple_offsets.cpp cli_status.cpp cli_df.cpp cli_ls.cpp @@ -195,7 +194,7 @@ configure_file(vitastor.pc.in vitastor.pc @ONLY) # vitastor-disk add_executable(vitastor-disk - disk_tool.cpp crc32c.c rw_blocking.cpp allocator.cpp ringloop.cpp blockstore_disk.cpp + disk_tool.cpp disk_simple_offsets.cpp crc32c.c base64.cpp ../json11/json11.cpp rw_blocking.cpp allocator.cpp ringloop.cpp blockstore_disk.cpp ) target_link_libraries(vitastor-disk tcmalloc_minimal diff --git a/src/base64.cpp b/src/base64.cpp index a5f04769..24ce0902 100644 --- a/src/base64.cpp +++ b/src/base64.cpp @@ -1,6 +1,7 @@ // Copyright (c) Vitaliy Filippov, 2019+ // License: VNPL-1.1 (see README.md for details) +#include #include "base64.h" std::string base64_encode(const std::string &in) @@ -53,3 +54,73 @@ std::string base64_decode(const std::string &in) } return out; } + +uint64_t stoull_full(const std::string & str, int base) +{ + if (isspace(str[0])) + { + return 0; + } + char *end = NULL; + uint64_t r = strtoull(str.c_str(), &end, base); + if (end != str.c_str()+str.length()) + { + return 0; + } + return r; +} + +uint64_t parse_size(std::string size_str) +{ + if (!size_str.length()) + { + return 0; + } + uint64_t mul = 1; + char type_char = tolower(size_str[size_str.length()-1]); + if (type_char == 'k' || type_char == 'm' || type_char == 'g' || type_char == 't') + { + if (type_char == 'k') + mul = (uint64_t)1<<10; + else if (type_char == 'm') + mul = (uint64_t)1<<20; + else if (type_char == 'g') + mul = (uint64_t)1<<30; + else /*if (type_char == 't')*/ + mul = (uint64_t)1<<40; + size_str = size_str.substr(0, size_str.length()-1); + } + uint64_t size = stoull_full(size_str, 0) * mul; + if (size == 0 && size_str != "0" && (size_str != "" || mul != 1)) + { + return UINT64_MAX; + } + return size; +} + +static uint64_t size_thresh[] = { (uint64_t)1024*1024*1024*1024, (uint64_t)1024*1024*1024, (uint64_t)1024*1024, 1024, 0 }; +static uint64_t size_thresh_d[] = { (uint64_t)1000000000000, (uint64_t)1000000000, (uint64_t)1000000, (uint64_t)1000, 0 }; +static const int size_thresh_n = sizeof(size_thresh)/sizeof(size_thresh[0]); +static const char *size_unit = "TGMKB"; + +std::string format_size(uint64_t size, bool nobytes) +{ + uint64_t *thr = nobytes ? size_thresh_d : size_thresh; + char buf[256]; + for (int i = 0; i < size_thresh_n; i++) + { + if (size >= thr[i] || i >= size_thresh_n-1) + { + double value = thr[i] ? (double)size/thr[i] : size; + int l = snprintf(buf, sizeof(buf), "%.1f", value); + assert(l < sizeof(buf)-2); + if (buf[l-1] == '0') + l -= 2; + buf[l] = i == size_thresh_n-1 && nobytes ? 0 : ' '; + buf[l+1] = i == size_thresh_n-1 && nobytes ? 0 : size_unit[i]; + buf[l+2] = 0; + break; + } + } + return std::string(buf); +} diff --git a/src/base64.h b/src/base64.h index 68427e33..a1de2717 100644 --- a/src/base64.h +++ b/src/base64.h @@ -2,7 +2,11 @@ // License: VNPL-1.1 (see README.md for details) #pragma once +#include #include std::string base64_encode(const std::string &in); std::string base64_decode(const std::string &in); +uint64_t parse_size(std::string size_str); +uint64_t stoull_full(const std::string & str, int base = 0); +std::string format_size(uint64_t size, bool nobytes = false); diff --git a/src/cli.cpp b/src/cli.cpp index 52cd5776..564f6361 100644 --- a/src/cli.cpp +++ b/src/cli.cpp @@ -140,15 +140,6 @@ static void help() "\n" "%s alloc-osd\n" " Allocate a new OSD number and reserve it by creating empty /osd/stats/ key.\n" - "%s simple-offsets \n" - " Calculate offsets for simple&stupid (no superblock) OSD deployment. Options:\n" - " --object_size 128k Set blockstore block size\n" - " --bitmap_granularity 4k Set bitmap granularity\n" - " --journal_size 16M Set journal size\n" - " --device_block_size 4k Set device block size\n" - " --journal_offset 0 Set journal offset\n" - " --device_size 0 Set device size\n" - " --format text Result format: json, options, env, or text\n" "\n" "GLOBAL OPTIONS:\n" " --etcd_address \n" @@ -159,7 +150,7 @@ static void help() " --no-color Disable colored output\n" " --json JSON output\n" , - exe_name, exe_name, exe_name, exe_name, exe_name, exe_name, exe_name, + exe_name, exe_name, exe_name, exe_name, exe_name, exe_name, exe_name, exe_name, exe_name, exe_name, exe_name, exe_name ); exit(0); @@ -271,15 +262,6 @@ static int run(cli_tool_t *p, json11::Json::object cfg) // Allocate a new OSD number action_cb = p->start_alloc_osd(cfg); } - else if (cmd[0] == "simple-offsets") - { - // Calculate offsets for simple & stupid OSD deployment without superblock - if (cmd.size() > 1) - { - cfg["device"] = cmd[1]; - } - action_cb = p->simple_offsets(cfg); - } else { result = { .err = EINVAL, .text = "unknown command: "+cmd[0].string_value() }; diff --git a/src/cli.h b/src/cli.h index a82b27e9..2bcfbaf4 100644 --- a/src/cli.h +++ b/src/cli.h @@ -65,7 +65,6 @@ public: std::function start_flatten(json11::Json); std::function start_rm(json11::Json); std::function start_alloc_osd(json11::Json cfg); - std::function simple_offsets(json11::Json cfg); // Should be called like loop_and_wait(start_status(), ) void loop_and_wait(std::function loop_cb, std::function complete_cb); @@ -73,12 +72,8 @@ public: void etcd_txn(json11::Json txn); }; -uint64_t parse_size(std::string size_str); - std::string print_table(json11::Json items, json11::Json header, bool use_esc); -std::string format_size(uint64_t size, bool nobytes = false); - std::string format_lat(uint64_t lat); std::string format_q(double depth); diff --git a/src/cli_create.cpp b/src/cli_create.cpp index 8963838f..39a1d483 100644 --- a/src/cli_create.cpp +++ b/src/cli_create.cpp @@ -507,34 +507,6 @@ resume_3: } }; -uint64_t parse_size(std::string size_str) -{ - if (!size_str.length()) - { - return 0; - } - uint64_t mul = 1; - char type_char = tolower(size_str[size_str.length()-1]); - if (type_char == 'k' || type_char == 'm' || type_char == 'g' || type_char == 't') - { - if (type_char == 'k') - mul = (uint64_t)1<<10; - else if (type_char == 'm') - mul = (uint64_t)1<<20; - else if (type_char == 'g') - mul = (uint64_t)1<<30; - else /*if (type_char == 't')*/ - mul = (uint64_t)1<<40; - size_str = size_str.substr(0, size_str.length()-1); - } - uint64_t size = json11::Json(size_str).uint64_value() * mul; - if (size == 0 && size_str != "0" && (size_str != "" || mul != 1)) - { - return UINT64_MAX; - } - return size; -} - std::function cli_tool_t::start_create(json11::Json cfg) { auto image_creator = new image_creator_t(); diff --git a/src/cli_ls.cpp b/src/cli_ls.cpp index b75484bc..6f26e8e9 100644 --- a/src/cli_ls.cpp +++ b/src/cli_ls.cpp @@ -446,33 +446,6 @@ std::string print_table(json11::Json items, json11::Json header, bool use_esc) return str; } -static uint64_t size_thresh[] = { (uint64_t)1024*1024*1024*1024, (uint64_t)1024*1024*1024, (uint64_t)1024*1024, 1024, 0 }; -static uint64_t size_thresh_d[] = { (uint64_t)1000000000000, (uint64_t)1000000000, (uint64_t)1000000, (uint64_t)1000, 0 }; -static const int size_thresh_n = sizeof(size_thresh)/sizeof(size_thresh[0]); -static const char *size_unit = "TGMKB"; - -std::string format_size(uint64_t size, bool nobytes) -{ - uint64_t *thr = nobytes ? size_thresh_d : size_thresh; - char buf[256]; - for (int i = 0; i < size_thresh_n; i++) - { - if (size >= thr[i] || i >= size_thresh_n-1) - { - double value = thr[i] ? (double)size/thr[i] : size; - int l = snprintf(buf, sizeof(buf), "%.1f", value); - assert(l < sizeof(buf)-2); - if (buf[l-1] == '0') - l -= 2; - buf[l] = i == size_thresh_n-1 && nobytes ? 0 : ' '; - buf[l+1] = i == size_thresh_n-1 && nobytes ? 0 : size_unit[i]; - buf[l+2] = 0; - break; - } - } - return std::string(buf); -} - std::string format_lat(uint64_t lat) { char buf[256]; diff --git a/src/cli_simple_offsets.cpp b/src/disk_simple_offsets.cpp similarity index 96% rename from src/cli_simple_offsets.cpp rename to src/disk_simple_offsets.cpp index fc37e63e..27aa871b 100644 --- a/src/cli_simple_offsets.cpp +++ b/src/disk_simple_offsets.cpp @@ -5,13 +5,14 @@ #include #include #include -#include "cli.h" -#include "cluster_client.h" -#include "base64.h" #include +#include "json11/json11.hpp" +#include "base64.h" +#include "blockstore.h" + // Calculate offsets for a block device and print OSD command line parameters -std::function cli_tool_t::simple_offsets(json11::Json cfg) +void disk_tool_simple_offsets(json11::Json cfg, bool json_output) { std::string device = cfg["device"].string_value(); if (device == "") @@ -29,7 +30,7 @@ std::function cli_tool_t::simple_offsets(json11::Json cfg) if (json_output) format = "json"; if (!object_size) - object_size = DEFAULT_BLOCK_SIZE; + object_size = 1 << DEFAULT_DATA_BLOCK_ORDER; if (!bitmap_granularity) bitmap_granularity = DEFAULT_BITMAP_GRANULARITY; if (!journal_size) @@ -145,5 +146,4 @@ std::function cli_tool_t::simple_offsets(json11::Json cfg) device.c_str(), journal_offset, meta_offset, data_offset ); } - return NULL; } diff --git a/src/disk_tool.cpp b/src/disk_tool.cpp index 543ff23d..f60f6a2a 100644 --- a/src/disk_tool.cpp +++ b/src/disk_tool.cpp @@ -16,6 +16,7 @@ #include #include +#include "json11/json11.hpp" #include "blockstore_impl.h" #include "blockstore_disk.h" #include "osd_id.h" @@ -106,6 +107,8 @@ struct disk_tool_t int resize_write_new_meta(); }; +void disk_tool_simple_offsets(json11::Json cfg, bool json_output); + int main(int argc, char *argv[]) { disk_tool_t self = {}; @@ -177,20 +180,33 @@ int main(int argc, char *argv[]) { return self.resize_data(); } + else if (cmd.size() && !strcmp(cmd[0], "simple-offsets")) + { + // Calculate offsets for simple & stupid OSD deployment without superblock + if (cmd.size() > 1) + { + self.options["device"] = cmd[1]; + } + disk_tool_simple_offsets(self.options, self.json); + return 0; + } else { printf( + "Vitastor disk management tool\n" + "(c) Vitaliy Filippov, 2022+ (VNPL-1.1)\n" + "\n" "USAGE:\n" - " %s dump-journal [--all] [--json] \n" + "%s dump-journal [--all] [--json] \n" " Dump journal in human-readable or JSON (if --json is specified) format.\n" " Without --all, only actual part of the journal is dumped.\n" " With --all, the whole journal area is scanned for journal entries,\n" " some of which may be outdated.\n" "\n" - " %s dump-meta \n" + "%s dump-meta \n" " Dump metadata in JSON format.\n" "\n" - " %s resize [--iodepth 32]\n" + "%s resize [--iodepth 32]\n" " Resize data area and/or rewrite/move journal and metadata\n" " ALL_OSD_PARAMETERS must include all (at least all disk-related)\n" " parameters from OSD command line (i.e. from systemd unit).\n" @@ -205,8 +221,18 @@ int main(int argc, char *argv[]) " [--new_journal_len ] make new journal area bytes long\n" " If any of the new layout parameter options are not specified, old values\n" " will be used.\n" + "\n" + "%s simple-offsets \n" + " Calculate offsets for simple&stupid (no superblock) OSD deployment. Options:\n" + " --object_size 128k Set blockstore block size\n" + " --bitmap_granularity 4k Set bitmap granularity\n" + " --journal_size 16M Set journal size\n" + " --device_block_size 4k Set device block size\n" + " --journal_offset 0 Set journal offset\n" + " --device_size 0 Set device size\n" + " --format text Result format: json, options, env, or text\n" , - argv[0], argv[0], argv[0] + argv[0], argv[0], argv[0], argv[0] ); } return 0; diff --git a/src/http_client.cpp b/src/http_client.cpp index 1bd61e90..7d98e6ea 100644 --- a/src/http_client.cpp +++ b/src/http_client.cpp @@ -14,6 +14,7 @@ #include #include "addr_util.h" +#include "base64.h" #include "json11/json11.hpp" #include "http_client.h" #include "timerfd_manager.h" @@ -603,21 +604,6 @@ void http_co_t::next_request() } } -uint64_t stoull_full(const std::string & str, int base) -{ - if (isspace(str[0])) - { - return 0; - } - char *end = NULL; - uint64_t r = strtoull(str.c_str(), &end, base); - if (end != str.c_str()+str.length()) - { - return 0; - } - return r; -} - static void parse_http_headers(std::string & res, http_response_t *parsed) { int pos = res.find("\r\n"); diff --git a/src/http_client.h b/src/http_client.h index 8fc11b4a..29c5d8c4 100644 --- a/src/http_client.h +++ b/src/http_client.h @@ -50,7 +50,6 @@ void http_post_message(http_co_t *handler, int type, const std::string & msg); void http_close(http_co_t *co); // Utils -uint64_t stoull_full(const std::string & str, int base = 10); std::string strtolower(const std::string & in); // FIXME: move to json11 bool json_is_true(const json11::Json & val); diff --git a/tests/run_3osds.sh b/tests/run_3osds.sh index c5d3336a..f6d380fc 100644 --- a/tests/run_3osds.sh +++ b/tests/run_3osds.sh @@ -27,7 +27,7 @@ fi start_osd() { local i=$1 - build/src/vitastor-osd --osd_num $i --bind_address 127.0.0.1 $NO_SAME $OSD_ARGS --etcd_address $ETCD_URL $(build/src/vitastor-cli simple-offsets --format options ./testdata/test_osd$i.bin 2>/dev/null) &>./testdata/osd$i.log & + build/src/vitastor-osd --osd_num $i --bind_address 127.0.0.1 $NO_SAME $OSD_ARGS --etcd_address $ETCD_URL $(build/src/vitastor-disk simple-offsets --format options ./testdata/test_osd$i.bin 2>/dev/null) &>./testdata/osd$i.log & eval OSD${i}_PID=$! } diff --git a/tests/test_add_osd.sh b/tests/test_add_osd.sh index 9e9b57a3..718ab855 100755 --- a/tests/test_add_osd.sh +++ b/tests/test_add_osd.sh @@ -10,7 +10,7 @@ LD_PRELOAD="build/src/libfio_vitastor.so" \ for i in 4; do dd if=/dev/zero of=./testdata/test_osd$i.bin bs=1024 count=1 seek=$((OSD_SIZE*1024-1)) - build/src/vitastor-osd --osd_num $i --bind_address 127.0.0.1 $OSD_ARGS --etcd_address $ETCD_URL $(build/src/vitastor-cli simple-offsets --format options ./testdata/test_osd$i.bin 2>/dev/null) &>./testdata/osd$i.log & + build/src/vitastor-osd --osd_num $i --bind_address 127.0.0.1 $OSD_ARGS --etcd_address $ETCD_URL $(build/src/vitastor-disk simple-offsets --format options ./testdata/test_osd$i.bin 2>/dev/null) &>./testdata/osd$i.log & eval OSD${i}_PID=$! done diff --git a/tests/test_move_reappear.sh b/tests/test_move_reappear.sh index 406cb617..59abfe85 100755 --- a/tests/test_move_reappear.sh +++ b/tests/test_move_reappear.sh @@ -7,7 +7,7 @@ OSD_COUNT=5 OSD_ARGS= for i in $(seq 1 $OSD_COUNT); do dd if=/dev/zero of=./testdata/test_osd$i.bin bs=1024 count=1 seek=$((OSD_SIZE*1024-1)) - build/src/vitastor-osd --osd_num $i --bind_address 127.0.0.1 $OSD_ARGS --etcd_address $ETCD_URL $(build/src/vitastor-cli simple-offsets --format options ./testdata/test_osd$i.bin 2>/dev/null) &>./testdata/osd$i.log & + build/src/vitastor-osd --osd_num $i --bind_address 127.0.0.1 $OSD_ARGS --etcd_address $ETCD_URL $(build/src/vitastor-disk simple-offsets --format options ./testdata/test_osd$i.bin 2>/dev/null) &>./testdata/osd$i.log & eval OSD${i}_PID=$! done diff --git a/tests/test_resize.sh b/tests/test_resize.sh index e4f6faf5..fdc05814 100755 --- a/tests/test_resize.sh +++ b/tests/test_resize.sh @@ -23,13 +23,13 @@ for i in $(seq 1 $OSD_COUNT); do done for i in $(seq 1 $OSD_COUNT); do - offsets=$(build/src/vitastor-cli simple-offsets --format json ./testdata/test_osd$i.bin) + offsets=$(build/src/vitastor-disk simple-offsets --format json ./testdata/test_osd$i.bin) meta_offset=$(echo $offsets | jq -r .meta_offset) data_offset=$(echo $offsets | jq -r .data_offset) build/src/vitastor-disk dump-journal --json ./testdata/test_osd$i.bin 4096 0 $meta_offset >./testdata/journal_before_resize.json build/src/vitastor-disk dump-meta ./testdata/test_osd$i.bin 4096 $meta_offset $((data_offset-meta_offset)) >./testdata/meta_before_resize.json build/src/vitastor-disk resize \ - $(build/src/vitastor-cli simple-offsets --format options ./testdata/test_osd$i.bin 2>/dev/null) \ + $(build/src/vitastor-disk simple-offsets --format options ./testdata/test_osd$i.bin 2>/dev/null) \ --new_meta_offset 0 \ --new_meta_len $((1024*1024)) \ --new_journal_offset $((1024*1024)) \ diff --git a/tests/test_splitbrain.sh b/tests/test_splitbrain.sh index 48bc75d1..b992481e 100755 --- a/tests/test_splitbrain.sh +++ b/tests/test_splitbrain.sh @@ -21,7 +21,7 @@ LD_PRELOAD="build/src/libfio_vitastor.so" \ # Kill OSD 2, start OSD 1 kill $OSD2_PID -build/src/vitastor-osd --osd_num 1 --bind_address 127.0.0.1 $OSD_ARGS --etcd_address $ETCD_URL $(build/src/vitastor-cli simple-offsets --format options --device ./testdata/test_osd2.bin 2>/dev/null) >>./testdata/osd2.log 2>&1 & +build/src/vitastor-osd --osd_num 1 --bind_address 127.0.0.1 $OSD_ARGS --etcd_address $ETCD_URL $(build/src/vitastor-disk simple-offsets --format options --device ./testdata/test_osd2.bin 2>/dev/null) >>./testdata/osd2.log 2>&1 & sleep 2 # Check PG state - it should NOT become active diff --git a/tests/test_vm_cont.sh b/tests/test_vm_cont.sh index 2f554156..5431c917 100755 --- a/tests/test_vm_cont.sh +++ b/tests/test_vm_cont.sh @@ -10,7 +10,7 @@ etcdctl --endpoints=http://127.0.0.1:12379/v3 del --prefix /vitastor/osd/state OSD_COUNT=3 OSD_ARGS= for i in $(seq 1 $OSD_COUNT); do - build/src/vitastor-osd --osd_num $i --bind_address 127.0.0.1 $OSD_ARGS --etcd_address $ETCD_URL $(build/src/vitastor-cli simple-offsets --format options ./testdata/test_osd$i.bin 2>/dev/null) &>./testdata/osd$i.log & + build/src/vitastor-osd --osd_num $i --bind_address 127.0.0.1 $OSD_ARGS --etcd_address $ETCD_URL $(build/src/vitastor-disk simple-offsets --format options ./testdata/test_osd$i.bin 2>/dev/null) &>./testdata/osd$i.log & eval OSD${i}_PID=$! done