Compare commits

..
34 Commits
Author SHA1 Message Date
Vitaliy Filippov a9ef9a86c0 Add update() API to kv_db 2024-01-06 17:14:42 +03:00
Vitaliy Filippov 25832cb7e4 Fix eviction when random_pos selects the end 2024-01-02 13:24:15 +03:00
Vitaliy Filippov e6326c6539 Implement min/max list_count to make listings during performance test reasonable 2024-01-02 13:24:15 +03:00
Vitaliy Filippov e32f382815 Fix and improve parallel allocation
- Do not try to allocate more DB blocks in an inode block until it's "confirmed" and "locked" by the first write
- Do not recheck for new zero DB blocks on first write into an inode block - a CAS failure means someone else is already writing into it
- Throw new allocation blocks away regardless of whether the known_version is 0 on a CAS failure
2024-01-02 13:24:15 +03:00
Vitaliy Filippov fb23d94000 Implement key_prefix for K/V stress test 2024-01-02 13:24:15 +03:00
Vitaliy Filippov ee462c2dad More fixes
- do not overwrite a block with older version if known version is newer
  (read may start before update and end after update)
- invalidated block versions can't be remembered and trusted
- right boundary for split blocks is right_half when diving down, not key_lt
- restart update also when block is "invalidated", not just on version mismatch
- copy callback in listings to avoid closure destruction bugs too
2024-01-02 13:24:15 +03:00
Vitaliy Filippov 16e4c767f1 Add logging and one more assert 2024-01-02 13:24:15 +03:00
Vitaliy Filippov 9e2b677499 Make get_block() wait for updating when unrelated block is found along the path 2024-01-02 13:24:15 +03:00
Vitaliy Filippov fd57096d2d Fix a race condition where changed blocks were parsed over existing cached blocks and getting a mix of data 2024-01-02 13:24:15 +03:00
Vitaliy Filippov e5ae907256 Simplify code by removing an unneeded "optimisation" 2024-01-02 13:24:15 +03:00
Vitaliy Filippov 64fd6f1c56 Add kv_log_level, print warnings on level 1, trace ops on level 10 2024-01-02 13:24:15 +03:00
Vitaliy Filippov 6e76e09d16 Fix duplicate keys in listings on parallel updates -- do not rewind key "iterator position" 2024-01-02 13:24:15 +03:00
Vitaliy Filippov 0964aeebd2 Implement key suffix to avoid collisions of multiple test workers 2024-01-02 13:24:15 +03:00
Vitaliy Filippov facff20ca1 Do not complain on empty first block 2024-01-02 13:24:15 +03:00
Vitaliy Filippov 16e09745f0 Add JSON output for stress-tester 2024-01-02 13:24:15 +03:00
Vitaliy Filippov 442f44a64f Print total stats 2024-01-02 13:24:15 +03:00
Vitaliy Filippov c67e3d56cb Do not send more than op_count operations (fix segfault on finish) 2024-01-02 13:24:15 +03:00
Vitaliy Filippov de41e46335 Add some more resiliency to serialize() 2024-01-02 13:24:15 +03:00
Vitaliy Filippov bf9a279ff9 Invalidate blocks being updated too 2024-01-02 13:24:15 +03:00
Vitaliy Filippov b7a41e6394 Change new block allocation method: make each writer choose multiple empty PG blocks and place blocks in them 2024-01-02 13:24:15 +03:00
Vitaliy Filippov 4175cb3720 Remove blocks from cache on unsuccessful updates 2024-01-02 13:24:15 +03:00
Vitaliy Filippov 3a4b71b0cd Allow to track multiple updates per block (it should never happen though) 2024-01-02 13:24:14 +03:00
Vitaliy Filippov 34969c5919 Do not call stop_updating after failed write_new_block and after clear_block (both delete the item) 2024-01-02 13:24:14 +03:00
Vitaliy Filippov 02a8df6586 Track versions of parent blocks and recheck if changed during update 2024-01-02 13:24:14 +03:00
Vitaliy Filippov 86c6482cf3 Fix resume_split condition (key_lt can also be "") 2024-01-02 13:24:14 +03:00
Vitaliy Filippov 4dd68c543c Experiment: transform offsets for better sharding 2024-01-02 13:24:14 +03:00
Vitaliy Filippov 10ad96c56c More post-stress-test fixes
- Prevent _split types of new blocks
- Stop updating new blocks only after the whole update, otherwise pointers
  may become invalid
- Use recheck_none for updates initially
- Use UINT64_MAX as initial block version when postponing ops, otherwise the
  check fails when the block is initially empty. This for example leads to
  writing both leaf items & block pointers (which is incorrect) into the root
  block when starting stress-test with --parallelism 32
- Fix -EINTR comparison
2024-01-02 13:24:14 +03:00
Vitaliy Filippov 6e451117ce Print operation statistics 2024-01-02 13:24:14 +03:00
Vitaliy Filippov 85f35bdf30 K/V fixes after stress-test :-)
- track block versions correctly - per inode block (128kb) instead of tree block (4kb)
- prevent multiple parallel CAS writes of the same inode block
- add logging for EILSEQ which means invalid data in the tree
- fix get_block updated flag which was true for blocks already in cache and was leading to infinite loops on "unrelated block" errors
- apply changes to blocks in cache only after successful writes (using "virtual changes")
- do not replace cached block with an older version from disk
- recheck "unrelated blocks" (read/update collisions) until data stops changing
- track tree path correctly - do not treat split block as parent of its right half
- correctly move blocks when finding new empty place on disk
- restart updates from the beginning when one of blocks is changed by a parallel update
- fix delete using SET opcode and setting key to the empty value instead
- prevent changing the same key more than 1 time in parallel
- fix listing verification
- resume continue_updates in update_find (required because it uses continue_update itself)
- add allow_old_cached parameter to get()
2024-01-02 13:24:14 +03:00
Vitaliy Filippov 09adaf62fd Implement K/V DB stress tester 2024-01-02 13:24:14 +03:00
Vitaliy Filippov af93f8323c Evict blocks based on memory limit & block usage 2024-01-02 13:24:14 +03:00
Vitaliy Filippov 3d29c76ff4 Track blocks per level 2024-01-02 13:24:14 +03:00
Vitaliy Filippov 19275379c1 Track block level 2024-01-02 13:24:14 +03:00
Vitaliy Filippov 96ad3c7c50 Experimental B-Tree Vitastor embedded K/V database implementation! 2024-01-02 13:24:14 +03:00
127 changed files with 3807 additions and 1698 deletions
+1 -19
View File
@@ -395,7 +395,7 @@ jobs:
steps: steps:
- name: Run test - name: Run test
id: test id: test
timeout-minutes: 6 timeout-minutes: 3
run: SCHEME=ec /root/vitastor/tests/test_snapshot_chain.sh run: SCHEME=ec /root/vitastor/tests/test_snapshot_chain.sh
- name: Print logs - name: Print logs
if: always() && steps.test.outcome == 'failure' if: always() && steps.test.outcome == 'failure'
@@ -532,24 +532,6 @@ jobs:
echo "" echo ""
done done
test_switch_primary:
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_switch_primary.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_write: test_write:
runs-on: ubuntu-latest runs-on: ubuntu-latest
needs: build needs: build
-4
View File
@@ -39,10 +39,6 @@ for my $line (<>)
$test_name .= '_'.lc($1).'_'.$2; $test_name .= '_'.lc($1).'_'.$2;
} }
} }
if ($test_name eq 'test_snapshot_chain_ec')
{
$timeout = 6;
}
$line =~ s!\./test_!/root/vitastor/tests/test_!; $line =~ s!\./test_!/root/vitastor/tests/test_!;
# Gitea CI doesn't support artifacts yet, lol # Gitea CI doesn't support artifacts yet, lol
#- name: Upload results #- name: Upload results
+2 -2
View File
@@ -38,7 +38,7 @@ in the offer.
on behalf of third parties, including on behalf of his employer. on behalf of third parties, including on behalf of his employer.
2. Subject of the Agreement. \ 2. Subject of the Agreement. \
2.1. Subject of the Agreement shall be the Contributions sent to the Author by Contributors. \ 2.1. Subject of the Agreement shall be the Contributions sent to the Author by Contributors.
2.2. The Contributor grants to the Author the right to use Contributions at his own 2.2. The Contributor grants to the Author the right to use Contributions at his own
discretion and without any necessity to get a prior approval from Contributor or discretion and without any necessity to get a prior approval from Contributor or
any other third party in any way, under a simple (non-exclusive), royalty-free, any other third party in any way, under a simple (non-exclusive), royalty-free,
@@ -86,7 +86,7 @@ in the offer.
of their provision to the Author. \ of their provision to the Author. \
5.2. The Contributor represents and warrants that he legally owns exclusive 5.2. The Contributor represents and warrants that he legally owns exclusive
intellectual property rights to the Contributions. \ intellectual property rights to the Contributions. \
5.3. The Contributor represents and warrants that any further use of 5.3. The Contributor represents and warrants that any further use of \
Contributions by the Author as provided by Contributor under the terms Contributions by the Author as provided by Contributor under the terms
of the Agreement does not infringe on intellectual and other rights and of the Agreement does not infringe on intellectual and other rights and
legitimate interests of third parties. \ legitimate interests of third parties. \
+1 -1
View File
@@ -2,6 +2,6 @@ cmake_minimum_required(VERSION 2.8.12)
project(vitastor) project(vitastor)
set(VERSION "1.4.7") set(VERSION "1.3.1")
add_subdirectory(src) add_subdirectory(src)
+1 -1
View File
@@ -1,4 +1,4 @@
VERSION ?= v1.4.7 VERSION ?= v1.3.1
all: build push all: build push
+1 -1
View File
@@ -49,7 +49,7 @@ spec:
capabilities: capabilities:
add: ["SYS_ADMIN"] add: ["SYS_ADMIN"]
allowPrivilegeEscalation: true allowPrivilegeEscalation: true
image: vitalif/vitastor-csi:v1.4.7 image: vitalif/vitastor-csi:v1.3.1
args: args:
- "--node=$(NODE_ID)" - "--node=$(NODE_ID)"
- "--endpoint=$(CSI_ENDPOINT)" - "--endpoint=$(CSI_ENDPOINT)"
+1 -1
View File
@@ -121,7 +121,7 @@ spec:
privileged: true privileged: true
capabilities: capabilities:
add: ["SYS_ADMIN"] add: ["SYS_ADMIN"]
image: vitalif/vitastor-csi:v1.4.7 image: vitalif/vitastor-csi:v1.3.1
args: args:
- "--node=$(NODE_ID)" - "--node=$(NODE_ID)"
- "--endpoint=$(CSI_ENDPOINT)" - "--endpoint=$(CSI_ENDPOINT)"
+1 -1
View File
@@ -5,7 +5,7 @@ package vitastor
const ( const (
vitastorCSIDriverName = "csi.vitastor.io" vitastorCSIDriverName = "csi.vitastor.io"
vitastorCSIDriverVersion = "1.4.7" vitastorCSIDriverVersion = "1.3.1"
) )
// Config struct fills the parameters of request or user input // Config struct fills the parameters of request or user input
+1 -1
View File
@@ -188,6 +188,7 @@ func (ns *NodeServer) unmapNbd(devicePath string)
func findByPidFile(pidFile string) (*os.Process, error) func findByPidFile(pidFile string) (*os.Process, error)
{ {
klog.Infof("killing process with PID from file %s", pidFile)
pidBuf, err := os.ReadFile(pidFile) pidBuf, err := os.ReadFile(pidFile)
if (err != nil) if (err != nil)
{ {
@@ -208,7 +209,6 @@ func findByPidFile(pidFile string) (*os.Process, error)
func killByPidFile(pidFile string) error func killByPidFile(pidFile string) error
{ {
klog.Infof("killing process with PID from file %s", pidFile)
proc, err := findByPidFile(pidFile) proc, err := findByPidFile(pidFile)
if (err != nil) if (err != nil)
{ {
+1 -1
View File
@@ -1,4 +1,4 @@
vitastor (1.4.7-1) unstable; urgency=medium vitastor (1.3.1-1) unstable; urgency=medium
* Bugfixes * Bugfixes
+4 -4
View File
@@ -35,8 +35,8 @@ RUN set -e -x; \
mkdir -p /root/packages/vitastor-$REL; \ mkdir -p /root/packages/vitastor-$REL; \
rm -rf /root/packages/vitastor-$REL/*; \ rm -rf /root/packages/vitastor-$REL/*; \
cd /root/packages/vitastor-$REL; \ cd /root/packages/vitastor-$REL; \
cp -r /root/vitastor vitastor-1.4.7; \ cp -r /root/vitastor vitastor-1.3.1; \
cd vitastor-1.4.7; \ cd vitastor-1.3.1; \
ln -s /root/fio-build/fio-*/ ./fio; \ ln -s /root/fio-build/fio-*/ ./fio; \
FIO=$(head -n1 fio/debian/changelog | perl -pe 's/^.*\((.*?)\).*$/$1/'); \ FIO=$(head -n1 fio/debian/changelog | perl -pe 's/^.*\((.*?)\).*$/$1/'); \
ls /usr/include/linux/raw.h || cp ./debian/raw.h /usr/include/linux/raw.h; \ ls /usr/include/linux/raw.h || cp ./debian/raw.h /usr/include/linux/raw.h; \
@@ -49,8 +49,8 @@ RUN set -e -x; \
rm -rf a b; \ rm -rf a b; \
echo "dep:fio=$FIO" > debian/fio_version; \ echo "dep:fio=$FIO" > debian/fio_version; \
cd /root/packages/vitastor-$REL; \ cd /root/packages/vitastor-$REL; \
tar --sort=name --mtime='2020-01-01' --owner=0 --group=0 --exclude=debian -cJf vitastor_1.4.7.orig.tar.xz vitastor-1.4.7; \ tar --sort=name --mtime='2020-01-01' --owner=0 --group=0 --exclude=debian -cJf vitastor_1.3.1.orig.tar.xz vitastor-1.3.1; \
cd vitastor-1.4.7; \ cd vitastor-1.3.1; \
V=$(head -n1 debian/changelog | perl -pe 's/^.*\((.*?)\).*$/$1/'); \ V=$(head -n1 debian/changelog | perl -pe 's/^.*\((.*?)\).*$/$1/'); \
DEBFULLNAME="Vitaliy Filippov <vitalif@yourcmc.ru>" dch -D $REL -v "$V""$REL" "Rebuild for $REL"; \ DEBFULLNAME="Vitaliy Filippov <vitalif@yourcmc.ru>" dch -D $REL -v "$V""$REL" "Rebuild for $REL"; \
DEB_BUILD_OPTIONS=nocheck dpkg-buildpackage --jobs=auto -sa; \ DEB_BUILD_OPTIONS=nocheck dpkg-buildpackage --jobs=auto -sa; \
+2 -2
View File
@@ -19,8 +19,8 @@ These parameters only apply to Monitors.
## etcd_mon_ttl ## etcd_mon_ttl
- Type: seconds - Type: seconds
- Default: 1 - Default: 30
- Minimum: 5 - Minimum: 10
Monitor etcd lease refresh interval in seconds Monitor etcd lease refresh interval in seconds
+2 -2
View File
@@ -19,8 +19,8 @@
## etcd_mon_ttl ## etcd_mon_ttl
- Тип: секунды - Тип: секунды
- Значение по умолчанию: 1 - Значение по умолчанию: 30
- Минимальное значение: 5 - Минимальное значение: 10
Интервал обновления etcd резервации (lease) монитором Интервал обновления etcd резервации (lease) монитором
+2 -2
View File
@@ -215,8 +215,8 @@ is scheduled.
## up_wait_retry_interval ## up_wait_retry_interval
- Type: milliseconds - Type: milliseconds
- Default: 50 - Default: 500
- Minimum: 10 - Minimum: 50
- Can be changed online: yes - Can be changed online: yes
OSDs respond to clients with a special error code when they receive I/O OSDs respond to clients with a special error code when they receive I/O
+2 -2
View File
@@ -224,8 +224,8 @@ OSD в любом случае согласовывают реальное зн
## up_wait_retry_interval ## up_wait_retry_interval
- Тип: миллисекунды - Тип: миллисекунды
- Значение по умолчанию: 50 - Значение по умолчанию: 500
- Минимальное значение: 10 - Минимальное значение: 50
- Можно менять на лету: да - Можно менять на лету: да
Когда OSD получают от клиентов запросы ввода-вывода, относящиеся к не Когда OSD получают от клиентов запросы ввода-вывода, относящиеся к не
+2 -12
View File
@@ -59,7 +59,6 @@ them, even without restarting by updating configuration in etcd.
- [recovery_tune_client_util_high](#recovery_tune_client_util_high) - [recovery_tune_client_util_high](#recovery_tune_client_util_high)
- [recovery_tune_agg_interval](#recovery_tune_agg_interval) - [recovery_tune_agg_interval](#recovery_tune_agg_interval)
- [recovery_tune_sleep_min_us](#recovery_tune_sleep_min_us) - [recovery_tune_sleep_min_us](#recovery_tune_sleep_min_us)
- [recovery_tune_sleep_cutoff_us](#recovery_tune_sleep_cutoff_us)
## etcd_report_interval ## etcd_report_interval
@@ -605,14 +604,5 @@ is usually fine.
- Default: 10 - Default: 10
- Can be changed online: yes - Can be changed online: yes
Minimum possible value for auto-tuned recovery_sleep_us. Lower values Minimum possible value for auto-tuned recovery_sleep_us. Values lower
are changed to 0. than this value are changed to 0.
## recovery_tune_sleep_cutoff_us
- Type: microseconds
- Default: 10000000
- Can be changed online: yes
Maximum possible value for auto-tuned recovery_sleep_us. Higher values
are treated as outliers and ignored in aggregation.
+1 -12
View File
@@ -60,7 +60,6 @@
- [recovery_tune_client_util_high](#recovery_tune_client_util_high) - [recovery_tune_client_util_high](#recovery_tune_client_util_high)
- [recovery_tune_agg_interval](#recovery_tune_agg_interval) - [recovery_tune_agg_interval](#recovery_tune_agg_interval)
- [recovery_tune_sleep_min_us](#recovery_tune_sleep_min_us) - [recovery_tune_sleep_min_us](#recovery_tune_sleep_min_us)
- [recovery_tune_sleep_cutoff_us](#recovery_tune_sleep_cutoff_us)
## etcd_report_interval ## etcd_report_interval
@@ -635,14 +634,4 @@ EC (кодов коррекции ошибок) с более, чем 1 диск
- Можно менять на лету: да - Можно менять на лету: да
Минимальное возможное значение авто-подстроенного recovery_sleep_us. Минимальное возможное значение авто-подстроенного recovery_sleep_us.
Меньшие значения заменяются на 0. Значения ниже данного заменяются на 0.
## recovery_tune_sleep_cutoff_us
- Тип: микросекунды
- Значение по умолчанию: 10000000
- Можно менять на лету: да
Максимальное возможное значение авто-подстроенного recovery_sleep_us.
Большие значения считаются случайными выбросами и игнорируются в
усреднении.
-3
View File
@@ -154,9 +154,6 @@ That is, if it becomes impossible to place PG data on at least (pg_minsize)
OSDs, PG is deactivated for both read and write. So you know that a fresh OSDs, PG is deactivated for both read and write. So you know that a fresh
write always goes to at least (pg_minsize) OSDs (disks). write always goes to at least (pg_minsize) OSDs (disks).
That is, pg_size minus pg_minsize sets the number of disk failures to tolerate
without temporary downtime (for [osd_out_time](monitor.en.md#osd_out_time)).
FIXME: pg_minsize behaviour may be changed in the future to only make PGs FIXME: pg_minsize behaviour may be changed in the future to only make PGs
read-only instead of deactivating them. read-only instead of deactivating them.
-4
View File
@@ -157,10 +157,6 @@
OSD, PG деактивируется на чтение и запись. Иными словами, всегда известно, OSD, PG деактивируется на чтение и запись. Иными словами, всегда известно,
что новые блоки данных всегда записываются как минимум на pg_minsize дисков. что новые блоки данных всегда записываются как минимум на pg_minsize дисков.
По сути, разница pg_size и pg_minsize задаёт число отказов дисков, которые пул
может пережить без временной (на [osd_out_time](monitor.ru.md#osd_out_time))
остановки обслуживания.
FIXME: Поведение pg_minsize может быть изменено в будущем с полной деактивации FIXME: Поведение pg_minsize может быть изменено в будущем с полной деактивации
PG на перевод их в режим только для чтения. PG на перевод их в режим только для чтения.
+2 -2
View File
@@ -1,7 +1,7 @@
- name: etcd_mon_ttl - name: etcd_mon_ttl
type: sec type: sec
min: 5 min: 10
default: 1 default: 30
info: Monitor etcd lease refresh interval in seconds info: Monitor etcd lease refresh interval in seconds
info_ru: Интервал обновления etcd резервации (lease) монитором info_ru: Интервал обновления etcd резервации (lease) монитором
- name: etcd_mon_timeout - name: etcd_mon_timeout
+2 -2
View File
@@ -245,8 +245,8 @@
повторная попытка соединения. повторная попытка соединения.
- name: up_wait_retry_interval - name: up_wait_retry_interval
type: ms type: ms
min: 10 min: 50
default: 50 default: 500
online: true online: true
info: | info: |
OSDs respond to clients with a special error code when they receive I/O OSDs respond to clients with a special error code when they receive I/O
+3 -14
View File
@@ -731,19 +731,8 @@
default: 10 default: 10
online: true online: true
info: | info: |
Minimum possible value for auto-tuned recovery_sleep_us. Lower values Minimum possible value for auto-tuned recovery_sleep_us. Values lower
are changed to 0. than this value are changed to 0.
info_ru: | info_ru: |
Минимальное возможное значение авто-подстроенного recovery_sleep_us. Минимальное возможное значение авто-подстроенного recovery_sleep_us.
Меньшие значения заменяются на 0. Значения ниже данного заменяются на 0.
- name: recovery_tune_sleep_cutoff_us
type: us
default: 10000000
online: true
info: |
Maximum possible value for auto-tuned recovery_sleep_us. Higher values
are treated as outliers and ignored in aggregation.
info_ru: |
Максимальное возможное значение авто-подстроенного recovery_sleep_us.
Большие значения считаются случайными выбросами и игнорируются в
усреднении.
-1
View File
@@ -37,7 +37,6 @@ Vitastor CSI supports:
- Volume snapshots. Example: [snapshot class](../../csi/deploy/example-snapshot-class.yaml), [snapshot](../../csi/deploy/example-snapshot.yaml), [clone](../../csi/deploy/example-snapshot-clone.yaml) - Volume snapshots. Example: [snapshot class](../../csi/deploy/example-snapshot-class.yaml), [snapshot](../../csi/deploy/example-snapshot.yaml), [clone](../../csi/deploy/example-snapshot-clone.yaml)
- [VDUSE](../usage/qemu.en.md#vduse) (preferred) and [NBD](../usage/nbd.en.md) device mapping methods - [VDUSE](../usage/qemu.en.md#vduse) (preferred) and [NBD](../usage/nbd.en.md) device mapping methods
- Upgrades with VDUSE - new handler processes are restarted when CSI pods are restarted themselves - Upgrades with VDUSE - new handler processes are restarted when CSI pods are restarted themselves
- VDUSE daemon auto-restart - handler processes are automatically restarted if they crash due to a bug in Vitastor client code
- Multiple clusters by using multiple configuration files in ConfigMap. - Multiple clusters by using multiple configuration files in ConfigMap.
Remember that to use snapshots with CSI you also have to install [Snapshot Controller and CRDs](https://kubernetes-csi.github.io/docs/snapshot-controller.html#deployment). Remember that to use snapshots with CSI you also have to install [Snapshot Controller and CRDs](https://kubernetes-csi.github.io/docs/snapshot-controller.html#deployment).
-1
View File
@@ -37,7 +37,6 @@ CSI-плагин Vitastor поддерживает:
- Снимки томов. Пример: [класс снимков](../../csi/deploy/example-snapshot-class.yaml), [снимок](../../csi/deploy/example-snapshot.yaml), [клон снимка](../../csi/deploy/example-snapshot-clone.yaml) - Снимки томов. Пример: [класс снимков](../../csi/deploy/example-snapshot-class.yaml), [снимок](../../csi/deploy/example-snapshot.yaml), [клон снимка](../../csi/deploy/example-snapshot-clone.yaml)
- Способы подключения устройств [VDUSE](../usage/qemu.ru.md#vduse) (предпочитаемый) и [NBD](../usage/nbd.ru.md) - Способы подключения устройств [VDUSE](../usage/qemu.ru.md#vduse) (предпочитаемый) и [NBD](../usage/nbd.ru.md)
- Обновление при использовании VDUSE - новые процессы-обработчики устройств успешно перезапускаются вместе с самими подами CSI - Обновление при использовании VDUSE - новые процессы-обработчики устройств успешно перезапускаются вместе с самими подами CSI
- Автоперезауск демонов VDUSE - процесс-обработчик автоматически перезапустится, если он внезапно упадёт из-за бага в коде клиента Vitastor
- Несколько кластеров через задание нескольких файлов конфигурации в ConfigMap. - Несколько кластеров через задание нескольких файлов конфигурации в ConfigMap.
Не забывайте, что для использования снимков нужно сначала установить [контроллер снимков и CRD](https://kubernetes-csi.github.io/docs/snapshot-controller.html#deployment). Не забывайте, что для использования снимков нужно сначала установить [контроллер снимков и CRD](https://kubernetes-csi.github.io/docs/snapshot-controller.html#deployment).
+7 -14
View File
@@ -11,26 +11,19 @@ Replicated setups:
- Single-threaded write+fsync latency: - Single-threaded write+fsync latency:
- With immediate commit: 2 network roundtrips + 1 disk write. - With immediate commit: 2 network roundtrips + 1 disk write.
- With lazy commit: 4 network roundtrips + 1 disk write + 1 disk flush. - With lazy commit: 4 network roundtrips + 1 disk write + 1 disk flush.
- Linear read: `min(total network bandwidth, sum(disk read MB/s))`. - Saturated parallel read iops: min(network bandwidth, sum(disk read iops)).
- Linear write: `min(total network bandwidth, sum(disk write MB/s / number of replicas))`. - Saturated parallel write iops: min(network bandwidth, sum(disk write iops / number of replicas / write amplification)).
- Saturated parallel read iops: `min(total network bandwidth, sum(disk read iops))`.
- Saturated parallel write iops: `min(total network bandwidth / number of replicas, sum(disk write iops / number of replicas / (write amplification = 4)))`.
EC/XOR setups (EC N+K): EC/XOR setups:
- Single-threaded (T1Q1) read latency: 1.5 network roundtrips + 1 disk read. - Single-threaded (T1Q1) read latency: 1.5 network roundtrips + 1 disk read.
- Single-threaded write+fsync latency: - Single-threaded write+fsync latency:
- With immediate commit: 3.5 network roundtrips + 1 disk read + 2 disk writes. - With immediate commit: 3.5 network roundtrips + 1 disk read + 2 disk writes.
- With lazy commit: 5.5 network roundtrips + 1 disk read + 2 disk writes + 2 disk fsyncs. - With lazy commit: 5.5 network roundtrips + 1 disk read + 2 disk writes + 2 disk fsyncs.
- 0.5 in actually `(N-1)/N` which means that an additional roundtrip doesn't happen when - 0.5 in actually (k-1)/k which means that an additional roundtrip doesn't happen when
the read sub-operation can be served locally. the read sub-operation can be served locally.
- Linear read: `min(total network bandwidth, sum(disk read MB/s))`. - Saturated parallel read iops: min(network bandwidth, sum(disk read iops)).
- Linear write: `min(total network bandwidth, sum(disk write MB/s * N/(N+K)))`. - Saturated parallel write iops: min(network bandwidth, sum(disk write iops * number of data drives / (number of data + parity drives) / write amplification)).
- Saturated parallel read iops: `min(total network bandwidth, sum(disk read iops))`. In fact, you should put disk write iops under the condition of ~10% reads / ~90% writes in this formula.
- Saturated parallel write iops: roughly `total iops / (N+K) / WA`. More exactly,
`min(total network bandwidth * N/(N+K), sum(disk randrw iops / (N*4 + K*5 + 1)))` with
random read/write mix corresponding to `(N-1)/(N*4 + K*5 + 1)*100 % reads`.
- For example, with EC 2+1 it is: `(7% randrw iops) / 14`.
- With EC 6+3 it is: `(12.5% randrw iops) / 40`.
Write amplification for 4 KB blocks is usually 3-5 in Vitastor: Write amplification for 4 KB blocks is usually 3-5 in Vitastor:
1. Journal block write 1. Journal block write
+7 -14
View File
@@ -11,27 +11,20 @@
- Запись+fsync в 1 поток: - Запись+fsync в 1 поток:
- С мгновенным сбросом: 2 RTT + 1 запись. - С мгновенным сбросом: 2 RTT + 1 запись.
- С отложенным ("ленивым") сбросом: 4 RTT + 1 запись + 1 fsync. - С отложенным ("ленивым") сбросом: 4 RTT + 1 запись + 1 fsync.
- Линейное чтение: сумма МБ/с чтения всех дисков, либо общая производительность сети (сумма пропускной способности сети всех нод), если в сеть упрётся раньше. - Параллельное чтение: сумма IOPS всех дисков либо производительность сети, если в сеть упрётся раньше.
- Линейная запись: сумма МБ/с записи всех дисков / число реплик, либо производительность сети / число реплик, если в сеть упрётся раньше. - Параллельная запись: сумма IOPS всех дисков / число реплик / WA либо производительность сети, если в сеть упрётся раньше.
- Параллельное случайное мелкое чтение: сумма IOPS чтения всех дисков, либо производительность сети, если в сеть упрётся раньше.
- Параллельная случайная мелкая запись: сумма IOPS записи всех дисков / число реплик / WA, либо производительность сети / число реплик, если в сеть упрётся раньше.
При использовании кодов коррекции ошибок (EC N+K): При использовании кодов коррекции ошибок (EC):
- Задержка чтения в 1 поток (T1Q1): 1.5 RTT + 1 чтение. - Задержка чтения в 1 поток (T1Q1): 1.5 RTT + 1 чтение.
- Запись+fsync в 1 поток: - Запись+fsync в 1 поток:
- С мгновенным сбросом: 3.5 RTT + 1 чтение + 2 записи. - С мгновенным сбросом: 3.5 RTT + 1 чтение + 2 записи.
- С отложенным ("ленивым") сбросом: 5.5 RTT + 1 чтение + 2 записи + 2 fsync. - С отложенным ("ленивым") сбросом: 5.5 RTT + 1 чтение + 2 записи + 2 fsync.
- Под 0.5 на самом деле подразумевается (N-1)/N, где N - число дисков данных, - Под 0.5 на самом деле подразумевается (k-1)/k, где k - число дисков данных,
что означает, что дополнительное обращение по сети не нужно, когда операция что означает, что дополнительное обращение по сети не нужно, когда операция
чтения обслуживается локально. чтения обслуживается локально.
- Линейное чтение: сумма МБ/с чтения всех дисков, либо общая производительность сети, если в сеть упрётся раньше. - Параллельное чтение: сумма IOPS всех дисков либо производительность сети, если в сеть упрётся раньше.
- Линейная запись: сумма МБ/с записи всех дисков * N/(N+K), либо производительность сети * N / (N+K), если в сеть упрётся раньше. - Параллельная запись: сумма IOPS всех дисков / общее число дисков данных и чётности / WA либо производительность сети, если в сеть упрётся раньше.
- Параллельное случайное мелкое чтение: сумма IOPS чтения всех дисков либо производительность сети, если в сеть упрётся раньше. Примечание: IOPS дисков в данном случае надо брать в смешанном режиме чтения/записи в пропорции, аналогичной формулам выше.
- Параллельная случайная мелкая запись: грубо `(сумма IOPS / (N+K) / WA)`. Если точнее, то:
сумма смешанного IOPS всех дисков при `(N-1)/(N*4 + K*5 + 1)*100 %` чтения, делённая на `(N*4 + K*5 + 1)`.
Либо, производительность сети * N/(N+K), если в сеть упрётся раньше.
- Например, при EC 2+1 это: `(сумма IOPS при 7% чтения) / 14`.
- При EC 6+3 это: `(сумма IOPS при 12.5% чтения) / 40`.
WA (мультипликатор записи) для 4 КБ блоков в Vitastor обычно составляет 3-5: WA (мультипликатор записи) для 4 КБ блоков в Vitastor обычно составляет 3-5:
1. Запись метаданных в журнал 1. Запись метаданных в журнал
+1 -1
View File
@@ -261,7 +261,7 @@ Options (see also [Cluster-Wide Disk Layout Parameters](../config/layout-cluster
``` ```
--object_size 128k Set blockstore block size --object_size 128k Set blockstore block size
--bitmap_granularity 4k Set bitmap granularity --bitmap_granularity 4k Set bitmap granularity
--journal_size 32M Set journal size --journal_size 16M Set journal size
--data_csum_type none Set data checksum type (crc32c or none) --data_csum_type none Set data checksum type (crc32c or none)
--csum_block_size 4k Set data checksum block size --csum_block_size 4k Set data checksum block size
--device_block_size 4k Set device block size --device_block_size 4k Set device block size
+1 -1
View File
@@ -267,7 +267,7 @@ OSD отключены fsync-и.
``` ```
--object_size 128k Размер блока хранилища --object_size 128k Размер блока хранилища
--bitmap_granularity 4k Гранулярность битовых карт --bitmap_granularity 4k Гранулярность битовых карт
--journal_size 32M Размер журнала --journal_size 16M Размер журнала
--data_csum_type none Задать тип контрольных сумм (crc32c или none) --data_csum_type none Задать тип контрольных сумм (crc32c или none)
--csum_block_size 4k Задать размер блока расчёта контрольных сумм --csum_block_size 4k Задать размер блока расчёта контрольных сумм
--device_block_size 4k Размер блока устройства --device_block_size 4k Размер блока устройства
+18 -49
View File
@@ -55,7 +55,7 @@ const etcd_tree = {
// etcd connection - configurable online // etcd connection - configurable online
etcd_address: "10.0.115.10:2379/v3", etcd_address: "10.0.115.10:2379/v3",
// mon // mon
etcd_mon_ttl: 5, // min: 1 etcd_mon_ttl: 30, // min: 10
etcd_mon_timeout: 1000, // ms. min: 0 etcd_mon_timeout: 1000, // ms. min: 0
etcd_mon_retries: 5, // min: 0 etcd_mon_retries: 5, // min: 0
mon_change_timeout: 1000, // ms. min: 100 mon_change_timeout: 1000, // ms. min: 100
@@ -92,7 +92,7 @@ const etcd_tree = {
peer_connect_timeout: 5, // seconds. min: 1 peer_connect_timeout: 5, // seconds. min: 1
osd_idle_timeout: 5, // seconds. min: 1 osd_idle_timeout: 5, // seconds. min: 1
osd_ping_timeout: 5, // seconds. min: 1 osd_ping_timeout: 5, // seconds. min: 1
up_wait_retry_interval: 50, // ms. min: 10 up_wait_retry_interval: 500, // ms. min: 50
max_etcd_attempts: 5, max_etcd_attempts: 5,
etcd_quick_timeout: 1000, // ms etcd_quick_timeout: 1000, // ms
etcd_slow_timeout: 5000, // ms etcd_slow_timeout: 5000, // ms
@@ -390,8 +390,7 @@ class Mon
{ {
constructor(config) constructor(config)
{ {
this.failconnect = (e) => this._die(e, 2); this.die = (e) => this._die(e);
this.die = (e) => this._die(e, 1);
if (fs.existsSync(config.config_path||'/etc/vitastor/vitastor.conf')) if (fs.existsSync(config.config_path||'/etc/vitastor/vitastor.conf'))
{ {
config = { config = {
@@ -480,10 +479,10 @@ class Mon
check_config() check_config()
{ {
this.config.etcd_mon_ttl = Number(this.config.etcd_mon_ttl) || 5; this.config.etcd_mon_ttl = Number(this.config.etcd_mon_ttl) || 30;
if (this.config.etcd_mon_ttl < 1) if (this.config.etcd_mon_ttl < 10)
{ {
this.config.etcd_mon_ttl = 1; this.config.etcd_mon_ttl = 10;
} }
this.config.etcd_mon_timeout = Number(this.config.etcd_mon_timeout) || 0; this.config.etcd_mon_timeout = Number(this.config.etcd_mon_timeout) || 0;
if (this.config.etcd_mon_timeout <= 0) if (this.config.etcd_mon_timeout <= 0)
@@ -605,7 +604,7 @@ class Mon
} }
if (!this.ws) if (!this.ws)
{ {
this.failconnect('Failed to open etcd watch websocket'); this.die('Failed to open etcd watch websocket');
} }
const cur_addr = this.selected_etcd_url; const cur_addr = this.selected_etcd_url;
this.ws_alive = true; this.ws_alive = true;
@@ -675,12 +674,7 @@ class Mon
{ {
this.parse_kv(e.kv); this.parse_kv(e.kv);
const key = e.kv.key.substr(this.etcd_prefix.length); const key = e.kv.key.substr(this.etcd_prefix.length);
if (key.substr(0, 11) == '/osd/state/') if (key.substr(0, 11) == '/osd/stats/' || key.substr(0, 10) == '/pg/stats/' || key.substr(0, 16) == '/osd/inodestats/')
{
stats_changed = true;
changed = true;
}
else if (key.substr(0, 11) == '/osd/stats/' || key.substr(0, 10) == '/pg/stats/' || key.substr(0, 16) == '/osd/inodestats/')
{ {
stats_changed = true; stats_changed = true;
} }
@@ -797,9 +791,9 @@ class Mon
const res = await this.etcd_call('/lease/keepalive', { ID: this.etcd_lease_id }, this.config.etcd_mon_timeout, this.config.etcd_mon_retries); const res = await this.etcd_call('/lease/keepalive', { ID: this.etcd_lease_id }, this.config.etcd_mon_timeout, this.config.etcd_mon_retries);
if (!res.result.TTL) if (!res.result.TTL)
{ {
this.failconnect('Lease expired'); this.die('Lease expired');
} }
}, this.config.etcd_mon_ttl*1000); }, this.config.etcd_mon_timeout);
if (!this.signals_set) if (!this.signals_set)
{ {
process.on('SIGINT', this.on_stop_cb); process.on('SIGINT', this.on_stop_cb);
@@ -1420,14 +1414,7 @@ class Mon
} }
if (changed) if (changed)
{ {
const ok = await this.save_pg_config(new_config_pgs); await this.save_pg_config(new_config_pgs);
if (ok)
console.log('PG configuration successfully changed');
else
{
console.log('Someone changed PG configuration while we also tried to change it. Retrying in '+this.config.mon_change_timeout+' ms');
this.schedule_recheck();
}
} }
} }
this.recheck_pgs_active = false; this.recheck_pgs_active = false;
@@ -1508,11 +1495,6 @@ class Mon
this.save_new_pgs_txn(new_config_pgs, etcd_request, pool_id, up_osds, osd_tree, real_prev_pgs, pool_res.pgs, pg_history); this.save_new_pgs_txn(new_config_pgs, etcd_request, pool_id, up_osds, osd_tree, real_prev_pgs, pool_res.pgs, pg_history);
} }
new_config_pgs.hash = tree_hash; new_config_pgs.hash = tree_hash;
return await this.save_pg_config(new_config_pgs, etcd_request);
}
async save_pg_config(new_config_pgs, etcd_request = { compare: [], success: [] })
{
etcd_request.compare.push( etcd_request.compare.push(
{ key: b64(this.etcd_prefix+'/mon/master'), target: 'LEASE', lease: ''+this.etcd_lease_id }, { key: b64(this.etcd_prefix+'/mon/master'), target: 'LEASE', lease: ''+this.etcd_lease_id },
{ key: b64(this.etcd_prefix+'/config/pgs'), target: 'MOD', mod_revision: ''+this.etcd_watch_revision, result: 'LESS' }, { key: b64(this.etcd_prefix+'/config/pgs'), target: 'MOD', mod_revision: ''+this.etcd_watch_revision, result: 'LESS' },
@@ -1640,13 +1622,9 @@ class Mon
} }
const sum_diff = { op_stats: {}, subop_stats: {}, recovery_stats: {} }; const sum_diff = { op_stats: {}, subop_stats: {}, recovery_stats: {} };
// Sum derived values instead of deriving summed // Sum derived values instead of deriving summed
for (const osd in this.state.osd.state) for (const osd in this.state.osd.stats)
{ {
const derived = this.prev_stats.osd_diff[osd]; const derived = this.prev_stats.osd_diff[osd];
if (!this.state.osd.state[osd] || !derived)
{
continue;
}
for (const type in sum_diff) for (const type in sum_diff)
{ {
for (const op in derived[type]||{}) for (const op in derived[type]||{})
@@ -1747,13 +1725,9 @@ class Mon
const used = this.state.pool.stats[pool_id].used_raw_tb; const used = this.state.pool.stats[pool_id].used_raw_tb;
this.state.pool.stats[pool_id].used_raw_tb = Number(used)/1024/1024/1024/1024; this.state.pool.stats[pool_id].used_raw_tb = Number(used)/1024/1024/1024/1024;
} }
for (const osd_num in this.state.osd.state) for (const osd_num in this.state.osd.inodestats)
{ {
const ist = this.state.osd.inodestats[osd_num]; const ist = this.state.osd.inodestats[osd_num];
if (!ist || !this.state.osd.state[osd_num])
{
continue;
}
for (const pool_id in ist) for (const pool_id in ist)
{ {
inode_stats[pool_id] = inode_stats[pool_id] || {}; inode_stats[pool_id] = inode_stats[pool_id] || {};
@@ -1769,14 +1743,9 @@ class Mon
} }
} }
} }
for (const osd in this.state.osd.state) for (const osd in this.prev_stats.osd_diff)
{ {
const osd_diff = this.prev_stats.osd_diff[osd]; for (const pool_id in this.prev_stats.osd_diff[osd].inode_stats)
if (!osd_diff || !this.state.osd.state[osd])
{
continue;
}
for (const pool_id in osd_diff.inode_stats)
{ {
for (const inode_num in this.prev_stats.osd_diff[osd].inode_stats[pool_id]) for (const inode_num in this.prev_stats.osd_diff[osd].inode_stats[pool_id])
{ {
@@ -2016,14 +1985,14 @@ class Mon
return res.json; return res.json;
} }
} }
this.failconnect(); this.die();
} }
_die(err, code) _die(err)
{ {
// In fact we can just try to rejoin // In fact we can just try to rejoin
console.error(new Error(err || 'Cluster connection failed')); console.error(new Error(err || 'Cluster connection failed'));
process.exit(code || 2); process.exit(1);
} }
local_ips(all) local_ips(all)
+1 -1
View File
@@ -1,6 +1,6 @@
{ {
"name": "vitastor-mon", "name": "vitastor-mon",
"version": "1.4.7", "version": "1.3.1",
"description": "Vitastor SDS monitor service", "description": "Vitastor SDS monitor service",
"main": "mon-main.js", "main": "mon-main.js",
"scripts": { "scripts": {
+1 -3
View File
@@ -8,9 +8,7 @@ PartOf=vitastor.target
LimitNOFILE=1048576 LimitNOFILE=1048576
LimitNPROC=1048576 LimitNPROC=1048576
LimitMEMLOCK=infinity LimitMEMLOCK=infinity
# Use the following for direct logs to files ExecStart=bash -c 'exec vitastor-disk exec-osd /dev/vitastor/osd%i-data >>/var/log/vitastor/osd%i.log 2>&1'
#ExecStart=bash -c 'exec vitastor-disk exec-osd /dev/vitastor/osd%i-data >>/var/log/vitastor/osd%i.log 2>&1'
ExecStart=vitastor-disk exec-osd /dev/vitastor/osd%i-data
ExecStartPre=+vitastor-disk pre-exec /dev/vitastor/osd%i-data ExecStartPre=+vitastor-disk pre-exec /dev/vitastor/osd%i-data
WorkingDirectory=/ WorkingDirectory=/
User=vitastor User=vitastor
+1 -1
View File
@@ -50,7 +50,7 @@ from cinder.volume import configuration
from cinder.volume import driver from cinder.volume import driver
from cinder.volume import volume_utils from cinder.volume import volume_utils
VERSION = '1.4.7' VERSION = '1.3.1'
LOG = logging.getLogger(__name__) LOG = logging.getLogger(__name__)
-643
View File
@@ -1,643 +0,0 @@
commit c1cd026e211e94b120028e7c98a6e4ce5afe9846
Author: Vitaliy Filippov <vitalif@yourcmc.ru>
Date: Wed Jan 24 22:04:50 2024 +0300
Add Vitastor support
diff --git a/include/libvirt/libvirt-storage.h b/include/libvirt/libvirt-storage.h
index aaad4a3da1..5f5daa8341 100644
--- a/include/libvirt/libvirt-storage.h
+++ b/include/libvirt/libvirt-storage.h
@@ -326,6 +326,7 @@ typedef enum {
VIR_CONNECT_LIST_STORAGE_POOLS_ZFS = 1 << 17, /* (Since: 1.2.8) */
VIR_CONNECT_LIST_STORAGE_POOLS_VSTORAGE = 1 << 18, /* (Since: 3.1.0) */
VIR_CONNECT_LIST_STORAGE_POOLS_ISCSI_DIRECT = 1 << 19, /* (Since: 5.6.0) */
+ VIR_CONNECT_LIST_STORAGE_POOLS_VITASTOR = 1 << 20, /* (Since: 5.0.0) */
} virConnectListAllStoragePoolsFlags;
int virConnectListAllStoragePools(virConnectPtr conn,
diff --git a/src/conf/domain_conf.c b/src/conf/domain_conf.c
index 22ad43e1d7..56c81d6852 100644
--- a/src/conf/domain_conf.c
+++ b/src/conf/domain_conf.c
@@ -7185,7 +7185,8 @@ virDomainDiskSourceNetworkParse(xmlNodePtr node,
src->configFile = virXPathString("string(./config/@file)", ctxt);
if (src->protocol == VIR_STORAGE_NET_PROTOCOL_HTTP ||
- src->protocol == VIR_STORAGE_NET_PROTOCOL_HTTPS)
+ src->protocol == VIR_STORAGE_NET_PROTOCOL_HTTPS ||
+ src->protocol == VIR_STORAGE_NET_PROTOCOL_VITASTOR)
src->query = virXMLPropString(node, "query");
if (virDomainStorageNetworkParseHosts(node, ctxt, &src->hosts, &src->nhosts) < 0)
@@ -30618,6 +30619,7 @@ virDomainStorageSourceTranslateSourcePool(virStorageSource *src,
case VIR_STORAGE_POOL_MPATH:
case VIR_STORAGE_POOL_RBD:
+ case VIR_STORAGE_POOL_VITASTOR:
case VIR_STORAGE_POOL_SHEEPDOG:
case VIR_STORAGE_POOL_GLUSTER:
case VIR_STORAGE_POOL_LAST:
diff --git a/src/conf/domain_validate.c b/src/conf/domain_validate.c
index c72108886e..c739ed6c43 100644
--- a/src/conf/domain_validate.c
+++ b/src/conf/domain_validate.c
@@ -495,6 +495,7 @@ virDomainDiskDefValidateSourceChainOne(const virStorageSource *src)
case VIR_STORAGE_NET_PROTOCOL_RBD:
break;
+ case VIR_STORAGE_NET_PROTOCOL_VITASTOR:
case VIR_STORAGE_NET_PROTOCOL_NBD:
case VIR_STORAGE_NET_PROTOCOL_SHEEPDOG:
case VIR_STORAGE_NET_PROTOCOL_GLUSTER:
@@ -541,7 +542,7 @@ virDomainDiskDefValidateSourceChainOne(const virStorageSource *src)
}
}
- /* internal snapshots and config files are currently supported only with rbd: */
+ /* internal snapshots are currently supported only with rbd: */
if (virStorageSourceGetActualType(src) != VIR_STORAGE_TYPE_NETWORK &&
src->protocol != VIR_STORAGE_NET_PROTOCOL_RBD) {
if (src->snapshot) {
@@ -549,10 +550,15 @@ virDomainDiskDefValidateSourceChainOne(const virStorageSource *src)
_("<snapshot> element is currently supported only with 'rbd' disks"));
return -1;
}
+ }
+ /* config files are currently supported only with rbd and vitastor: */
+ if (virStorageSourceGetActualType(src) != VIR_STORAGE_TYPE_NETWORK &&
+ src->protocol != VIR_STORAGE_NET_PROTOCOL_RBD &&
+ src->protocol != VIR_STORAGE_NET_PROTOCOL_VITASTOR) {
if (src->configFile) {
virReportError(VIR_ERR_XML_ERROR, "%s",
- _("<config> element is currently supported only with 'rbd' disks"));
+ _("<config> element is currently supported only with 'rbd' and 'vitastor' disks"));
return -1;
}
}
diff --git a/src/conf/schemas/domaincommon.rng b/src/conf/schemas/domaincommon.rng
index b98a2ae602..7d7a872e01 100644
--- a/src/conf/schemas/domaincommon.rng
+++ b/src/conf/schemas/domaincommon.rng
@@ -1997,6 +1997,35 @@
</element>
</define>
+ <define name="diskSourceNetworkProtocolVitastor">
+ <element name="source">
+ <interleave>
+ <attribute name="protocol">
+ <value>vitastor</value>
+ </attribute>
+ <ref name="diskSourceCommon"/>
+ <optional>
+ <attribute name="name"/>
+ </optional>
+ <optional>
+ <attribute name="query"/>
+ </optional>
+ <zeroOrMore>
+ <ref name="diskSourceNetworkHost"/>
+ </zeroOrMore>
+ <optional>
+ <element name="config">
+ <attribute name="file">
+ <ref name="absFilePath"/>
+ </attribute>
+ <empty/>
+ </element>
+ </optional>
+ <empty/>
+ </interleave>
+ </element>
+ </define>
+
<define name="diskSourceNetworkProtocolISCSI">
<element name="source">
<attribute name="protocol">
@@ -2347,6 +2376,7 @@
<ref name="diskSourceNetworkProtocolSimple"/>
<ref name="diskSourceNetworkProtocolVxHS"/>
<ref name="diskSourceNetworkProtocolNFS"/>
+ <ref name="diskSourceNetworkProtocolVitastor"/>
</choice>
</define>
diff --git a/src/conf/storage_conf.c b/src/conf/storage_conf.c
index 68842004b7..1d69a788b6 100644
--- a/src/conf/storage_conf.c
+++ b/src/conf/storage_conf.c
@@ -56,7 +56,7 @@ VIR_ENUM_IMPL(virStoragePool,
"logical", "disk", "iscsi",
"iscsi-direct", "scsi", "mpath",
"rbd", "sheepdog", "gluster",
- "zfs", "vstorage",
+ "zfs", "vstorage", "vitastor",
);
VIR_ENUM_IMPL(virStoragePoolFormatFileSystem,
@@ -242,6 +242,18 @@ static virStoragePoolTypeInfo poolTypeInfo[] = {
.formatToString = virStorageFileFormatTypeToString,
}
},
+ {.poolType = VIR_STORAGE_POOL_VITASTOR,
+ .poolOptions = {
+ .flags = (VIR_STORAGE_POOL_SOURCE_HOST |
+ VIR_STORAGE_POOL_SOURCE_NETWORK |
+ VIR_STORAGE_POOL_SOURCE_NAME),
+ },
+ .volOptions = {
+ .defaultFormat = VIR_STORAGE_FILE_RAW,
+ .formatFromString = virStorageVolumeFormatFromString,
+ .formatToString = virStorageFileFormatTypeToString,
+ }
+ },
{.poolType = VIR_STORAGE_POOL_SHEEPDOG,
.poolOptions = {
.flags = (VIR_STORAGE_POOL_SOURCE_HOST |
@@ -538,6 +550,11 @@ virStoragePoolDefParseSource(xmlXPathContextPtr ctxt,
_("element 'name' is mandatory for RBD pool"));
return -1;
}
+ if (pool_type == VIR_STORAGE_POOL_VITASTOR && source->name == NULL) {
+ virReportError(VIR_ERR_XML_ERROR, "%s",
+ _("element 'name' is mandatory for Vitastor pool"));
+ return -1;
+ }
if (options->formatFromString) {
g_autofree char *format = NULL;
@@ -1127,6 +1144,7 @@ virStoragePoolDefFormatBuf(virBuffer *buf,
/* RBD, Sheepdog, Gluster and Iscsi-direct devices are not local block devs nor
* files, so they don't have a target */
if (def->type != VIR_STORAGE_POOL_RBD &&
+ def->type != VIR_STORAGE_POOL_VITASTOR &&
def->type != VIR_STORAGE_POOL_SHEEPDOG &&
def->type != VIR_STORAGE_POOL_GLUSTER &&
def->type != VIR_STORAGE_POOL_ISCSI_DIRECT) {
diff --git a/src/conf/storage_conf.h b/src/conf/storage_conf.h
index fc67957cfe..720c07ef74 100644
--- a/src/conf/storage_conf.h
+++ b/src/conf/storage_conf.h
@@ -103,6 +103,7 @@ typedef enum {
VIR_STORAGE_POOL_GLUSTER, /* Gluster device */
VIR_STORAGE_POOL_ZFS, /* ZFS */
VIR_STORAGE_POOL_VSTORAGE, /* Virtuozzo Storage */
+ VIR_STORAGE_POOL_VITASTOR, /* Vitastor */
VIR_STORAGE_POOL_LAST,
} virStoragePoolType;
@@ -454,6 +455,7 @@ VIR_ENUM_DECL(virStoragePartedFs);
VIR_CONNECT_LIST_STORAGE_POOLS_SCSI | \
VIR_CONNECT_LIST_STORAGE_POOLS_MPATH | \
VIR_CONNECT_LIST_STORAGE_POOLS_RBD | \
+ VIR_CONNECT_LIST_STORAGE_POOLS_VITASTOR | \
VIR_CONNECT_LIST_STORAGE_POOLS_SHEEPDOG | \
VIR_CONNECT_LIST_STORAGE_POOLS_GLUSTER | \
VIR_CONNECT_LIST_STORAGE_POOLS_ZFS | \
diff --git a/src/conf/storage_source_conf.c b/src/conf/storage_source_conf.c
index f974a521b1..cd394d0a9f 100644
--- a/src/conf/storage_source_conf.c
+++ b/src/conf/storage_source_conf.c
@@ -88,6 +88,7 @@ VIR_ENUM_IMPL(virStorageNetProtocol,
"ssh",
"vxhs",
"nfs",
+ "vitastor",
);
@@ -1301,6 +1302,7 @@ virStorageSourceNetworkDefaultPort(virStorageNetProtocol protocol)
case VIR_STORAGE_NET_PROTOCOL_GLUSTER:
return 24007;
+ case VIR_STORAGE_NET_PROTOCOL_VITASTOR:
case VIR_STORAGE_NET_PROTOCOL_RBD:
/* we don't provide a default for RBD */
return 0;
diff --git a/src/conf/storage_source_conf.h b/src/conf/storage_source_conf.h
index 5e7d127453..283709eeb3 100644
--- a/src/conf/storage_source_conf.h
+++ b/src/conf/storage_source_conf.h
@@ -129,6 +129,7 @@ typedef enum {
VIR_STORAGE_NET_PROTOCOL_SSH,
VIR_STORAGE_NET_PROTOCOL_VXHS,
VIR_STORAGE_NET_PROTOCOL_NFS,
+ VIR_STORAGE_NET_PROTOCOL_VITASTOR,
VIR_STORAGE_NET_PROTOCOL_LAST
} virStorageNetProtocol;
diff --git a/src/conf/virstorageobj.c b/src/conf/virstorageobj.c
index 59fa5da372..4739167f5f 100644
--- a/src/conf/virstorageobj.c
+++ b/src/conf/virstorageobj.c
@@ -1438,6 +1438,7 @@ virStoragePoolObjSourceFindDuplicateCb(const void *payload,
return 1;
break;
+ case VIR_STORAGE_POOL_VITASTOR:
case VIR_STORAGE_POOL_ISCSI_DIRECT:
case VIR_STORAGE_POOL_RBD:
case VIR_STORAGE_POOL_LAST:
@@ -1921,6 +1922,8 @@ virStoragePoolObjMatch(virStoragePoolObj *obj,
(obj->def->type == VIR_STORAGE_POOL_MPATH)) ||
(MATCH(VIR_CONNECT_LIST_STORAGE_POOLS_RBD) &&
(obj->def->type == VIR_STORAGE_POOL_RBD)) ||
+ (MATCH(VIR_CONNECT_LIST_STORAGE_POOLS_VITASTOR) &&
+ (obj->def->type == VIR_STORAGE_POOL_VITASTOR)) ||
(MATCH(VIR_CONNECT_LIST_STORAGE_POOLS_SHEEPDOG) &&
(obj->def->type == VIR_STORAGE_POOL_SHEEPDOG)) ||
(MATCH(VIR_CONNECT_LIST_STORAGE_POOLS_GLUSTER) &&
diff --git a/src/libvirt-storage.c b/src/libvirt-storage.c
index db7660aac4..561df34709 100644
--- a/src/libvirt-storage.c
+++ b/src/libvirt-storage.c
@@ -94,6 +94,7 @@ virStoragePoolGetConnect(virStoragePoolPtr pool)
* VIR_CONNECT_LIST_STORAGE_POOLS_SCSI
* VIR_CONNECT_LIST_STORAGE_POOLS_MPATH
* VIR_CONNECT_LIST_STORAGE_POOLS_RBD
+ * VIR_CONNECT_LIST_STORAGE_POOLS_VITASTOR
* VIR_CONNECT_LIST_STORAGE_POOLS_SHEEPDOG
* VIR_CONNECT_LIST_STORAGE_POOLS_GLUSTER
* VIR_CONNECT_LIST_STORAGE_POOLS_ZFS
diff --git a/src/libxl/libxl_conf.c b/src/libxl/libxl_conf.c
index 62e1be6672..71a1d42896 100644
--- a/src/libxl/libxl_conf.c
+++ b/src/libxl/libxl_conf.c
@@ -979,6 +979,7 @@ libxlMakeNetworkDiskSrcStr(virStorageSource *src,
case VIR_STORAGE_NET_PROTOCOL_SSH:
case VIR_STORAGE_NET_PROTOCOL_VXHS:
case VIR_STORAGE_NET_PROTOCOL_NFS:
+ case VIR_STORAGE_NET_PROTOCOL_VITASTOR:
case VIR_STORAGE_NET_PROTOCOL_LAST:
case VIR_STORAGE_NET_PROTOCOL_NONE:
virReportError(VIR_ERR_NO_SUPPORT,
diff --git a/src/libxl/xen_xl.c b/src/libxl/xen_xl.c
index f175359307..8efcf4c329 100644
--- a/src/libxl/xen_xl.c
+++ b/src/libxl/xen_xl.c
@@ -1456,6 +1456,7 @@ xenFormatXLDiskSrcNet(virStorageSource *src)
case VIR_STORAGE_NET_PROTOCOL_SSH:
case VIR_STORAGE_NET_PROTOCOL_VXHS:
case VIR_STORAGE_NET_PROTOCOL_NFS:
+ case VIR_STORAGE_NET_PROTOCOL_VITASTOR:
case VIR_STORAGE_NET_PROTOCOL_LAST:
case VIR_STORAGE_NET_PROTOCOL_NONE:
virReportError(VIR_ERR_NO_SUPPORT,
diff --git a/src/qemu/qemu_block.c b/src/qemu/qemu_block.c
index 7e9daf0bdc..825b4a3006 100644
--- a/src/qemu/qemu_block.c
+++ b/src/qemu/qemu_block.c
@@ -758,6 +758,38 @@ qemuBlockStorageSourceGetRBDProps(virStorageSource *src,
}
+static virJSONValue *
+qemuBlockStorageSourceGetVitastorProps(virStorageSource *src)
+{
+ virJSONValue *ret = NULL;
+ virStorageNetHostDef *host;
+ size_t i;
+ g_auto(virBuffer) buf = VIR_BUFFER_INITIALIZER;
+ g_autofree char *etcd = NULL;
+
+ for (i = 0; i < src->nhosts; i++) {
+ host = src->hosts + i;
+ if ((virStorageNetHostTransport)host->transport != VIR_STORAGE_NET_HOST_TRANS_TCP) {
+ return NULL;
+ }
+ virBufferAsprintf(&buf, i > 0 ? ",%s:%u" : "%s:%u", host->name, host->port);
+ }
+ if (src->nhosts > 0) {
+ etcd = virBufferContentAndReset(&buf);
+ }
+
+ if (virJSONValueObjectAdd(&ret,
+ "S:etcd-host", etcd,
+ "S:etcd-prefix", src->query,
+ "S:config-path", src->configFile,
+ "s:image", src->path,
+ NULL) < 0)
+ return NULL;
+
+ return ret;
+}
+
+
static virJSONValue *
qemuBlockStorageSourceGetSheepdogProps(virStorageSource *src)
{
@@ -1140,6 +1172,12 @@ qemuBlockStorageSourceGetBackendProps(virStorageSource *src,
return NULL;
break;
+ case VIR_STORAGE_NET_PROTOCOL_VITASTOR:
+ driver = "vitastor";
+ if (!(fileprops = qemuBlockStorageSourceGetVitastorProps(src)))
+ return NULL;
+ break;
+
case VIR_STORAGE_NET_PROTOCOL_SHEEPDOG:
driver = "sheepdog";
if (!(fileprops = qemuBlockStorageSourceGetSheepdogProps(src)))
@@ -2032,6 +2070,7 @@ qemuBlockGetBackingStoreString(virStorageSource *src,
case VIR_STORAGE_NET_PROTOCOL_SHEEPDOG:
case VIR_STORAGE_NET_PROTOCOL_RBD:
+ case VIR_STORAGE_NET_PROTOCOL_VITASTOR:
case VIR_STORAGE_NET_PROTOCOL_VXHS:
case VIR_STORAGE_NET_PROTOCOL_NFS:
case VIR_STORAGE_NET_PROTOCOL_SSH:
@@ -2415,6 +2454,12 @@ qemuBlockStorageSourceCreateGetStorageProps(virStorageSource *src,
return -1;
break;
+ case VIR_STORAGE_NET_PROTOCOL_VITASTOR:
+ driver = "vitastor";
+ if (!(location = qemuBlockStorageSourceGetVitastorProps(src)))
+ return -1;
+ break;
+
case VIR_STORAGE_NET_PROTOCOL_SHEEPDOG:
driver = "sheepdog";
if (!(location = qemuBlockStorageSourceGetSheepdogProps(src)))
diff --git a/src/qemu/qemu_domain.c b/src/qemu/qemu_domain.c
index 953808fcfe..62860283d8 100644
--- a/src/qemu/qemu_domain.c
+++ b/src/qemu/qemu_domain.c
@@ -5215,7 +5215,8 @@ qemuDomainValidateStorageSource(virStorageSource *src,
if (src->query &&
(actualType != VIR_STORAGE_TYPE_NETWORK ||
(src->protocol != VIR_STORAGE_NET_PROTOCOL_HTTPS &&
- src->protocol != VIR_STORAGE_NET_PROTOCOL_HTTP))) {
+ src->protocol != VIR_STORAGE_NET_PROTOCOL_HTTP &&
+ src->protocol != VIR_STORAGE_NET_PROTOCOL_VITASTOR))) {
virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s",
_("query is supported only with HTTP(S) protocols"));
return -1;
@@ -10340,6 +10341,7 @@ qemuDomainPrepareStorageSourceTLS(virStorageSource *src,
break;
case VIR_STORAGE_NET_PROTOCOL_RBD:
+ case VIR_STORAGE_NET_PROTOCOL_VITASTOR:
case VIR_STORAGE_NET_PROTOCOL_SHEEPDOG:
case VIR_STORAGE_NET_PROTOCOL_GLUSTER:
case VIR_STORAGE_NET_PROTOCOL_ISCSI:
diff --git a/src/qemu/qemu_snapshot.c b/src/qemu/qemu_snapshot.c
index 73ff533827..e9c799ca8f 100644
--- a/src/qemu/qemu_snapshot.c
+++ b/src/qemu/qemu_snapshot.c
@@ -423,6 +423,7 @@ qemuSnapshotPrepareDiskExternalInactive(virDomainSnapshotDiskDef *snapdisk,
case VIR_STORAGE_NET_PROTOCOL_NONE:
case VIR_STORAGE_NET_PROTOCOL_NBD:
case VIR_STORAGE_NET_PROTOCOL_RBD:
+ case VIR_STORAGE_NET_PROTOCOL_VITASTOR:
case VIR_STORAGE_NET_PROTOCOL_SHEEPDOG:
case VIR_STORAGE_NET_PROTOCOL_GLUSTER:
case VIR_STORAGE_NET_PROTOCOL_ISCSI:
@@ -648,6 +649,7 @@ qemuSnapshotPrepareDiskInternal(virDomainDiskDef *disk,
case VIR_STORAGE_NET_PROTOCOL_NONE:
case VIR_STORAGE_NET_PROTOCOL_NBD:
case VIR_STORAGE_NET_PROTOCOL_RBD:
+ case VIR_STORAGE_NET_PROTOCOL_VITASTOR:
case VIR_STORAGE_NET_PROTOCOL_SHEEPDOG:
case VIR_STORAGE_NET_PROTOCOL_GLUSTER:
case VIR_STORAGE_NET_PROTOCOL_ISCSI:
diff --git a/src/storage/storage_driver.c b/src/storage/storage_driver.c
index 314fe930e0..fb615a8b4e 100644
--- a/src/storage/storage_driver.c
+++ b/src/storage/storage_driver.c
@@ -1626,6 +1626,7 @@ storageVolLookupByPathCallback(virStoragePoolObj *obj,
case VIR_STORAGE_POOL_GLUSTER:
case VIR_STORAGE_POOL_RBD:
+ case VIR_STORAGE_POOL_VITASTOR:
case VIR_STORAGE_POOL_SHEEPDOG:
case VIR_STORAGE_POOL_ZFS:
case VIR_STORAGE_POOL_LAST:
diff --git a/src/storage_file/storage_source_backingstore.c b/src/storage_file/storage_source_backingstore.c
index 80681924ea..8a3ade9ec0 100644
--- a/src/storage_file/storage_source_backingstore.c
+++ b/src/storage_file/storage_source_backingstore.c
@@ -287,6 +287,75 @@ virStorageSourceParseRBDColonString(const char *rbdstr,
}
+static int
+virStorageSourceParseVitastorColonString(const char *colonstr,
+ virStorageSource *src)
+{
+ char *p, *e, *next;
+ g_autofree char *options = NULL;
+
+ /* optionally skip the "vitastor:" prefix if provided */
+ if (STRPREFIX(colonstr, "vitastor:"))
+ colonstr += strlen("vitastor:");
+
+ options = g_strdup(colonstr);
+
+ p = options;
+ while (*p) {
+ /* find : delimiter or end of string */
+ for (e = p; *e && *e != ':'; ++e) {
+ if (*e == '\\') {
+ e++;
+ if (*e == '\0')
+ break;
+ }
+ }
+ if (*e == '\0') {
+ next = e; /* last kv pair */
+ } else {
+ next = e + 1;
+ *e = '\0';
+ }
+
+ if (STRPREFIX(p, "image=")) {
+ src->path = g_strdup(p + strlen("image="));
+ } else if (STRPREFIX(p, "etcd-prefix=")) {
+ src->query = g_strdup(p + strlen("etcd-prefix="));
+ } else if (STRPREFIX(p, "config-path=")) {
+ src->configFile = g_strdup(p + strlen("config-path="));
+ } else if (STRPREFIX(p, "etcd-host=")) {
+ char *h, *sep;
+
+ h = p + strlen("etcd-host=");
+ while (h < e) {
+ for (sep = h; sep < e; ++sep) {
+ if (*sep == '\\' && (sep[1] == ',' ||
+ sep[1] == ';' ||
+ sep[1] == ' ')) {
+ *sep = '\0';
+ sep += 2;
+ break;
+ }
+ }
+
+ if (virStorageSourceRBDAddHost(src, h) < 0)
+ return -1;
+
+ h = sep;
+ }
+ }
+
+ p = next;
+ }
+
+ if (!src->path) {
+ return -1;
+ }
+
+ return 0;
+}
+
+
static int
virStorageSourceParseNBDColonString(const char *nbdstr,
virStorageSource *src)
@@ -399,6 +468,11 @@ virStorageSourceParseBackingColon(virStorageSource *src,
return -1;
break;
+ case VIR_STORAGE_NET_PROTOCOL_VITASTOR:
+ if (virStorageSourceParseVitastorColonString(path, src) < 0)
+ return -1;
+ break;
+
case VIR_STORAGE_NET_PROTOCOL_SHEEPDOG:
case VIR_STORAGE_NET_PROTOCOL_LAST:
case VIR_STORAGE_NET_PROTOCOL_NONE:
@@ -975,6 +1049,54 @@ virStorageSourceParseBackingJSONRBD(virStorageSource *src,
return 0;
}
+static int
+virStorageSourceParseBackingJSONVitastor(virStorageSource *src,
+ virJSONValue *json,
+ const char *jsonstr G_GNUC_UNUSED,
+ int opaque G_GNUC_UNUSED)
+{
+ const char *filename;
+ const char *image = virJSONValueObjectGetString(json, "image");
+ const char *conf = virJSONValueObjectGetString(json, "config-path");
+ const char *etcd_prefix = virJSONValueObjectGetString(json, "etcd-prefix");
+ virJSONValue *servers = virJSONValueObjectGetArray(json, "server");
+ size_t nservers;
+ size_t i;
+
+ src->type = VIR_STORAGE_TYPE_NETWORK;
+ src->protocol = VIR_STORAGE_NET_PROTOCOL_VITASTOR;
+
+ /* legacy syntax passed via 'filename' option */
+ if ((filename = virJSONValueObjectGetString(json, "filename")))
+ return virStorageSourceParseVitastorColonString(filename, src);
+
+ if (!image) {
+ virReportError(VIR_ERR_INVALID_ARG, "%s",
+ _("missing image name in Vitastor backing volume "
+ "JSON specification"));
+ return -1;
+ }
+
+ src->path = g_strdup(image);
+ src->configFile = g_strdup(conf);
+ src->query = g_strdup(etcd_prefix);
+
+ if (servers) {
+ nservers = virJSONValueArraySize(servers);
+
+ src->hosts = g_new0(virStorageNetHostDef, nservers);
+ src->nhosts = nservers;
+
+ for (i = 0; i < nservers; i++) {
+ if (virStorageSourceParseBackingJSONInetSocketAddress(src->hosts + i,
+ virJSONValueArrayGet(servers, i)) < 0)
+ return -1;
+ }
+ }
+
+ return 0;
+}
+
static int
virStorageSourceParseBackingJSONRaw(virStorageSource *src,
virJSONValue *json,
@@ -1152,6 +1274,7 @@ static const struct virStorageSourceJSONDriverParser jsonParsers[] = {
{"sheepdog", false, virStorageSourceParseBackingJSONSheepdog, 0},
{"ssh", false, virStorageSourceParseBackingJSONSSH, 0},
{"rbd", false, virStorageSourceParseBackingJSONRBD, 0},
+ {"vitastor", false, virStorageSourceParseBackingJSONVitastor, 0},
{"raw", true, virStorageSourceParseBackingJSONRaw, 0},
{"nfs", false, virStorageSourceParseBackingJSONNFS, 0},
{"vxhs", false, virStorageSourceParseBackingJSONVxHS, 0},
diff --git a/src/test/test_driver.c b/src/test/test_driver.c
index e87d7cfd44..ccc05d7aae 100644
--- a/src/test/test_driver.c
+++ b/src/test/test_driver.c
@@ -7335,6 +7335,7 @@ testStorageVolumeTypeForPool(int pooltype)
case VIR_STORAGE_POOL_ISCSI_DIRECT:
case VIR_STORAGE_POOL_GLUSTER:
case VIR_STORAGE_POOL_RBD:
+ case VIR_STORAGE_POOL_VITASTOR:
return VIR_STORAGE_VOL_NETWORK;
case VIR_STORAGE_POOL_LOGICAL:
case VIR_STORAGE_POOL_DISK:
diff --git a/tests/storagepoolcapsschemadata/poolcaps-fs.xml b/tests/storagepoolcapsschemadata/poolcaps-fs.xml
index eee75af746..8bd0a57bdd 100644
--- a/tests/storagepoolcapsschemadata/poolcaps-fs.xml
+++ b/tests/storagepoolcapsschemadata/poolcaps-fs.xml
@@ -204,4 +204,11 @@
</enum>
</volOptions>
</pool>
+ <pool type='vitastor' supported='no'>
+ <volOptions>
+ <defaultFormat type='raw'/>
+ <enum name='targetFormatType'>
+ </enum>
+ </volOptions>
+ </pool>
</storagepoolCapabilities>
diff --git a/tests/storagepoolcapsschemadata/poolcaps-full.xml b/tests/storagepoolcapsschemadata/poolcaps-full.xml
index 805950a937..852df0de16 100644
--- a/tests/storagepoolcapsschemadata/poolcaps-full.xml
+++ b/tests/storagepoolcapsschemadata/poolcaps-full.xml
@@ -204,4 +204,11 @@
</enum>
</volOptions>
</pool>
+ <pool type='vitastor' supported='yes'>
+ <volOptions>
+ <defaultFormat type='raw'/>
+ <enum name='targetFormatType'>
+ </enum>
+ </volOptions>
+ </pool>
</storagepoolCapabilities>
diff --git a/tests/storagepoolxml2argvtest.c b/tests/storagepoolxml2argvtest.c
index e8e40d695e..db55fe5f3a 100644
--- a/tests/storagepoolxml2argvtest.c
+++ b/tests/storagepoolxml2argvtest.c
@@ -65,6 +65,7 @@ testCompareXMLToArgvFiles(bool shouldFail,
case VIR_STORAGE_POOL_GLUSTER:
case VIR_STORAGE_POOL_ZFS:
case VIR_STORAGE_POOL_VSTORAGE:
+ case VIR_STORAGE_POOL_VITASTOR:
case VIR_STORAGE_POOL_LAST:
default:
VIR_TEST_DEBUG("pool type '%s' has no xml2argv test", defTypeStr);
diff --git a/tools/virsh-pool.c b/tools/virsh-pool.c
index 36f00cf643..5f5bd3464e 100644
--- a/tools/virsh-pool.c
+++ b/tools/virsh-pool.c
@@ -1223,6 +1223,9 @@ cmdPoolList(vshControl *ctl, const vshCmd *cmd G_GNUC_UNUSED)
case VIR_STORAGE_POOL_VSTORAGE:
flags |= VIR_CONNECT_LIST_STORAGE_POOLS_VSTORAGE;
break;
+ case VIR_STORAGE_POOL_VITASTOR:
+ flags |= VIR_CONNECT_LIST_STORAGE_POOLS_VITASTOR;
+ break;
case VIR_STORAGE_POOL_LAST:
break;
}
-28
View File
@@ -1,28 +0,0 @@
name: Pull Request
about: Submit a pull request
body:
- type: textarea
id: description
attributes:
label: Description
description: Describe your pull request
placeholder: ""
value: ""
validations:
required: true
- type: input
id: author
attributes:
label: Contributor Name
description: Contributor Name or Company Details if the Contributor is a company
placeholder: ""
validations:
required: false
- type: checkboxes
id: terms
attributes:
label: CLA
description: By submitting this pull request, I accept [Vitastor CLA](https://git.yourcmc.ru/vitalif/vitastor/src/branch/master/CLA-en.md)
options:
- label: "I accept Vitastor CLA agreement: https://git.yourcmc.ru/vitalif/vitastor/src/branch/master/CLA-en.md"
required: true
+1 -1
View File
@@ -24,4 +24,4 @@ rm fio
mv fio-copy fio mv fio-copy fio
FIO=`rpm -qi fio | perl -e 'while(<>) { /^Epoch[\s:]+(\S+)/ && print "$1:"; /^Version[\s:]+(\S+)/ && print $1; /^Release[\s:]+(\S+)/ && print "-$1"; }'` FIO=`rpm -qi fio | perl -e 'while(<>) { /^Epoch[\s:]+(\S+)/ && print "$1:"; /^Version[\s:]+(\S+)/ && print $1; /^Release[\s:]+(\S+)/ && print "-$1"; }'`
perl -i -pe 's/(Requires:\s*fio)([^\n]+)?/$1 = '$FIO'/' $VITASTOR/rpm/vitastor-el$EL.spec perl -i -pe 's/(Requires:\s*fio)([^\n]+)?/$1 = '$FIO'/' $VITASTOR/rpm/vitastor-el$EL.spec
tar --transform 's#^#vitastor-1.4.7/#' --exclude 'rpm/*.rpm' -czf $VITASTOR/../vitastor-1.4.7$(rpm --eval '%dist').tar.gz * tar --transform 's#^#vitastor-1.3.1/#' --exclude 'rpm/*.rpm' -czf $VITASTOR/../vitastor-1.3.1$(rpm --eval '%dist').tar.gz *
+1 -1
View File
@@ -36,7 +36,7 @@ ADD . /root/vitastor
RUN set -e; \ RUN set -e; \
cd /root/vitastor/rpm; \ cd /root/vitastor/rpm; \
sh build-tarball.sh; \ sh build-tarball.sh; \
cp /root/vitastor-1.4.7.el7.tar.gz ~/rpmbuild/SOURCES; \ cp /root/vitastor-1.3.1.el7.tar.gz ~/rpmbuild/SOURCES; \
cp vitastor-el7.spec ~/rpmbuild/SPECS/vitastor.spec; \ cp vitastor-el7.spec ~/rpmbuild/SPECS/vitastor.spec; \
cd ~/rpmbuild/SPECS/; \ cd ~/rpmbuild/SPECS/; \
rpmbuild -ba vitastor.spec; \ rpmbuild -ba vitastor.spec; \
+2 -2
View File
@@ -1,11 +1,11 @@
Name: vitastor Name: vitastor
Version: 1.4.7 Version: 1.3.1
Release: 1%{?dist} Release: 1%{?dist}
Summary: Vitastor, a fast software-defined clustered block storage Summary: Vitastor, a fast software-defined clustered block storage
License: Vitastor Network Public License 1.1 License: Vitastor Network Public License 1.1
URL: https://vitastor.io/ URL: https://vitastor.io/
Source0: vitastor-1.4.7.el7.tar.gz Source0: vitastor-1.3.1.el7.tar.gz
BuildRequires: liburing-devel >= 0.6 BuildRequires: liburing-devel >= 0.6
BuildRequires: gperftools-devel BuildRequires: gperftools-devel
+1 -1
View File
@@ -35,7 +35,7 @@ ADD . /root/vitastor
RUN set -e; \ RUN set -e; \
cd /root/vitastor/rpm; \ cd /root/vitastor/rpm; \
sh build-tarball.sh; \ sh build-tarball.sh; \
cp /root/vitastor-1.4.7.el8.tar.gz ~/rpmbuild/SOURCES; \ cp /root/vitastor-1.3.1.el8.tar.gz ~/rpmbuild/SOURCES; \
cp vitastor-el8.spec ~/rpmbuild/SPECS/vitastor.spec; \ cp vitastor-el8.spec ~/rpmbuild/SPECS/vitastor.spec; \
cd ~/rpmbuild/SPECS/; \ cd ~/rpmbuild/SPECS/; \
rpmbuild -ba vitastor.spec; \ rpmbuild -ba vitastor.spec; \
+2 -2
View File
@@ -1,11 +1,11 @@
Name: vitastor Name: vitastor
Version: 1.4.7 Version: 1.3.1
Release: 1%{?dist} Release: 1%{?dist}
Summary: Vitastor, a fast software-defined clustered block storage Summary: Vitastor, a fast software-defined clustered block storage
License: Vitastor Network Public License 1.1 License: Vitastor Network Public License 1.1
URL: https://vitastor.io/ URL: https://vitastor.io/
Source0: vitastor-1.4.7.el8.tar.gz Source0: vitastor-1.3.1.el8.tar.gz
BuildRequires: liburing-devel >= 0.6 BuildRequires: liburing-devel >= 0.6
BuildRequires: gperftools-devel BuildRequires: gperftools-devel
+1 -1
View File
@@ -18,7 +18,7 @@ ADD . /root/vitastor
RUN set -e; \ RUN set -e; \
cd /root/vitastor/rpm; \ cd /root/vitastor/rpm; \
sh build-tarball.sh; \ sh build-tarball.sh; \
cp /root/vitastor-1.4.7.el9.tar.gz ~/rpmbuild/SOURCES; \ cp /root/vitastor-1.3.1.el9.tar.gz ~/rpmbuild/SOURCES; \
cp vitastor-el9.spec ~/rpmbuild/SPECS/vitastor.spec; \ cp vitastor-el9.spec ~/rpmbuild/SPECS/vitastor.spec; \
cd ~/rpmbuild/SPECS/; \ cd ~/rpmbuild/SPECS/; \
rpmbuild -ba vitastor.spec; \ rpmbuild -ba vitastor.spec; \
+2 -2
View File
@@ -1,11 +1,11 @@
Name: vitastor Name: vitastor
Version: 1.4.7 Version: 1.3.1
Release: 1%{?dist} Release: 1%{?dist}
Summary: Vitastor, a fast software-defined clustered block storage Summary: Vitastor, a fast software-defined clustered block storage
License: Vitastor Network Public License 1.1 License: Vitastor Network Public License 1.1
URL: https://vitastor.io/ URL: https://vitastor.io/
Source0: vitastor-1.4.7.el9.tar.gz Source0: vitastor-1.3.1.el9.tar.gz
BuildRequires: liburing-devel >= 0.6 BuildRequires: liburing-devel >= 0.6
BuildRequires: gperftools-devel BuildRequires: gperftools-devel
+21 -2
View File
@@ -16,8 +16,8 @@ if("${CMAKE_INSTALL_PREFIX}" MATCHES "^/usr/local/?$")
set(CMAKE_INSTALL_RPATH "${CMAKE_INSTALL_PREFIX}/${CMAKE_INSTALL_LIBDIR}") set(CMAKE_INSTALL_RPATH "${CMAKE_INSTALL_PREFIX}/${CMAKE_INSTALL_LIBDIR}")
endif() endif()
add_definitions(-DVERSION="1.4.7") add_definitions(-DVERSION="1.3.1")
add_definitions(-D_LARGEFILE64_SOURCE -D_FILE_OFFSET_BITS=64 -Wall -Wno-sign-compare -Wno-comment -Wno-parentheses -Wno-pointer-arith -fdiagnostics-color=always -fno-omit-frame-pointer -I ${CMAKE_SOURCE_DIR}/src) add_definitions(-Wall -Wno-sign-compare -Wno-comment -Wno-parentheses -Wno-pointer-arith -fdiagnostics-color=always -fno-omit-frame-pointer -I ${CMAKE_SOURCE_DIR}/src)
add_link_options(-fno-omit-frame-pointer) add_link_options(-fno-omit-frame-pointer)
if (${WITH_ASAN}) if (${WITH_ASAN})
add_definitions(-fsanitize=address) add_definitions(-fsanitize=address)
@@ -181,6 +181,25 @@ target_link_libraries(vitastor-nbd
vitastor_client vitastor_client
) )
# vitastor-kv
add_executable(vitastor-kv
kv_cli.cpp
kv_db.cpp
kv_db.h
)
target_link_libraries(vitastor-kv
vitastor_client
)
add_executable(vitastor-kv-stress
kv_stress.cpp
kv_db.cpp
kv_db.h
)
target_link_libraries(vitastor-kv-stress
vitastor_client
)
# vitastor-nfs # vitastor-nfs
add_executable(vitastor-nfs add_executable(vitastor-nfs
nfs_proxy.cpp nfs_proxy.cpp
-8
View File
@@ -108,10 +108,6 @@ void blockstore_disk_t::parse_config(std::map<std::string, std::string> & config
{ {
throw std::runtime_error("journal_block_size must be a multiple of "+std::to_string(DIRECT_IO_ALIGNMENT)); throw std::runtime_error("journal_block_size must be a multiple of "+std::to_string(DIRECT_IO_ALIGNMENT));
} }
else if (journal_block_size > MAX_DATA_BLOCK_SIZE)
{
throw std::runtime_error("journal_block_size must not exceed "+std::to_string(MAX_DATA_BLOCK_SIZE));
}
if (!meta_block_size) if (!meta_block_size)
{ {
meta_block_size = 4096; meta_block_size = 4096;
@@ -120,10 +116,6 @@ void blockstore_disk_t::parse_config(std::map<std::string, std::string> & config
{ {
throw std::runtime_error("meta_block_size must be a multiple of "+std::to_string(DIRECT_IO_ALIGNMENT)); throw std::runtime_error("meta_block_size must be a multiple of "+std::to_string(DIRECT_IO_ALIGNMENT));
} }
else if (meta_block_size > MAX_DATA_BLOCK_SIZE)
{
throw std::runtime_error("meta_block_size must not exceed "+std::to_string(MAX_DATA_BLOCK_SIZE));
}
if (data_offset % disk_alignment) if (data_offset % disk_alignment)
{ {
throw std::runtime_error("data_offset must be a multiple of disk_alignment = "+std::to_string(disk_alignment)); throw std::runtime_error("data_offset must be a multiple of disk_alignment = "+std::to_string(disk_alignment));
+33 -34
View File
@@ -19,6 +19,7 @@ journal_flusher_t::journal_flusher_t(blockstore_impl_t *bs)
syncing_flushers = 0; syncing_flushers = 0;
// FIXME: allow to configure flusher_start_threshold and journal_trim_interval // FIXME: allow to configure flusher_start_threshold and journal_trim_interval
flusher_start_threshold = bs->dsk.journal_block_size / sizeof(journal_entry_stable); flusher_start_threshold = bs->dsk.journal_block_size / sizeof(journal_entry_stable);
journal_trim_interval = 512;
journal_trim_counter = bs->journal.flush_journal ? 1 : 0; journal_trim_counter = bs->journal.flush_journal ? 1 : 0;
trim_wanted = bs->journal.flush_journal ? 1 : 0; trim_wanted = bs->journal.flush_journal ? 1 : 0;
journal_superblock = bs->journal.inmemory ? bs->journal.buffer : memalign_or_die(MEM_ALIGNMENT, bs->dsk.journal_block_size); journal_superblock = bs->journal.inmemory ? bs->journal.buffer : memalign_or_die(MEM_ALIGNMENT, bs->dsk.journal_block_size);
@@ -93,7 +94,7 @@ void journal_flusher_t::loop()
void journal_flusher_t::enqueue_flush(obj_ver_id ov) void journal_flusher_t::enqueue_flush(obj_ver_id ov)
{ {
#ifdef BLOCKSTORE_DEBUG #ifdef BLOCKSTORE_DEBUG
printf("enqueue_flush %jx:%jx v%ju\n", ov.oid.inode, ov.oid.stripe, ov.version); printf("enqueue_flush %lx:%lx v%lu\n", ov.oid.inode, ov.oid.stripe, ov.version);
#endif #endif
auto it = flush_versions.find(ov.oid); auto it = flush_versions.find(ov.oid);
if (it != flush_versions.end()) if (it != flush_versions.end())
@@ -116,7 +117,7 @@ void journal_flusher_t::enqueue_flush(obj_ver_id ov)
void journal_flusher_t::unshift_flush(obj_ver_id ov, bool force) void journal_flusher_t::unshift_flush(obj_ver_id ov, bool force)
{ {
#ifdef BLOCKSTORE_DEBUG #ifdef BLOCKSTORE_DEBUG
printf("unshift_flush %jx:%jx v%ju\n", ov.oid.inode, ov.oid.stripe, ov.version); printf("unshift_flush %lx:%lx v%lu\n", ov.oid.inode, ov.oid.stripe, ov.version);
#endif #endif
auto it = flush_versions.find(ov.oid); auto it = flush_versions.find(ov.oid);
if (it != flush_versions.end()) if (it != flush_versions.end())
@@ -142,7 +143,7 @@ void journal_flusher_t::unshift_flush(obj_ver_id ov, bool force)
void journal_flusher_t::remove_flush(object_id oid) void journal_flusher_t::remove_flush(object_id oid)
{ {
#ifdef BLOCKSTORE_DEBUG #ifdef BLOCKSTORE_DEBUG
printf("undo_flush %jx:%jx\n", oid.inode, oid.stripe); printf("undo_flush %lx:%lx\n", oid.inode, oid.stripe);
#endif #endif
auto v_it = flush_versions.find(oid); auto v_it = flush_versions.find(oid);
if (v_it != flush_versions.end()) if (v_it != flush_versions.end())
@@ -183,7 +184,8 @@ void journal_flusher_t::mark_trim_possible()
if (trim_wanted > 0) if (trim_wanted > 0)
{ {
dequeuing = true; dequeuing = true;
journal_trim_counter = 0; if (!journal_trim_counter)
journal_trim_counter = journal_trim_interval;
bs->ringloop->wakeup(); bs->ringloop->wakeup();
} }
} }
@@ -233,7 +235,7 @@ void journal_flusher_t::dump_diagnostics()
break; break;
} }
printf( printf(
"Flusher: queued=%zd first=%s%jx:%jx trim_wanted=%d dequeuing=%d trimming=%d cur=%d target=%d active=%d syncing=%d\n", "Flusher: queued=%ld first=%s%lx:%lx trim_wanted=%d dequeuing=%d trimming=%d cur=%d target=%d active=%d syncing=%d\n",
flush_queue.size(), unflushable_type, unflushable.oid.inode, unflushable.oid.stripe, flush_queue.size(), unflushable_type, unflushable.oid.inode, unflushable.oid.stripe,
trim_wanted, dequeuing, trimming, cur_flusher_count, target_flusher_count, trim_wanted, dequeuing, trimming, cur_flusher_count, target_flusher_count,
active_flushers, syncing_flushers active_flushers, syncing_flushers
@@ -266,7 +268,7 @@ bool journal_flusher_t::try_find_other(std::map<obj_ver_id, dirty_entry>::iterat
{ {
int search_left = flush_queue.size() - 1; int search_left = flush_queue.size() - 1;
#ifdef BLOCKSTORE_DEBUG #ifdef BLOCKSTORE_DEBUG
printf("Flusher overran writers (%jx:%jx v%ju, dirty_start=%08jx) - searching for older flushes (%d left)\n", printf("Flusher overran writers (%lx:%lx v%lu, dirty_start=%08lx) - searching for older flushes (%d left)\n",
cur.oid.inode, cur.oid.stripe, cur.version, bs->journal.dirty_start, search_left); cur.oid.inode, cur.oid.stripe, cur.version, bs->journal.dirty_start, search_left);
#endif #endif
while (search_left > 0) while (search_left > 0)
@@ -283,7 +285,7 @@ bool journal_flusher_t::try_find_other(std::map<obj_ver_id, dirty_entry>::iterat
dirty_end->second.journal_sector < bs->journal.used_start)) dirty_end->second.journal_sector < bs->journal.used_start))
{ {
#ifdef BLOCKSTORE_DEBUG #ifdef BLOCKSTORE_DEBUG
printf("Write %jx:%jx v%ju is too new: offset=%08jx\n", cur.oid.inode, cur.oid.stripe, cur.version, dirty_end->second.journal_sector); printf("Write %lx:%lx v%lu is too new: offset=%08lx\n", cur.oid.inode, cur.oid.stripe, cur.version, dirty_end->second.journal_sector);
#endif #endif
enqueue_flush(cur); enqueue_flush(cur);
} }
@@ -364,10 +366,9 @@ resume_0:
!flusher->flush_queue.size() || !flusher->dequeuing) !flusher->flush_queue.size() || !flusher->dequeuing)
{ {
stop_flusher: stop_flusher:
if (flusher->trim_wanted > 0 && cur.oid.inode != 0) if (flusher->trim_wanted > 0 && flusher->journal_trim_counter > 0)
{ {
// Attempt forced trim // Attempt forced trim
cur.oid = {};
flusher->active_flushers++; flusher->active_flushers++;
goto trim_journal; goto trim_journal;
} }
@@ -386,7 +387,7 @@ stop_flusher:
if (repeat_it != flusher->sync_to_repeat.end()) if (repeat_it != flusher->sync_to_repeat.end())
{ {
#ifdef BLOCKSTORE_DEBUG #ifdef BLOCKSTORE_DEBUG
printf("Postpone %jx:%jx v%ju\n", cur.oid.inode, cur.oid.stripe, cur.version); printf("Postpone %lx:%lx v%lu\n", cur.oid.inode, cur.oid.stripe, cur.version);
#endif #endif
// We don't flush different parts of history of the same object in parallel // We don't flush different parts of history of the same object in parallel
// So we check if someone is already flushing this object // So we check if someone is already flushing this object
@@ -415,13 +416,12 @@ stop_flusher:
flusher->sync_to_repeat.erase(cur.oid); flusher->sync_to_repeat.erase(cur.oid);
if (!flusher->try_find_other(dirty_end, cur)) if (!flusher->try_find_other(dirty_end, cur))
{ {
cur.oid = {};
goto stop_flusher; goto stop_flusher;
} }
} }
} }
#ifdef BLOCKSTORE_DEBUG #ifdef BLOCKSTORE_DEBUG
printf("Flushing %jx:%jx v%ju\n", cur.oid.inode, cur.oid.stripe, cur.version); printf("Flushing %lx:%lx v%lu\n", cur.oid.inode, cur.oid.stripe, cur.version);
#endif #endif
flusher->active_flushers++; flusher->active_flushers++;
// Find it in clean_db // Find it in clean_db
@@ -448,7 +448,7 @@ stop_flusher:
// Object not allocated. This is a bug. // Object not allocated. This is a bug.
char err[1024]; char err[1024];
snprintf( snprintf(
err, 1024, "BUG: Object %jx:%jx v%ju that we are trying to flush is not allocated on the data device", err, 1024, "BUG: Object %lx:%lx v%lu that we are trying to flush is not allocated on the data device",
cur.oid.inode, cur.oid.stripe, cur.version cur.oid.inode, cur.oid.stripe, cur.version
); );
throw std::runtime_error(err); throw std::runtime_error(err);
@@ -538,7 +538,7 @@ resume_2:
clean_disk_entry *old_entry = (clean_disk_entry*)((uint8_t*)meta_old.buf + meta_old.pos*bs->dsk.clean_entry_size); clean_disk_entry *old_entry = (clean_disk_entry*)((uint8_t*)meta_old.buf + meta_old.pos*bs->dsk.clean_entry_size);
if (old_entry->oid.inode != 0 && old_entry->oid != cur.oid) if (old_entry->oid.inode != 0 && old_entry->oid != cur.oid)
{ {
printf("Fatal error (metadata corruption or bug): tried to wipe metadata entry %ju (%jx:%jx v%ju) as old location of %jx:%jx\n", printf("Fatal error (metadata corruption or bug): tried to wipe metadata entry %lu (%lx:%lx v%lu) as old location of %lx:%lx\n",
old_clean_loc >> bs->dsk.block_order, old_entry->oid.inode, old_entry->oid.stripe, old_clean_loc >> bs->dsk.block_order, old_entry->oid.inode, old_entry->oid.stripe,
old_entry->version, cur.oid.inode, cur.oid.stripe); old_entry->version, cur.oid.inode, cur.oid.stripe);
exit(1); exit(1);
@@ -571,7 +571,7 @@ resume_2:
// Erase dirty_db entries // Erase dirty_db entries
bs->erase_dirty(dirty_start, std::next(dirty_end), clean_loc); bs->erase_dirty(dirty_start, std::next(dirty_end), clean_loc);
#ifdef BLOCKSTORE_DEBUG #ifdef BLOCKSTORE_DEBUG
printf("Flushed %jx:%jx v%ju (%d copies, wr:%d, del:%d), %jd left\n", cur.oid.inode, cur.oid.stripe, cur.version, printf("Flushed %lx:%lx v%lu (%d copies, wr:%d, del:%d), %ld left\n", cur.oid.inode, cur.oid.stripe, cur.version,
copy_count, has_writes, has_delete, flusher->flush_queue.size()); copy_count, has_writes, has_delete, flusher->flush_queue.size());
#endif #endif
release_oid: release_oid:
@@ -584,8 +584,7 @@ resume_2:
flusher->sync_to_repeat.erase(repeat_it); flusher->sync_to_repeat.erase(repeat_it);
trim_journal: trim_journal:
// Clear unused part of the journal every <journal_trim_interval> flushes // Clear unused part of the journal every <journal_trim_interval> flushes
if (bs->journal_trim_interval && !((++flusher->journal_trim_counter) % bs->journal_trim_interval) || if (!((++flusher->journal_trim_counter) % flusher->journal_trim_interval) || flusher->trim_wanted > 0)
flusher->trim_wanted > 0)
{ {
resume_26: resume_26:
resume_27: resume_27:
@@ -610,8 +609,8 @@ void journal_flusher_co::update_metadata_entry()
{ {
printf( printf(
has_delete has_delete
? "Fatal error (metadata corruption or bug): tried to delete metadata entry %ju (%jx:%jx v%ju) while deleting %jx:%jx v%ju\n" ? "Fatal error (metadata corruption or bug): tried to delete metadata entry %lu (%lx:%lx v%lu) while deleting %lx:%lx v%lu\n"
: "Fatal error (metadata corruption or bug): tried to overwrite non-zero metadata entry %ju (%jx:%jx v%ju) with %jx:%jx v%ju\n", : "Fatal error (metadata corruption or bug): tried to overwrite non-zero metadata entry %lu (%lx:%lx v%lu) with %lx:%lx v%lu\n",
clean_loc >> bs->dsk.block_order, new_entry->oid.inode, new_entry->oid.stripe, clean_loc >> bs->dsk.block_order, new_entry->oid.inode, new_entry->oid.stripe,
new_entry->version, cur.oid.inode, cur.oid.stripe, cur.version new_entry->version, cur.oid.inode, cur.oid.stripe, cur.version
); );
@@ -711,7 +710,7 @@ bool journal_flusher_co::write_meta_block(flusher_meta_write_t & meta_block, int
if (wait_state == wait_base) if (wait_state == wait_base)
goto resume_0; goto resume_0;
await_sqe(0); await_sqe(0);
data->iov = (struct iovec){ meta_block.buf, (size_t)bs->dsk.meta_block_size }; data->iov = (struct iovec){ meta_block.buf, bs->dsk.meta_block_size };
data->callback = simple_callback_w; data->callback = simple_callback_w;
my_uring_prep_writev( my_uring_prep_writev(
sqe, bs->dsk.meta_fd, &data->iov, 1, bs->dsk.meta_offset + bs->dsk.meta_block_size + meta_block.sector sqe, bs->dsk.meta_fd, &data->iov, 1, bs->dsk.meta_offset + bs->dsk.meta_block_size + meta_block.sector
@@ -761,7 +760,7 @@ bool journal_flusher_co::clear_incomplete_csum_block_bits(int wait_base)
{ {
// If we encounter bad checksums during flush, we still update the bad block, // If we encounter bad checksums during flush, we still update the bad block,
// but intentionally mangle checksums to avoid hiding the corruption. // but intentionally mangle checksums to avoid hiding the corruption.
iovec iov = { .iov_base = v[i].buf, .iov_len = (size_t)v[i].len }; iovec iov = { .iov_base = v[i].buf, .iov_len = v[i].len };
if (!(v[i].copy_flags & COPY_BUF_JOURNAL)) if (!(v[i].copy_flags & COPY_BUF_JOURNAL))
{ {
assert(!(v[i].offset % bs->dsk.csum_block_size)); assert(!(v[i].offset % bs->dsk.csum_block_size));
@@ -769,7 +768,7 @@ bool journal_flusher_co::clear_incomplete_csum_block_bits(int wait_base)
bs->verify_padded_checksums(new_clean_bitmap, new_clean_bitmap + 2*bs->dsk.clean_entry_bitmap_size, bs->verify_padded_checksums(new_clean_bitmap, new_clean_bitmap + 2*bs->dsk.clean_entry_bitmap_size,
v[i].offset, &iov, 1, [&](uint32_t bad_block, uint32_t calc_csum, uint32_t stored_csum) v[i].offset, &iov, 1, [&](uint32_t bad_block, uint32_t calc_csum, uint32_t stored_csum)
{ {
printf("Checksum mismatch in object %jx:%jx v%ju in data area at offset 0x%jx+0x%x: got %08x, expected %08x\n", printf("Checksum mismatch in object %lx:%lx v%lu in data area at offset 0x%lx+0x%x: got %08x, expected %08x\n",
cur.oid.inode, cur.oid.stripe, old_clean_ver, old_clean_loc, bad_block, calc_csum, stored_csum); cur.oid.inode, cur.oid.stripe, old_clean_ver, old_clean_loc, bad_block, calc_csum, stored_csum);
for (uint32_t j = 0; j < bs->dsk.csum_block_size; j += bs->dsk.bitmap_granularity) for (uint32_t j = 0; j < bs->dsk.csum_block_size; j += bs->dsk.bitmap_granularity)
{ {
@@ -782,7 +781,7 @@ bool journal_flusher_co::clear_incomplete_csum_block_bits(int wait_base)
{ {
bs->verify_journal_checksums(v[i].csum_buf, v[i].offset, &iov, 1, [&](uint32_t bad_block, uint32_t calc_csum, uint32_t stored_csum) bs->verify_journal_checksums(v[i].csum_buf, v[i].offset, &iov, 1, [&](uint32_t bad_block, uint32_t calc_csum, uint32_t stored_csum)
{ {
printf("Checksum mismatch in object %jx:%jx v%ju in journal at offset 0x%jx+0x%x (block offset 0x%jx): got %08x, expected %08x\n", printf("Checksum mismatch in object %lx:%lx v%lu in journal at offset 0x%lx+0x%x (block offset 0x%lx): got %08x, expected %08x\n",
cur.oid.inode, cur.oid.stripe, old_clean_ver, cur.oid.inode, cur.oid.stripe, old_clean_ver,
v[i].disk_offset, bad_block, v[i].offset, calc_csum, stored_csum); v[i].disk_offset, bad_block, v[i].offset, calc_csum, stored_csum);
bad_block += (v[i].offset/bs->dsk.csum_block_size) * bs->dsk.csum_block_size; bad_block += (v[i].offset/bs->dsk.csum_block_size) * bs->dsk.csum_block_size;
@@ -806,7 +805,7 @@ bool journal_flusher_co::clear_incomplete_csum_block_bits(int wait_base)
if (new_entry->oid != cur.oid) if (new_entry->oid != cur.oid)
{ {
printf( printf(
"Fatal error (metadata corruption or bug): tried to make holes in %ju (%jx:%jx v%ju) with %jx:%jx v%ju\n", "Fatal error (metadata corruption or bug): tried to make holes in %lu (%lx:%lx v%lu) with %lx:%lx v%lu\n",
clean_loc >> bs->dsk.block_order, new_entry->oid.inode, new_entry->oid.stripe, clean_loc >> bs->dsk.block_order, new_entry->oid.inode, new_entry->oid.stripe,
new_entry->version, cur.oid.inode, cur.oid.stripe, cur.version new_entry->version, cur.oid.inode, cur.oid.stripe, cur.version
); );
@@ -926,7 +925,7 @@ void journal_flusher_co::scan_dirty()
{ {
char err[1024]; char err[1024];
snprintf( snprintf(
err, 1024, "BUG: Unexpected dirty_entry %jx:%jx v%ju unstable state during flush: 0x%x", err, 1024, "BUG: Unexpected dirty_entry %lx:%lx v%lu unstable state during flush: 0x%x",
dirty_it->first.oid.inode, dirty_it->first.oid.stripe, dirty_it->first.version, dirty_it->second.state dirty_it->first.oid.inode, dirty_it->first.oid.stripe, dirty_it->first.version, dirty_it->second.state
); );
throw std::runtime_error(err); throw std::runtime_error(err);
@@ -1022,7 +1021,7 @@ void journal_flusher_co::scan_dirty()
// May happen if the metadata entry is corrupt, but journal isn't // May happen if the metadata entry is corrupt, but journal isn't
// FIXME: Report corrupted object to the upper layer (OSD) // FIXME: Report corrupted object to the upper layer (OSD)
printf( printf(
"Warning: object %jx:%jx has overwrites, but doesn't have a clean version." "Warning: object %lx:%lx has overwrites, but doesn't have a clean version."
" Metadata is likely corrupted. Dropping object from the DB.\n", " Metadata is likely corrupted. Dropping object from the DB.\n",
cur.oid.inode, cur.oid.stripe cur.oid.inode, cur.oid.stripe
); );
@@ -1057,7 +1056,7 @@ void journal_flusher_co::scan_dirty()
flusher->enqueue_flush(cur); flusher->enqueue_flush(cur);
cur.version = dirty_end->first.version; cur.version = dirty_end->first.version;
#ifdef BLOCKSTORE_DEBUG #ifdef BLOCKSTORE_DEBUG
printf("Partial checksum block overwrites found - rewinding flush back to %jx:%jx v%ju\n", cur.oid.inode, cur.oid.stripe, cur.version); printf("Partial checksum block overwrites found - rewinding flush back to %lx:%lx v%lu\n", cur.oid.inode, cur.oid.stripe, cur.version);
#endif #endif
v.clear(); v.clear();
copy_count = 0; copy_count = 0;
@@ -1085,7 +1084,7 @@ bool journal_flusher_co::read_dirty(int wait_base)
auto & vi = v[v.size()-i]; auto & vi = v[v.size()-i];
assert(vi.len != 0); assert(vi.len != 0);
vi.buf = memalign_or_die(MEM_ALIGNMENT, vi.len); vi.buf = memalign_or_die(MEM_ALIGNMENT, vi.len);
data->iov = (struct iovec){ vi.buf, (size_t)vi.len }; data->iov = (struct iovec){ vi.buf, vi.len };
data->callback = simple_callback_r; data->callback = simple_callback_r;
my_uring_prep_readv( my_uring_prep_readv(
sqe, bs->dsk.data_fd, &data->iov, 1, bs->dsk.data_offset + old_clean_loc + vi.offset sqe, bs->dsk.data_fd, &data->iov, 1, bs->dsk.data_offset + old_clean_loc + vi.offset
@@ -1209,7 +1208,7 @@ bool journal_flusher_co::modify_meta_read(uint64_t meta_loc, flusher_meta_write_
.usage_count = 1, .usage_count = 1,
}).first; }).first;
await_sqe(0); await_sqe(0);
data->iov = (struct iovec){ wr.it->second.buf, (size_t)bs->dsk.meta_block_size }; data->iov = (struct iovec){ wr.it->second.buf, bs->dsk.meta_block_size };
data->callback = simple_callback_r; data->callback = simple_callback_r;
wr.submitted = true; wr.submitted = true;
my_uring_prep_readv( my_uring_prep_readv(
@@ -1248,7 +1247,7 @@ void journal_flusher_co::free_data_blocks()
auto uo_it = bs->used_clean_objects.find(old_clean_loc); auto uo_it = bs->used_clean_objects.find(old_clean_loc);
bool used = uo_it != bs->used_clean_objects.end(); bool used = uo_it != bs->used_clean_objects.end();
#ifdef BLOCKSTORE_DEBUG #ifdef BLOCKSTORE_DEBUG
printf("%s block %ju from %jx:%jx v%ju (new location is %ju)\n", printf("%s block %lu from %lx:%lx v%lu (new location is %lu)\n",
used ? "Postpone free" : "Free", used ? "Postpone free" : "Free",
old_clean_loc >> bs->dsk.block_order, old_clean_loc >> bs->dsk.block_order,
cur.oid.inode, cur.oid.stripe, cur.version, cur.oid.inode, cur.oid.stripe, cur.version,
@@ -1265,7 +1264,7 @@ void journal_flusher_co::free_data_blocks()
auto uo_it = bs->used_clean_objects.find(old_clean_loc); auto uo_it = bs->used_clean_objects.find(old_clean_loc);
bool used = uo_it != bs->used_clean_objects.end(); bool used = uo_it != bs->used_clean_objects.end();
#ifdef BLOCKSTORE_DEBUG #ifdef BLOCKSTORE_DEBUG
printf("%s block %ju from %jx:%jx v%ju (delete)\n", printf("%s block %lu from %lx:%lx v%lu (delete)\n",
used ? "Postpone free" : "Free", used ? "Postpone free" : "Free",
old_clean_loc >> bs->dsk.block_order, old_clean_loc >> bs->dsk.block_order,
cur.oid.inode, cur.oid.stripe, cur.version); cur.oid.inode, cur.oid.stripe, cur.version);
@@ -1347,6 +1346,7 @@ bool journal_flusher_co::trim_journal(int wait_base)
else if (wait_state == wait_base+2) goto resume_2; else if (wait_state == wait_base+2) goto resume_2;
else if (wait_state == wait_base+3) goto resume_3; else if (wait_state == wait_base+3) goto resume_3;
else if (wait_state == wait_base+4) goto resume_4; else if (wait_state == wait_base+4) goto resume_4;
flusher->journal_trim_counter = 0;
new_trim_pos = bs->journal.get_trim_pos(); new_trim_pos = bs->journal.get_trim_pos();
if (new_trim_pos != bs->journal.used_start) if (new_trim_pos != bs->journal.used_start)
{ {
@@ -1378,7 +1378,7 @@ bool journal_flusher_co::trim_journal(int wait_base)
.csum_block_size = bs->dsk.csum_block_size, .csum_block_size = bs->dsk.csum_block_size,
}; };
((journal_entry_start*)flusher->journal_superblock)->crc32 = je_crc32((journal_entry*)flusher->journal_superblock); ((journal_entry_start*)flusher->journal_superblock)->crc32 = je_crc32((journal_entry*)flusher->journal_superblock);
data->iov = (struct iovec){ flusher->journal_superblock, (size_t)bs->dsk.journal_block_size }; data->iov = (struct iovec){ flusher->journal_superblock, bs->dsk.journal_block_size };
data->callback = simple_callback_w; data->callback = simple_callback_w;
my_uring_prep_writev(sqe, bs->dsk.journal_fd, &data->iov, 1, bs->journal.offset); my_uring_prep_writev(sqe, bs->dsk.journal_fd, &data->iov, 1, bs->journal.offset);
wait_count++; wait_count++;
@@ -1410,7 +1410,7 @@ bool journal_flusher_co::trim_journal(int wait_base)
} }
bs->journal.used_start = new_trim_pos; bs->journal.used_start = new_trim_pos;
#ifdef BLOCKSTORE_DEBUG #ifdef BLOCKSTORE_DEBUG
printf("Journal trimmed to %08jx (next_free=%08jx dirty_start=%08jx)\n", bs->journal.used_start, bs->journal.next_free, bs->journal.dirty_start); printf("Journal trimmed to %08lx (next_free=%08lx dirty_start=%08lx)\n", bs->journal.used_start, bs->journal.next_free, bs->journal.dirty_start);
#endif #endif
if (bs->journal.flush_journal && !flusher->flush_queue.size()) if (bs->journal.flush_journal && !flusher->flush_queue.size())
{ {
@@ -1419,7 +1419,6 @@ bool journal_flusher_co::trim_journal(int wait_base)
exit(0); exit(0);
} }
} }
flusher->journal_trim_counter = 0;
flusher->trimming = false; flusher->trimming = false;
} }
return true; return true;
+1 -1
View File
@@ -107,7 +107,7 @@ class journal_flusher_t
blockstore_impl_t *bs; blockstore_impl_t *bs;
friend class journal_flusher_co; friend class journal_flusher_co;
int journal_trim_counter; int journal_trim_counter, journal_trim_interval;
bool trimming; bool trimming;
void* journal_superblock; void* journal_superblock;
+22 -21
View File
@@ -163,10 +163,20 @@ void blockstore_impl_t::loop()
} }
else if (op->opcode == BS_OP_SYNC) else if (op->opcode == BS_OP_SYNC)
{ {
// sync only completed writes? // wait for all small writes to be submitted
// wait for all big writes to complete, submit data device fsync
// wait for the data device fsync to complete, then submit journal writes for big writes // wait for the data device fsync to complete, then submit journal writes for big writes
// then submit an fsync operation // then submit an fsync operation
if (has_writes)
{
// Can't submit SYNC before previous writes
continue;
}
wr_st = continue_sync(op); wr_st = continue_sync(op);
if (wr_st != 2)
{
has_writes = wr_st > 0 ? 1 : 2;
}
} }
else if (op->opcode == BS_OP_STABLE) else if (op->opcode == BS_OP_STABLE)
{ {
@@ -195,10 +205,6 @@ void blockstore_impl_t::loop()
// ring is full, stop submission // ring is full, stop submission
break; break;
} }
else if (PRIV(op)->wait_for == WAIT_JOURNAL)
{
PRIV(op)->wait_detail2 = (unstable_writes.size()+unstable_unsynced);
}
} }
} }
if (op_idx != new_idx) if (op_idx != new_idx)
@@ -269,7 +275,7 @@ void blockstore_impl_t::check_wait(blockstore_op_t *op)
{ {
// stop submission if there's still no free space // stop submission if there's still no free space
#ifdef BLOCKSTORE_DEBUG #ifdef BLOCKSTORE_DEBUG
printf("Still waiting for %ju SQE(s)\n", PRIV(op)->wait_detail); printf("Still waiting for %lu SQE(s)\n", PRIV(op)->wait_detail);
#endif #endif
return; return;
} }
@@ -277,12 +283,11 @@ void blockstore_impl_t::check_wait(blockstore_op_t *op)
} }
else if (PRIV(op)->wait_for == WAIT_JOURNAL) else if (PRIV(op)->wait_for == WAIT_JOURNAL)
{ {
if (journal.used_start == PRIV(op)->wait_detail && if (journal.used_start == PRIV(op)->wait_detail)
(unstable_writes.size()+unstable_unsynced) == PRIV(op)->wait_detail2)
{ {
// do not submit // do not submit
#ifdef BLOCKSTORE_DEBUG #ifdef BLOCKSTORE_DEBUG
printf("Still waiting to flush journal offset %08jx\n", PRIV(op)->wait_detail); printf("Still waiting to flush journal offset %08lx\n", PRIV(op)->wait_detail);
#endif #endif
return; return;
} }
@@ -553,14 +558,13 @@ void blockstore_impl_t::process_list(blockstore_op_t *op)
if (stable_count >= stable_alloc) if (stable_count >= stable_alloc)
{ {
stable_alloc *= 2; stable_alloc *= 2;
obj_ver_id* nst = (obj_ver_id*)realloc(stable, sizeof(obj_ver_id) * stable_alloc); stable = (obj_ver_id*)realloc(stable, sizeof(obj_ver_id) * stable_alloc);
if (!nst) if (!stable)
{ {
op->retval = -ENOMEM; op->retval = -ENOMEM;
FINISH_OP(op); FINISH_OP(op);
return; return;
} }
stable = nst;
} }
stable[stable_count++] = { stable[stable_count++] = {
.oid = clean_it->first, .oid = clean_it->first,
@@ -638,8 +642,8 @@ void blockstore_impl_t::process_list(blockstore_op_t *op)
if (stable_count >= stable_alloc) if (stable_count >= stable_alloc)
{ {
stable_alloc += 32768; stable_alloc += 32768;
obj_ver_id *nst = (obj_ver_id*)realloc(stable, sizeof(obj_ver_id) * stable_alloc); stable = (obj_ver_id*)realloc(stable, sizeof(obj_ver_id) * stable_alloc);
if (!nst) if (!stable)
{ {
if (unstable) if (unstable)
free(unstable); free(unstable);
@@ -647,7 +651,6 @@ void blockstore_impl_t::process_list(blockstore_op_t *op)
FINISH_OP(op); FINISH_OP(op);
return; return;
} }
stable = nst;
} }
stable[stable_count++] = dirty_it->first; stable[stable_count++] = dirty_it->first;
} }
@@ -663,8 +666,8 @@ void blockstore_impl_t::process_list(blockstore_op_t *op)
if (unstable_count >= unstable_alloc) if (unstable_count >= unstable_alloc)
{ {
unstable_alloc += 32768; unstable_alloc += 32768;
obj_ver_id *nst = (obj_ver_id*)realloc(unstable, sizeof(obj_ver_id) * unstable_alloc); unstable = (obj_ver_id*)realloc(unstable, sizeof(obj_ver_id) * unstable_alloc);
if (!nst) if (!unstable)
{ {
if (stable) if (stable)
free(stable); free(stable);
@@ -672,7 +675,6 @@ void blockstore_impl_t::process_list(blockstore_op_t *op)
FINISH_OP(op); FINISH_OP(op);
return; return;
} }
unstable = nst;
} }
unstable[unstable_count++] = dirty_it->first; unstable[unstable_count++] = dirty_it->first;
} }
@@ -692,8 +694,8 @@ void blockstore_impl_t::process_list(blockstore_op_t *op)
if (stable_count+unstable_count > stable_alloc) if (stable_count+unstable_count > stable_alloc)
{ {
stable_alloc = stable_count+unstable_count; stable_alloc = stable_count+unstable_count;
obj_ver_id *nst = (obj_ver_id*)realloc(stable, sizeof(obj_ver_id) * stable_alloc); stable = (obj_ver_id*)realloc(stable, sizeof(obj_ver_id) * stable_alloc);
if (!nst) if (!stable)
{ {
if (unstable) if (unstable)
free(unstable); free(unstable);
@@ -701,7 +703,6 @@ void blockstore_impl_t::process_list(blockstore_op_t *op)
FINISH_OP(op); FINISH_OP(op);
return; return;
} }
stable = nst;
} }
// Copy unstable entries // Copy unstable entries
for (int i = 0; i < unstable_count; i++) for (int i = 0; i < unstable_count; i++)
+2 -4
View File
@@ -55,7 +55,6 @@
#define IS_JOURNAL(st) (((st) & 0x0F) == BS_ST_SMALL_WRITE) #define IS_JOURNAL(st) (((st) & 0x0F) == BS_ST_SMALL_WRITE)
#define IS_BIG_WRITE(st) (((st) & 0x0F) == BS_ST_BIG_WRITE) #define IS_BIG_WRITE(st) (((st) & 0x0F) == BS_ST_BIG_WRITE)
#define IS_DELETE(st) (((st) & 0x0F) == BS_ST_DELETE) #define IS_DELETE(st) (((st) & 0x0F) == BS_ST_DELETE)
#define IS_INSTANT(st) (((st) & BS_ST_TYPE_MASK) == BS_ST_DELETE || ((st) & BS_ST_INSTANT))
#define BS_SUBMIT_CHECK_SQES(n) \ #define BS_SUBMIT_CHECK_SQES(n) \
if (ringloop->sqes_left() < (n))\ if (ringloop->sqes_left() < (n))\
@@ -202,7 +201,7 @@ struct blockstore_op_private_t
{ {
// Wait status // Wait status
int wait_for; int wait_for;
uint64_t wait_detail, wait_detail2; uint64_t wait_detail;
int pending_ops; int pending_ops;
int op_state; int op_state;
@@ -253,7 +252,6 @@ class blockstore_impl_t
bool inmemory_meta = false; bool inmemory_meta = false;
// Maximum and minimum flusher count // Maximum and minimum flusher count
unsigned max_flusher_count, min_flusher_count; unsigned max_flusher_count, min_flusher_count;
unsigned journal_trim_interval;
// Maximum queue depth // Maximum queue depth
unsigned max_write_iodepth = 128; unsigned max_write_iodepth = 128;
// Enable small (journaled) write throttling, useful for the SSD+HDD case // Enable small (journaled) write throttling, useful for the SSD+HDD case
@@ -379,7 +377,7 @@ class blockstore_impl_t
// Stabilize // Stabilize
int dequeue_stable(blockstore_op_t *op); int dequeue_stable(blockstore_op_t *op);
int continue_stable(blockstore_op_t *op); int continue_stable(blockstore_op_t *op);
void mark_stable(obj_ver_id ov, bool forget_dirty = false); void mark_stable(const obj_ver_id & ov, bool forget_dirty = false);
void stabilize_object(object_id oid, uint64_t max_ver); void stabilize_object(object_id oid, uint64_t max_ver);
blockstore_op_t* selective_sync(blockstore_op_t *op); blockstore_op_t* selective_sync(blockstore_op_t *op);
int split_stab_op(blockstore_op_t *op, std::function<int(obj_ver_id v)> decider); int split_stab_op(blockstore_op_t *op, std::function<int(obj_ver_id v)> decider);
+33 -35
View File
@@ -63,7 +63,7 @@ int blockstore_init_meta::loop()
throw std::runtime_error("Failed to allocate metadata read buffer"); throw std::runtime_error("Failed to allocate metadata read buffer");
// Read superblock // Read superblock
GET_SQE(); GET_SQE();
data->iov = { metadata_buffer, (size_t)bs->dsk.meta_block_size }; data->iov = { metadata_buffer, bs->dsk.meta_block_size };
data->callback = [this](ring_data_t *data) { handle_event(data, -1); }; data->callback = [this](ring_data_t *data) { handle_event(data, -1); };
my_uring_prep_readv(sqe, bs->dsk.meta_fd, &data->iov, 1, bs->dsk.meta_offset); my_uring_prep_readv(sqe, bs->dsk.meta_fd, &data->iov, 1, bs->dsk.meta_offset);
bs->ringloop->submit(); bs->ringloop->submit();
@@ -100,7 +100,7 @@ resume_1:
{ {
printf("Initializing metadata area\n"); printf("Initializing metadata area\n");
GET_SQE(); GET_SQE();
data->iov = (struct iovec){ metadata_buffer, (size_t)bs->dsk.meta_block_size }; data->iov = (struct iovec){ metadata_buffer, bs->dsk.meta_block_size };
data->callback = [this](ring_data_t *data) { handle_event(data, -1); }; data->callback = [this](ring_data_t *data) { handle_event(data, -1); };
my_uring_prep_writev(sqe, bs->dsk.meta_fd, &data->iov, 1, bs->dsk.meta_offset); my_uring_prep_writev(sqe, bs->dsk.meta_fd, &data->iov, 1, bs->dsk.meta_offset);
bs->ringloop->submit(); bs->ringloop->submit();
@@ -153,7 +153,7 @@ resume_1:
else if (hdr->version > BLOCKSTORE_META_FORMAT_V2) else if (hdr->version > BLOCKSTORE_META_FORMAT_V2)
{ {
printf( printf(
"Metadata format is too new for me (stored version is %ju, max supported %u).\n", "Metadata format is too new for me (stored version is %lu, max supported %u).\n",
hdr->version, BLOCKSTORE_META_FORMAT_V2 hdr->version, BLOCKSTORE_META_FORMAT_V2
); );
exit(1); exit(1);
@@ -167,7 +167,7 @@ resume_1:
printf( printf(
"Configuration stored in metadata superblock" "Configuration stored in metadata superblock"
" (meta_block_size=%u, data_block_size=%u, bitmap_granularity=%u, data_csum_type=%u, csum_block_size=%u)" " (meta_block_size=%u, data_block_size=%u, bitmap_granularity=%u, data_csum_type=%u, csum_block_size=%u)"
" differs from OSD configuration (%ju/%u/%ju, %u/%u).\n", " differs from OSD configuration (%lu/%u/%lu, %u/%u).\n",
hdr->meta_block_size, hdr->data_block_size, hdr->bitmap_granularity, hdr->meta_block_size, hdr->data_block_size, hdr->bitmap_granularity,
hdr->data_csum_type, hdr->csum_block_size, hdr->data_csum_type, hdr->csum_block_size,
bs->dsk.meta_block_size, bs->dsk.data_block_size, bs->dsk.bitmap_granularity, bs->dsk.meta_block_size, bs->dsk.data_block_size, bs->dsk.bitmap_granularity,
@@ -199,8 +199,7 @@ resume_2:
submitted++; submitted++;
next_offset += bufs[i].size; next_offset += bufs[i].size;
GET_SQE(); GET_SQE();
assert(bufs[i].size <= 0x7fffffff); data->iov = { bufs[i].buf, bufs[i].size };
data->iov = { bufs[i].buf, (size_t)bufs[i].size };
data->callback = [this, i](ring_data_t *data) { handle_event(data, i); }; data->callback = [this, i](ring_data_t *data) { handle_event(data, i); };
if (!zero_on_init) if (!zero_on_init)
my_uring_prep_readv(sqe, bs->dsk.meta_fd, &data->iov, 1, bs->dsk.meta_offset + bufs[i].offset); my_uring_prep_readv(sqe, bs->dsk.meta_fd, &data->iov, 1, bs->dsk.meta_offset + bufs[i].offset);
@@ -232,8 +231,7 @@ resume_2:
{ {
// write the modified buffer back // write the modified buffer back
GET_SQE(); GET_SQE();
assert(bufs[i].size <= 0x7fffffff); data->iov = { bufs[i].buf, bufs[i].size };
data->iov = { bufs[i].buf, (size_t)bufs[i].size };
data->callback = [this, i](ring_data_t *data) { handle_event(data, i); }; data->callback = [this, i](ring_data_t *data) { handle_event(data, i); };
my_uring_prep_writev(sqe, bs->dsk.meta_fd, &data->iov, 1, bs->dsk.meta_offset + bufs[i].offset); my_uring_prep_writev(sqe, bs->dsk.meta_fd, &data->iov, 1, bs->dsk.meta_offset + bufs[i].offset);
bufs[i].state = INIT_META_WRITING; bufs[i].state = INIT_META_WRITING;
@@ -259,7 +257,7 @@ resume_2:
next_offset = entries_to_zero[i]/entries_per_block; next_offset = entries_to_zero[i]/entries_per_block;
for (j = i; j < entries_to_zero.size() && entries_to_zero[j]/entries_per_block == next_offset; j++) {} for (j = i; j < entries_to_zero.size() && entries_to_zero[j]/entries_per_block == next_offset; j++) {}
GET_SQE(); GET_SQE();
data->iov = { metadata_buffer, (size_t)bs->dsk.meta_block_size }; data->iov = { metadata_buffer, bs->dsk.meta_block_size };
data->callback = [this](ring_data_t *data) { handle_event(data, -1); }; data->callback = [this](ring_data_t *data) { handle_event(data, -1); };
my_uring_prep_readv(sqe, bs->dsk.meta_fd, &data->iov, 1, bs->dsk.meta_offset + (1+next_offset)*bs->dsk.meta_block_size); my_uring_prep_readv(sqe, bs->dsk.meta_fd, &data->iov, 1, bs->dsk.meta_offset + (1+next_offset)*bs->dsk.meta_block_size);
submitted++; submitted++;
@@ -275,7 +273,7 @@ resume_5:
memset((uint8_t*)metadata_buffer + pos*bs->dsk.clean_entry_size, 0, bs->dsk.clean_entry_size); memset((uint8_t*)metadata_buffer + pos*bs->dsk.clean_entry_size, 0, bs->dsk.clean_entry_size);
} }
GET_SQE(); GET_SQE();
data->iov = { metadata_buffer, (size_t)bs->dsk.meta_block_size }; data->iov = { metadata_buffer, bs->dsk.meta_block_size };
data->callback = [this](ring_data_t *data) { handle_event(data, -1); }; data->callback = [this](ring_data_t *data) { handle_event(data, -1); };
my_uring_prep_writev(sqe, bs->dsk.meta_fd, &data->iov, 1, bs->dsk.meta_offset + (1+next_offset)*bs->dsk.meta_block_size); my_uring_prep_writev(sqe, bs->dsk.meta_fd, &data->iov, 1, bs->dsk.meta_offset + (1+next_offset)*bs->dsk.meta_block_size);
submitted++; submitted++;
@@ -289,7 +287,7 @@ resume_6:
entries_to_zero.clear(); entries_to_zero.clear();
} }
// metadata read finished // metadata read finished
printf("Metadata entries loaded: %ju, free blocks: %ju / %ju\n", entries_loaded, bs->data_alloc->get_free_count(), bs->dsk.block_count); printf("Metadata entries loaded: %lu, free blocks: %lu / %lu\n", entries_loaded, bs->data_alloc->get_free_count(), bs->dsk.block_count);
if (!bs->inmemory_meta) if (!bs->inmemory_meta)
{ {
free(metadata_buffer); free(metadata_buffer);
@@ -330,7 +328,7 @@ bool blockstore_init_meta::handle_meta_block(uint8_t *buf, uint64_t entries_per_
uint32_t *entry_csum = (uint32_t*)((uint8_t*)entry + bs->dsk.clean_entry_size - 4); uint32_t *entry_csum = (uint32_t*)((uint8_t*)entry + bs->dsk.clean_entry_size - 4);
if (*entry_csum != crc32c(0, entry, bs->dsk.clean_entry_size - 4)) if (*entry_csum != crc32c(0, entry, bs->dsk.clean_entry_size - 4))
{ {
printf("Metadata entry %ju is corrupt (checksum mismatch), skipping\n", done_cnt+i); printf("Metadata entry %lu is corrupt (checksum mismatch), skipping\n", done_cnt+i);
continue; continue;
} }
} }
@@ -368,7 +366,7 @@ bool blockstore_init_meta::handle_meta_block(uint8_t *buf, uint64_t entries_per_
entries_to_zero.push_back(clean_it->second.location >> bs->dsk.block_order); entries_to_zero.push_back(clean_it->second.location >> bs->dsk.block_order);
} }
#ifdef BLOCKSTORE_DEBUG #ifdef BLOCKSTORE_DEBUG
printf("Free block %ju from %jx:%jx v%ju (new location is %ju)\n", printf("Free block %lu from %lx:%lx v%lu (new location is %lu)\n",
old_clean_loc, old_clean_loc,
clean_it->first.inode, clean_it->first.stripe, clean_it->second.version, clean_it->first.inode, clean_it->first.stripe, clean_it->second.version,
done_cnt+i); done_cnt+i);
@@ -382,7 +380,7 @@ bool blockstore_init_meta::handle_meta_block(uint8_t *buf, uint64_t entries_per_
} }
entries_loaded++; entries_loaded++;
#ifdef BLOCKSTORE_DEBUG #ifdef BLOCKSTORE_DEBUG
printf("Allocate block (clean entry) %ju: %jx:%jx v%ju\n", done_cnt+i, entry->oid.inode, entry->oid.stripe, entry->version); printf("Allocate block (clean entry) %lu: %lx:%lx v%lu\n", done_cnt+i, entry->oid.inode, entry->oid.stripe, entry->version);
#endif #endif
bs->data_alloc->set(done_cnt+i, true); bs->data_alloc->set(done_cnt+i, true);
clean_db[entry->oid] = (struct clean_entry){ clean_db[entry->oid] = (struct clean_entry){
@@ -396,7 +394,7 @@ bool blockstore_init_meta::handle_meta_block(uint8_t *buf, uint64_t entries_per_
updated = true; updated = true;
memset(entry, 0, bs->dsk.clean_entry_size); memset(entry, 0, bs->dsk.clean_entry_size);
#ifdef BLOCKSTORE_DEBUG #ifdef BLOCKSTORE_DEBUG
printf("Old clean entry %ju: %jx:%jx v%ju\n", done_cnt+i, entry->oid.inode, entry->oid.stripe, entry->version); printf("Old clean entry %lu: %lx:%lx v%lu\n", done_cnt+i, entry->oid.inode, entry->oid.stripe, entry->version);
#endif #endif
} }
} }
@@ -468,7 +466,7 @@ int blockstore_init_journal::loop()
if (!sqe) if (!sqe)
throw std::runtime_error("io_uring is full while trying to read journal"); throw std::runtime_error("io_uring is full while trying to read journal");
data = ((ring_data_t*)sqe->user_data); data = ((ring_data_t*)sqe->user_data);
data->iov = { submitted_buf, (size_t)bs->journal.block_size }; data->iov = { submitted_buf, bs->journal.block_size };
data->callback = simple_callback; data->callback = simple_callback;
my_uring_prep_readv(sqe, bs->dsk.journal_fd, &data->iov, 1, bs->journal.offset); my_uring_prep_readv(sqe, bs->dsk.journal_fd, &data->iov, 1, bs->journal.offset);
bs->ringloop->submit(); bs->ringloop->submit();
@@ -509,7 +507,7 @@ resume_1:
// FIXME: Randomize initial crc32. Track crc32 when trimming. // FIXME: Randomize initial crc32. Track crc32 when trimming.
printf("Resetting journal\n"); printf("Resetting journal\n");
GET_SQE(); GET_SQE();
data->iov = (struct iovec){ submitted_buf, (size_t)(2*bs->journal.block_size) }; data->iov = (struct iovec){ submitted_buf, 2*bs->journal.block_size };
data->callback = simple_callback; data->callback = simple_callback;
my_uring_prep_writev(sqe, bs->dsk.journal_fd, &data->iov, 1, bs->journal.offset); my_uring_prep_writev(sqe, bs->dsk.journal_fd, &data->iov, 1, bs->journal.offset);
wait_count++; wait_count++;
@@ -559,7 +557,7 @@ resume_1:
(je_start->version != JOURNAL_VERSION_V2 || je_start->size != JE_START_V2_SIZE && je_start->size != JE_START_V1_SIZE)) (je_start->version != JOURNAL_VERSION_V2 || je_start->size != JE_START_V2_SIZE && je_start->size != JE_START_V1_SIZE))
{ {
fprintf( fprintf(
stderr, "The code only supports journal versions 2 and 1, but it is %ju on disk." stderr, "The code only supports journal versions 2 and 1, but it is %lu on disk."
" Please use vitastor-disk to rewrite the journal\n", " Please use vitastor-disk to rewrite the journal\n",
je_start->size == JE_START_V0_SIZE ? 0 : je_start->version je_start->size == JE_START_V0_SIZE ? 0 : je_start->version
); );
@@ -608,7 +606,7 @@ resume_1:
submitted_buf = (uint8_t*)bs->journal.buffer + journal_pos; submitted_buf = (uint8_t*)bs->journal.buffer + journal_pos;
data->iov = { data->iov = {
submitted_buf, submitted_buf,
(size_t)(end - journal_pos < JOURNAL_BUFFER_SIZE ? end - journal_pos : JOURNAL_BUFFER_SIZE), end - journal_pos < JOURNAL_BUFFER_SIZE ? end - journal_pos : JOURNAL_BUFFER_SIZE,
}; };
data->callback = [this](ring_data_t *data1) { handle_event(data1); }; data->callback = [this](ring_data_t *data1) { handle_event(data1); };
my_uring_prep_readv(sqe, bs->dsk.journal_fd, &data->iov, 1, bs->journal.offset + journal_pos); my_uring_prep_readv(sqe, bs->dsk.journal_fd, &data->iov, 1, bs->journal.offset + journal_pos);
@@ -624,7 +622,7 @@ resume_1:
if (init_write_buf && !bs->readonly) if (init_write_buf && !bs->readonly)
{ {
GET_SQE(); GET_SQE();
data->iov = { init_write_buf, (size_t)bs->journal.block_size }; data->iov = { init_write_buf, bs->journal.block_size };
data->callback = simple_callback; data->callback = simple_callback;
my_uring_prep_writev(sqe, bs->dsk.journal_fd, &data->iov, 1, bs->journal.offset + init_write_sector); my_uring_prep_writev(sqe, bs->dsk.journal_fd, &data->iov, 1, bs->journal.offset + init_write_sector);
wait_count++; wait_count++;
@@ -693,7 +691,7 @@ resume_1:
IS_BIG_WRITE(dirty_it->second.state) && IS_BIG_WRITE(dirty_it->second.state) &&
dirty_it->second.location == UINT64_MAX) dirty_it->second.location == UINT64_MAX)
{ {
printf("Fatal error (bug): %jx:%jx v%ju big_write journal_entry was allocated over another object\n", printf("Fatal error (bug): %lx:%lx v%lu big_write journal_entry was allocated over another object\n",
dirty_it->first.oid.inode, dirty_it->first.oid.stripe, dirty_it->first.version); dirty_it->first.oid.inode, dirty_it->first.oid.stripe, dirty_it->first.version);
exit(1); exit(1);
} }
@@ -701,7 +699,7 @@ resume_1:
bs->flusher->mark_trim_possible(); bs->flusher->mark_trim_possible();
bs->journal.dirty_start = bs->journal.next_free; bs->journal.dirty_start = bs->journal.next_free;
printf( printf(
"Journal entries loaded: %ju, free journal space: %ju bytes (%08jx..%08jx is used), free blocks: %ju / %ju\n", "Journal entries loaded: %lu, free journal space: %lu bytes (%08lx..%08lx is used), free blocks: %lu / %lu\n",
entries_loaded, entries_loaded,
(bs->journal.next_free >= bs->journal.used_start (bs->journal.next_free >= bs->journal.used_start
? bs->journal.len-bs->journal.block_size - (bs->journal.next_free-bs->journal.used_start) ? bs->journal.len-bs->journal.block_size - (bs->journal.next_free-bs->journal.used_start)
@@ -756,7 +754,7 @@ int blockstore_init_journal::handle_journal_part(void *buf, uint64_t done_pos, u
{ {
#ifdef BLOCKSTORE_DEBUG #ifdef BLOCKSTORE_DEBUG
printf( printf(
"je_small_write%s oid=%jx:%jx ver=%ju offset=%u len=%u\n", "je_small_write%s oid=%lx:%lx ver=%lu offset=%u len=%u\n",
je->type == JE_SMALL_WRITE_INSTANT ? "_instant" : "", je->type == JE_SMALL_WRITE_INSTANT ? "_instant" : "",
je->small_write.oid.inode, je->small_write.oid.stripe, je->small_write.version, je->small_write.oid.inode, je->small_write.oid.stripe, je->small_write.version,
je->small_write.offset, je->small_write.len je->small_write.offset, je->small_write.len
@@ -778,7 +776,7 @@ int blockstore_init_journal::handle_journal_part(void *buf, uint64_t done_pos, u
if (location != je->small_write.data_offset) if (location != je->small_write.data_offset)
{ {
char err[1024]; char err[1024];
snprintf(err, 1024, "BUG: calculated journal data offset (%08jx) != stored journal data offset (%08jx)", location, je->small_write.data_offset); snprintf(err, 1024, "BUG: calculated journal data offset (%08lx) != stored journal data offset (%08lx)", location, je->small_write.data_offset);
throw std::runtime_error(err); throw std::runtime_error(err);
} }
small_write_data.clear(); small_write_data.clear();
@@ -805,7 +803,7 @@ int blockstore_init_journal::handle_journal_part(void *buf, uint64_t done_pos, u
covered += part_end - part_begin; covered += part_end - part_begin;
small_write_data.push_back((iovec){ small_write_data.push_back((iovec){
.iov_base = (uint8_t*)done[i].buf + part_begin - done[i].pos, .iov_base = (uint8_t*)done[i].buf + part_begin - done[i].pos,
.iov_len = (size_t)(part_end - part_begin), .iov_len = part_end - part_begin,
}); });
} }
} }
@@ -828,7 +826,7 @@ int blockstore_init_journal::handle_journal_part(void *buf, uint64_t done_pos, u
if (!data_csum_valid) if (!data_csum_valid)
{ {
printf( printf(
"Journal entry data is corrupt for small_write%s oid=%jx:%jx ver=%ju offset=%u len=%u - data crc32 %x != %x\n", "Journal entry data is corrupt for small_write%s oid=%lx:%lx ver=%lu offset=%u len=%u - data crc32 %x != %x\n",
je->type == JE_SMALL_WRITE_INSTANT ? "_instant" : "", je->type == JE_SMALL_WRITE_INSTANT ? "_instant" : "",
je->small_write.oid.inode, je->small_write.oid.stripe, je->small_write.version, je->small_write.oid.inode, je->small_write.oid.stripe, je->small_write.version,
je->small_write.offset, je->small_write.len, je->small_write.offset, je->small_write.len,
@@ -847,7 +845,7 @@ int blockstore_init_journal::handle_journal_part(void *buf, uint64_t done_pos, u
if (je->size != required_size) if (je->size != required_size)
{ {
printf( printf(
"Journal entry data has invalid size for small_write%s oid=%jx:%jx ver=%ju offset=%u len=%u - should be %u bytes but is %u bytes\n", "Journal entry data has invalid size for small_write%s oid=%lx:%lx ver=%lu offset=%u len=%u - should be %u bytes but is %u bytes\n",
je->type == JE_SMALL_WRITE_INSTANT ? "_instant" : "", je->type == JE_SMALL_WRITE_INSTANT ? "_instant" : "",
je->small_write.oid.inode, je->small_write.oid.stripe, je->small_write.version, je->small_write.oid.inode, je->small_write.oid.stripe, je->small_write.version,
je->small_write.offset, je->small_write.len, je->small_write.offset, je->small_write.len,
@@ -895,7 +893,7 @@ int blockstore_init_journal::handle_journal_part(void *buf, uint64_t done_pos, u
if (block_crc32 != *block_csums) if (block_crc32 != *block_csums)
{ {
printf( printf(
"Journal entry data is corrupt for small_write%s oid=%jx:%jx ver=%ju offset=%u len=%u - block %u crc32 %x != %x\n", "Journal entry data is corrupt for small_write%s oid=%lx:%lx ver=%lu offset=%u len=%u - block %u crc32 %x != %x\n",
je->type == JE_SMALL_WRITE_INSTANT ? "_instant" : "", je->type == JE_SMALL_WRITE_INSTANT ? "_instant" : "",
je->small_write.oid.inode, je->small_write.oid.stripe, je->small_write.version, je->small_write.oid.inode, je->small_write.oid.stripe, je->small_write.version,
je->small_write.offset, je->small_write.len, je->small_write.offset, je->small_write.len,
@@ -958,7 +956,7 @@ int blockstore_init_journal::handle_journal_part(void *buf, uint64_t done_pos, u
bs->journal.used_sectors[proc_pos]++; bs->journal.used_sectors[proc_pos]++;
#ifdef BLOCKSTORE_DEBUG #ifdef BLOCKSTORE_DEBUG
printf( printf(
"journal offset %08jx is used by %jx:%jx v%ju (%ju refs)\n", "journal offset %08lx is used by %lx:%lx v%lu (%lu refs)\n",
proc_pos, ov.oid.inode, ov.oid.stripe, ov.version, bs->journal.used_sectors[proc_pos] proc_pos, ov.oid.inode, ov.oid.stripe, ov.version, bs->journal.used_sectors[proc_pos]
); );
#endif #endif
@@ -974,7 +972,7 @@ int blockstore_init_journal::handle_journal_part(void *buf, uint64_t done_pos, u
{ {
#ifdef BLOCKSTORE_DEBUG #ifdef BLOCKSTORE_DEBUG
printf( printf(
"je_big_write%s oid=%jx:%jx ver=%ju loc=%ju\n", "je_big_write%s oid=%lx:%lx ver=%lu loc=%lu\n",
je->type == JE_BIG_WRITE_INSTANT ? "_instant" : "", je->type == JE_BIG_WRITE_INSTANT ? "_instant" : "",
je->big_write.oid.inode, je->big_write.oid.stripe, je->big_write.version, je->big_write.location >> bs->dsk.block_order je->big_write.oid.inode, je->big_write.oid.stripe, je->big_write.version, je->big_write.location >> bs->dsk.block_order
); );
@@ -1051,7 +1049,7 @@ int blockstore_init_journal::handle_journal_part(void *buf, uint64_t done_pos, u
{ {
#ifdef BLOCKSTORE_DEBUG #ifdef BLOCKSTORE_DEBUG
printf( printf(
"Allocate block (journal) %ju: %jx:%jx v%ju\n", "Allocate block (journal) %lu: %lx:%lx v%lu\n",
je->big_write.location >> bs->dsk.block_order, je->big_write.location >> bs->dsk.block_order,
ov.oid.inode, ov.oid.stripe, ov.version ov.oid.inode, ov.oid.stripe, ov.version
); );
@@ -1061,7 +1059,7 @@ int blockstore_init_journal::handle_journal_part(void *buf, uint64_t done_pos, u
bs->journal.used_sectors[proc_pos]++; bs->journal.used_sectors[proc_pos]++;
#ifdef BLOCKSTORE_DEBUG #ifdef BLOCKSTORE_DEBUG
printf( printf(
"journal offset %08jx is used by %jx:%jx v%ju (%ju refs)\n", "journal offset %08lx is used by %lx:%lx v%lu (%lu refs)\n",
proc_pos, ov.oid.inode, ov.oid.stripe, ov.version, bs->journal.used_sectors[proc_pos] proc_pos, ov.oid.inode, ov.oid.stripe, ov.version, bs->journal.used_sectors[proc_pos]
); );
#endif #endif
@@ -1076,7 +1074,7 @@ int blockstore_init_journal::handle_journal_part(void *buf, uint64_t done_pos, u
else if (je->type == JE_STABLE) else if (je->type == JE_STABLE)
{ {
#ifdef BLOCKSTORE_DEBUG #ifdef BLOCKSTORE_DEBUG
printf("je_stable oid=%jx:%jx ver=%ju\n", je->stable.oid.inode, je->stable.oid.stripe, je->stable.version); printf("je_stable oid=%lx:%lx ver=%lu\n", je->stable.oid.inode, je->stable.oid.stripe, je->stable.version);
#endif #endif
// oid, version // oid, version
obj_ver_id ov = { obj_ver_id ov = {
@@ -1088,7 +1086,7 @@ int blockstore_init_journal::handle_journal_part(void *buf, uint64_t done_pos, u
else if (je->type == JE_ROLLBACK) else if (je->type == JE_ROLLBACK)
{ {
#ifdef BLOCKSTORE_DEBUG #ifdef BLOCKSTORE_DEBUG
printf("je_rollback oid=%jx:%jx ver=%ju\n", je->rollback.oid.inode, je->rollback.oid.stripe, je->rollback.version); printf("je_rollback oid=%lx:%lx ver=%lu\n", je->rollback.oid.inode, je->rollback.oid.stripe, je->rollback.version);
#endif #endif
// rollback dirty writes of <oid> up to <version> // rollback dirty writes of <oid> up to <version>
obj_ver_id ov = { obj_ver_id ov = {
@@ -1100,7 +1098,7 @@ int blockstore_init_journal::handle_journal_part(void *buf, uint64_t done_pos, u
else if (je->type == JE_DELETE) else if (je->type == JE_DELETE)
{ {
#ifdef BLOCKSTORE_DEBUG #ifdef BLOCKSTORE_DEBUG
printf("je_delete oid=%jx:%jx ver=%ju\n", je->del.oid.inode, je->del.oid.stripe, je->del.version); printf("je_delete oid=%lx:%lx ver=%lu\n", je->del.oid.inode, je->del.oid.stripe, je->del.version);
#endif #endif
bool dirty_exists = false; bool dirty_exists = false;
auto dirty_it = bs->dirty_db.upper_bound((obj_ver_id){ auto dirty_it = bs->dirty_db.upper_bound((obj_ver_id){
+9 -9
View File
@@ -90,8 +90,8 @@ int blockstore_journal_check_t::check_available(blockstore_op_t *op, int entries
} }
// In fact, it's even more rare than "ran out of journal space", so print a warning // In fact, it's even more rare than "ran out of journal space", so print a warning
printf( printf(
"Ran out of journal sector buffers: %d/%ju buffers used (%d dirty), next buffer (%jd)" "Ran out of journal sector buffers: %d/%lu buffers used (%d dirty), next buffer (%ld)"
" is %s and flushed %ju times. Consider increasing \'journal_sector_buffer_count\'\n", " is %s and flushed %lu times. Consider increasing \'journal_sector_buffer_count\'\n",
used, bs->journal.sector_count, dirty, next_sector, used, bs->journal.sector_count, dirty, next_sector,
bs->journal.sector_info[next_sector].dirty ? "dirty" : "not dirty", bs->journal.sector_info[next_sector].dirty ? "dirty" : "not dirty",
bs->journal.sector_info[next_sector].flush_count bs->journal.sector_info[next_sector].flush_count
@@ -103,7 +103,7 @@ int blockstore_journal_check_t::check_available(blockstore_op_t *op, int entries
if (data_after > 0) if (data_after > 0)
{ {
next_pos = next_pos + data_after; next_pos = next_pos + data_after;
if (next_pos >= bs->journal.len) if (next_pos > bs->journal.len)
{ {
if (right_dir) if (right_dir)
next_pos = bs->journal.block_size + data_after; next_pos = bs->journal.block_size + data_after;
@@ -114,7 +114,7 @@ int blockstore_journal_check_t::check_available(blockstore_op_t *op, int entries
{ {
// No space in the journal. Wait until used_start changes. // No space in the journal. Wait until used_start changes.
printf( printf(
"Ran out of journal space (used_start=%08jx, next_free=%08jx, dirty_start=%08jx)\n", "Ran out of journal space (used_start=%08lx, next_free=%08lx, dirty_start=%08lx)\n",
bs->journal.used_start, bs->journal.next_free, bs->journal.dirty_start bs->journal.used_start, bs->journal.next_free, bs->journal.dirty_start
); );
PRIV(op)->wait_for = WAIT_JOURNAL; PRIV(op)->wait_for = WAIT_JOURNAL;
@@ -146,7 +146,7 @@ journal_entry* prefill_single_journal_entry(journal_t & journal, uint16_t type,
journal.in_sector_pos = 0; journal.in_sector_pos = 0;
auto next_next_free = (journal.next_free+journal.block_size) < journal.len ? journal.next_free + journal.block_size : journal.block_size; auto next_next_free = (journal.next_free+journal.block_size) < journal.len ? journal.next_free + journal.block_size : journal.block_size;
// double check that next_free doesn't cross used_start from the left // double check that next_free doesn't cross used_start from the left
assert(journal.next_free >= journal.used_start && next_next_free >= journal.next_free || next_next_free < journal.used_start); assert(journal.next_free >= journal.used_start || next_next_free < journal.used_start);
journal.next_free = next_next_free; journal.next_free = next_next_free;
memset(journal.inmemory memset(journal.inmemory
? (uint8_t*)journal.buffer + journal.sector_info[journal.cur_sector].offset ? (uint8_t*)journal.buffer + journal.sector_info[journal.cur_sector].offset
@@ -183,7 +183,7 @@ void blockstore_impl_t::prepare_journal_sector_write(int cur_sector, blockstore_
(journal.inmemory (journal.inmemory
? (uint8_t*)journal.buffer + journal.sector_info[cur_sector].offset ? (uint8_t*)journal.buffer + journal.sector_info[cur_sector].offset
: (uint8_t*)journal.sector_buf + journal.block_size*cur_sector), : (uint8_t*)journal.sector_buf + journal.block_size*cur_sector),
(size_t)journal.block_size journal.block_size
}; };
data->callback = [this, flush_id = journal.submit_id](ring_data_t *data) { handle_journal_write(data, flush_id); }; data->callback = [this, flush_id = journal.submit_id](ring_data_t *data) { handle_journal_write(data, flush_id); };
my_uring_prep_writev( my_uring_prep_writev(
@@ -263,7 +263,7 @@ uint64_t journal_t::get_trim_pos()
// next_free does not need updating during trim // next_free does not need updating during trim
#ifdef BLOCKSTORE_DEBUG #ifdef BLOCKSTORE_DEBUG
printf( printf(
"Trimming journal (used_start=%08jx, next_free=%08jx, dirty_start=%08jx, new_start=%08jx, new_refcount=%jd)\n", "Trimming journal (used_start=%08lx, next_free=%08lx, dirty_start=%08lx, new_start=%08lx, new_refcount=%ld)\n",
used_start, next_free, dirty_start, used_start, next_free, dirty_start,
journal_used_it->first, journal_used_it->second journal_used_it->first, journal_used_it->second
); );
@@ -276,7 +276,7 @@ uint64_t journal_t::get_trim_pos()
// Journal is cleared up to <journal_used_it> // Journal is cleared up to <journal_used_it>
#ifdef BLOCKSTORE_DEBUG #ifdef BLOCKSTORE_DEBUG
printf( printf(
"Trimming journal (used_start=%08jx, next_free=%08jx, dirty_start=%08jx, new_start=%08jx, new_refcount=%jd)\n", "Trimming journal (used_start=%08lx, next_free=%08lx, dirty_start=%08lx, new_start=%08lx, new_refcount=%ld)\n",
used_start, next_free, dirty_start, used_start, next_free, dirty_start,
journal_used_it->first, journal_used_it->second journal_used_it->first, journal_used_it->second
); );
@@ -296,7 +296,7 @@ void journal_t::dump_diagnostics()
journal_used_it = used_sectors.begin(); journal_used_it = used_sectors.begin();
} }
printf( printf(
"Journal: used_start=%08jx next_free=%08jx dirty_start=%08jx trim_to=%08jx trim_to_refs=%jd\n", "Journal: used_start=%08lx next_free=%08lx dirty_start=%08lx trim_to=%08lx trim_to_refs=%ld\n",
used_start, next_free, dirty_start, used_start, next_free, dirty_start,
journal_used_it == used_sectors.end() ? 0 : journal_used_it->first, journal_used_it == used_sectors.end() ? 0 : journal_used_it->first,
journal_used_it == used_sectors.end() ? 0 : journal_used_it->second journal_used_it == used_sectors.end() ? 0 : journal_used_it->second
+1 -6
View File
@@ -13,14 +13,13 @@ void blockstore_impl_t::parse_config(blockstore_config_t & config, bool init)
max_flusher_count = strtoull(config["flusher_count"].c_str(), NULL, 10); max_flusher_count = strtoull(config["flusher_count"].c_str(), NULL, 10);
} }
min_flusher_count = strtoull(config["min_flusher_count"].c_str(), NULL, 10); min_flusher_count = strtoull(config["min_flusher_count"].c_str(), NULL, 10);
journal_trim_interval = strtoull(config["journal_trim_interval"].c_str(), NULL, 10);
max_write_iodepth = strtoull(config["max_write_iodepth"].c_str(), NULL, 10); max_write_iodepth = strtoull(config["max_write_iodepth"].c_str(), NULL, 10);
throttle_small_writes = config["throttle_small_writes"] == "true" || config["throttle_small_writes"] == "1" || config["throttle_small_writes"] == "yes"; throttle_small_writes = config["throttle_small_writes"] == "true" || config["throttle_small_writes"] == "1" || config["throttle_small_writes"] == "yes";
throttle_target_iops = strtoull(config["throttle_target_iops"].c_str(), NULL, 10); throttle_target_iops = strtoull(config["throttle_target_iops"].c_str(), NULL, 10);
throttle_target_mbs = strtoull(config["throttle_target_mbs"].c_str(), NULL, 10); throttle_target_mbs = strtoull(config["throttle_target_mbs"].c_str(), NULL, 10);
throttle_target_parallelism = strtoull(config["throttle_target_parallelism"].c_str(), NULL, 10); throttle_target_parallelism = strtoull(config["throttle_target_parallelism"].c_str(), NULL, 10);
throttle_threshold_us = strtoull(config["throttle_threshold_us"].c_str(), NULL, 10); throttle_threshold_us = strtoull(config["throttle_threshold_us"].c_str(), NULL, 10);
if (config["autosync_writes"] != "") if (config.find("autosync_writes") != config.end())
{ {
autosync_writes = strtoull(config["autosync_writes"].c_str(), NULL, 10); autosync_writes = strtoull(config["autosync_writes"].c_str(), NULL, 10);
} }
@@ -32,10 +31,6 @@ void blockstore_impl_t::parse_config(blockstore_config_t & config, bool init)
{ {
min_flusher_count = 1; min_flusher_count = 1;
} }
if (!journal_trim_interval)
{
journal_trim_interval = 512;
}
if (!max_write_iodepth) if (!max_write_iodepth)
{ {
max_write_iodepth = 128; max_write_iodepth = 128;
+7 -7
View File
@@ -25,7 +25,7 @@ int blockstore_impl_t::fulfill_read_push(blockstore_op_t *op, void *buf, uint64_
return 1; return 1;
} }
BS_SUBMIT_GET_SQE(sqe, data); BS_SUBMIT_GET_SQE(sqe, data);
data->iov = (struct iovec){ buf, (size_t)len }; data->iov = (struct iovec){ buf, len };
PRIV(op)->pending_ops++; PRIV(op)->pending_ops++;
my_uring_prep_readv( my_uring_prep_readv(
sqe, sqe,
@@ -505,7 +505,7 @@ int blockstore_impl_t::dequeue_read(blockstore_op_t *read_op)
for (auto & rv: PRIV(read_op)->read_vec) for (auto & rv: PRIV(read_op)->read_vec)
{ {
if (rv.journal_sector) if (rv.journal_sector)
journal.used_sectors.at(rv.journal_sector-1)++; journal.used_sectors[rv.journal_sector-1]++;
} }
} }
read_op->retval = 0; read_op->retval = 0;
@@ -700,7 +700,7 @@ uint8_t* blockstore_impl_t::read_clean_meta_block(blockstore_op_t *op, uint64_t
.buf = buf, .buf = buf,
}); });
BS_SUBMIT_GET_SQE(sqe, data); BS_SUBMIT_GET_SQE(sqe, data);
data->iov = (struct iovec){ buf, (size_t)dsk.meta_block_size }; data->iov = (struct iovec){ buf, dsk.meta_block_size };
PRIV(op)->pending_ops++; PRIV(op)->pending_ops++;
my_uring_prep_readv(sqe, dsk.meta_fd, &data->iov, 1, dsk.meta_offset + dsk.meta_block_size + sector); my_uring_prep_readv(sqe, dsk.meta_fd, &data->iov, 1, dsk.meta_offset + dsk.meta_block_size + sector);
data->callback = [this, op](ring_data_t *data) { handle_read_event(data, op); }; data->callback = [this, op](ring_data_t *data) { handle_read_event(data, op); };
@@ -855,7 +855,7 @@ void blockstore_impl_t::handle_read_event(ring_data_t *data, blockstore_op_t *op
{ {
ok = false; ok = false;
printf( printf(
"Checksum mismatch in object %jx:%jx v%ju in journal at 0x%jx, checksum block #%u: got %08x, expected %08x\n", "Checksum mismatch in object %lx:%lx v%lu in journal at 0x%lx, checksum block #%u: got %08x, expected %08x\n",
op->oid.inode, op->oid.stripe, op->version, op->oid.inode, op->oid.stripe, op->version,
rv[i].disk_offset, bad_block / dsk.csum_block_size, calc_csum, stored_csum rv[i].disk_offset, bad_block / dsk.csum_block_size, calc_csum, stored_csum
); );
@@ -875,7 +875,7 @@ void blockstore_impl_t::handle_read_event(ring_data_t *data, blockstore_op_t *op
{ {
ok = false; ok = false;
printf( printf(
"Checksum mismatch in object %jx:%jx v%ju in %s data at 0x%jx, checksum block #%u: got %08x, expected %08x\n", "Checksum mismatch in object %lx:%lx v%lu in %s data at 0x%lx, checksum block #%u: got %08x, expected %08x\n",
op->oid.inode, op->oid.stripe, op->version, op->oid.inode, op->oid.stripe, op->version,
(rv[i].copy_flags & COPY_BUF_JOURNALED_BIG ? "redirect-write" : "clean"), (rv[i].copy_flags & COPY_BUF_JOURNALED_BIG ? "redirect-write" : "clean"),
rv[i].disk_offset, bad_block / dsk.csum_block_size, calc_csum, stored_csum rv[i].disk_offset, bad_block / dsk.csum_block_size, calc_csum, stored_csum
@@ -918,7 +918,7 @@ void blockstore_impl_t::handle_read_event(ring_data_t *data, blockstore_op_t *op
{ {
// checksum error // checksum error
printf( printf(
"Checksum mismatch in object %jx:%jx v%ju in %s area at offset 0x%jx+0x%zx: %08x vs %08x\n", "Checksum mismatch in object %lx:%lx v%lu in %s area at offset 0x%lx+0x%lx: %08x vs %08x\n",
op->oid.inode, op->oid.stripe, op->version, op->oid.inode, op->oid.stripe, op->version,
(vec.copy_flags & COPY_BUF_JOURNAL) ? "journal" : "data", vec.disk_offset, p, (vec.copy_flags & COPY_BUF_JOURNAL) ? "journal" : "data", vec.disk_offset, p,
crc32c(0, (uint8_t*)op->buf + vec.offset - op->offset + p, dsk.csum_block_size), *csum crc32c(0, (uint8_t*)op->buf + vec.offset - op->offset + p, dsk.csum_block_size), *csum
@@ -966,7 +966,7 @@ void blockstore_impl_t::handle_read_event(ring_data_t *data, blockstore_op_t *op
{ {
if (rv.journal_sector) if (rv.journal_sector)
{ {
auto used = --journal.used_sectors.at(rv.journal_sector-1); auto used = --journal.used_sectors[rv.journal_sector-1];
if (used == 0) if (used == 0)
{ {
journal.used_sectors.erase(rv.journal_sector-1); journal.used_sectors.erase(rv.journal_sector-1);
+4 -9
View File
@@ -179,7 +179,7 @@ void blockstore_impl_t::erase_dirty(blockstore_dirty_db_t::iterator dirty_start,
{ {
object_id oid = dirty_it->first.oid; object_id oid = dirty_it->first.oid;
#ifdef BLOCKSTORE_DEBUG #ifdef BLOCKSTORE_DEBUG
printf("Unblock writes-after-delete %jx:%jx v%ju\n", oid.inode, oid.stripe, dirty_it->first.version); printf("Unblock writes-after-delete %lx:%lx v%lu\n", oid.inode, oid.stripe, dirty_it->first.version);
#endif #endif
dirty_it = dirty_end; dirty_it = dirty_end;
// Unblock operations blocked by delete flushing // Unblock operations blocked by delete flushing
@@ -210,26 +210,21 @@ void blockstore_impl_t::erase_dirty(blockstore_dirty_db_t::iterator dirty_start,
dirty_it->second.location != UINT64_MAX) dirty_it->second.location != UINT64_MAX)
{ {
#ifdef BLOCKSTORE_DEBUG #ifdef BLOCKSTORE_DEBUG
printf("Free block %ju from %jx:%jx v%ju\n", dirty_it->second.location >> dsk.block_order, printf("Free block %lu from %lx:%lx v%lu\n", dirty_it->second.location >> dsk.block_order,
dirty_it->first.oid.inode, dirty_it->first.oid.stripe, dirty_it->first.version); dirty_it->first.oid.inode, dirty_it->first.oid.stripe, dirty_it->first.version);
#endif #endif
data_alloc->set(dirty_it->second.location >> dsk.block_order, false); data_alloc->set(dirty_it->second.location >> dsk.block_order, false);
} }
auto used = --journal.used_sectors.at(dirty_it->second.journal_sector); auto used = --journal.used_sectors[dirty_it->second.journal_sector];
#ifdef BLOCKSTORE_DEBUG #ifdef BLOCKSTORE_DEBUG
printf( printf(
"remove usage of journal offset %08jx by %jx:%jx v%ju (%ju refs)\n", dirty_it->second.journal_sector, "remove usage of journal offset %08lx by %lx:%lx v%lu (%lu refs)\n", dirty_it->second.journal_sector,
dirty_it->first.oid.inode, dirty_it->first.oid.stripe, dirty_it->first.version, used dirty_it->first.oid.inode, dirty_it->first.oid.stripe, dirty_it->first.version, used
); );
#endif #endif
if (used == 0) if (used == 0)
{ {
journal.used_sectors.erase(dirty_it->second.journal_sector); journal.used_sectors.erase(dirty_it->second.journal_sector);
if (dirty_it->second.journal_sector == journal.sector_info[journal.cur_sector].offset)
{
// Mark current sector as "full" to select the new one
journal.in_sector_pos = dsk.journal_block_size;
}
flusher->mark_trim_possible(); flusher->mark_trim_possible();
} }
free_dirty_dyn_data(dirty_it->second); free_dirty_dyn_data(dirty_it->second);
+26 -69
View File
@@ -298,7 +298,7 @@ int blockstore_impl_t::dequeue_stable(blockstore_op_t *op)
if (clean_it == clean_db.end() || clean_it->second.version < ov.version) if (clean_it == clean_db.end() || clean_it->second.version < ov.version)
{ {
// No such object version // No such object version
printf("Error: %jx:%jx v%ju not found while stabilizing\n", ov.oid.inode, ov.oid.stripe, ov.version); printf("Error: %lx:%lx v%lu not found while stabilizing\n", ov.oid.inode, ov.oid.stripe, ov.version);
return -ENOENT; return -ENOENT;
} }
else else
@@ -307,49 +307,35 @@ int blockstore_impl_t::dequeue_stable(blockstore_op_t *op)
return STAB_SPLIT_DONE; return STAB_SPLIT_DONE;
} }
} }
else if (IS_IN_FLIGHT(dirty_it->second.state))
{
// Object write is still in progress. Wait until the write request completes
return STAB_SPLIT_WAIT;
}
else if (!IS_SYNCED(dirty_it->second.state))
{
// Object not synced yet - sync it
// In previous versions we returned EBUSY here and required
// the caller (OSD) to issue a global sync first. But a global sync
// waits for all writes in the queue including inflight writes. And
// inflight writes may themselves be blocked by unstable writes being
// still present in the journal and not flushed away from it.
// So we must sync specific objects here.
//
// Even more, we have to process "stabilize" request in parts. That is,
// we must stabilize all objects which are already synced. Otherwise
// they may block objects which are NOT synced yet.
return STAB_SPLIT_SYNC;
}
else if (IS_STABLE(dirty_it->second.state)) else if (IS_STABLE(dirty_it->second.state))
{ {
// Already stable // Already stable
return STAB_SPLIT_DONE; return STAB_SPLIT_DONE;
} }
while (true) else
{ {
if (IS_IN_FLIGHT(dirty_it->second.state)) return STAB_SPLIT_TODO;
{
// Object write is still in progress. Wait until the write request completes
return STAB_SPLIT_WAIT;
}
else if (!IS_SYNCED(dirty_it->second.state))
{
// Object not synced yet - sync it
// In previous versions we returned EBUSY here and required
// the caller (OSD) to issue a global sync first. But a global sync
// waits for all writes in the queue including inflight writes. And
// inflight writes may themselves be blocked by unstable writes being
// still present in the journal and not flushed away from it.
// So we must sync specific objects here.
//
// Even more, we have to process "stabilize" request in parts. That is,
// we must stabilize all objects which are already synced. Otherwise
// they may block objects which are NOT synced yet.
return STAB_SPLIT_SYNC;
}
else if (IS_STABLE(dirty_it->second.state))
{
break;
}
// Check previous versions too
if (dirty_it == dirty_db.begin())
{
break;
}
dirty_it--;
if (dirty_it->first.oid != ov.oid)
{
break;
}
} }
return STAB_SPLIT_TODO;
}); });
if (r != 1) if (r != 1)
{ {
@@ -416,7 +402,7 @@ resume_4:
{ {
// Mark all dirty_db entries up to op->version as stable // Mark all dirty_db entries up to op->version as stable
#ifdef BLOCKSTORE_DEBUG #ifdef BLOCKSTORE_DEBUG
printf("Stabilize %jx:%jx v%ju\n", v->oid.inode, v->oid.stripe, v->version); printf("Stabilize %lx:%lx v%lu\n", v->oid.inode, v->oid.stripe, v->version);
#endif #endif
mark_stable(*v); mark_stable(*v);
} }
@@ -426,40 +412,11 @@ resume_4:
return 2; return 2;
} }
void blockstore_impl_t::mark_stable(obj_ver_id v, bool forget_dirty) void blockstore_impl_t::mark_stable(const obj_ver_id & v, bool forget_dirty)
{ {
auto dirty_it = dirty_db.find(v); auto dirty_it = dirty_db.find(v);
if (dirty_it != dirty_db.end()) if (dirty_it != dirty_db.end())
{ {
if (IS_INSTANT(dirty_it->second.state))
{
// 'Instant' (non-EC) operations may complete and try to become stable out of order. Prevent it.
auto back_it = dirty_it;
while (back_it != dirty_db.begin())
{
back_it--;
if (back_it->first.oid != v.oid)
{
break;
}
if (!IS_STABLE(back_it->second.state))
{
// There are preceding unstable versions, can't flush <v>
return;
}
}
while (true)
{
dirty_it++;
if (dirty_it == dirty_db.end() || dirty_it->first.oid != v.oid ||
!IS_SYNCED(dirty_it->second.state))
{
dirty_it--;
break;
}
v.version = dirty_it->first.version;
}
}
while (1) while (1)
{ {
bool was_stable = IS_STABLE(dirty_it->second.state); bool was_stable = IS_STABLE(dirty_it->second.state);
@@ -507,7 +464,7 @@ void blockstore_impl_t::mark_stable(obj_ver_id v, bool forget_dirty)
{ {
// mark_stable should never be called for in-flight or submitted writes // mark_stable should never be called for in-flight or submitted writes
printf( printf(
"BUG: Attempt to mark_stable object %jx:%jx v%ju state of which is %x\n", "BUG: Attempt to mark_stable object %lx:%lx v%lu state of which is %x\n",
dirty_it->first.oid.inode, dirty_it->first.oid.stripe, dirty_it->first.version, dirty_it->first.oid.inode, dirty_it->first.oid.stripe, dirty_it->first.version,
dirty_it->second.state dirty_it->second.state
); );
+8 -9
View File
@@ -85,14 +85,16 @@ int blockstore_impl_t::continue_sync(blockstore_op_t *op)
left--; left--;
auto & dirty_entry = dirty_db.at(sbw); auto & dirty_entry = dirty_db.at(sbw);
uint64_t dyn_size = dsk.dirty_dyn_size(dirty_entry.offset, dirty_entry.len); uint64_t dyn_size = dsk.dirty_dyn_size(dirty_entry.offset, dirty_entry.len);
if (!space_check.check_available(op, 1, sizeof(journal_entry_big_write) + dyn_size, 0)) if (!space_check.check_available(op, 1, sizeof(journal_entry_big_write) + dyn_size,
(unstable_writes.size()+unstable_unsynced)*journal.block_size))
{ {
return 0; return 0;
} }
} }
} }
else if (!space_check.check_available(op, PRIV(op)->sync_big_writes.size(), else if (!space_check.check_available(op, PRIV(op)->sync_big_writes.size(),
sizeof(journal_entry_big_write) + dsk.clean_entry_bitmap_size, 0)) sizeof(journal_entry_big_write) + dsk.clean_entry_bitmap_size,
(unstable_writes.size()+unstable_unsynced)*journal.block_size))
{ {
return 0; return 0;
} }
@@ -115,14 +117,11 @@ int blockstore_impl_t::continue_sync(blockstore_op_t *op)
journal, (dirty_entry.state & BS_ST_INSTANT) ? JE_BIG_WRITE_INSTANT : JE_BIG_WRITE, journal, (dirty_entry.state & BS_ST_INSTANT) ? JE_BIG_WRITE_INSTANT : JE_BIG_WRITE,
sizeof(journal_entry_big_write) + dyn_size sizeof(journal_entry_big_write) + dyn_size
); );
auto jsec = dirty_entry.journal_sector = journal.sector_info[journal.cur_sector].offset; dirty_entry.journal_sector = journal.sector_info[journal.cur_sector].offset;
assert(journal.next_free >= journal.used_start
? (jsec >= journal.used_start && jsec < journal.next_free)
: (jsec >= journal.used_start || jsec < journal.next_free));
journal.used_sectors[journal.sector_info[journal.cur_sector].offset]++; journal.used_sectors[journal.sector_info[journal.cur_sector].offset]++;
#ifdef BLOCKSTORE_DEBUG #ifdef BLOCKSTORE_DEBUG
printf( printf(
"journal offset %08jx is used by %jx:%jx v%ju (%ju refs)\n", "journal offset %08lx is used by %lx:%lx v%lu (%lu refs)\n",
dirty_entry.journal_sector, it->oid.inode, it->oid.stripe, it->version, dirty_entry.journal_sector, it->oid.inode, it->oid.stripe, it->version,
journal.used_sectors[journal.sector_info[journal.cur_sector].offset] journal.used_sectors[journal.sector_info[journal.cur_sector].offset]
); );
@@ -176,7 +175,7 @@ void blockstore_impl_t::ack_sync(blockstore_op_t *op)
for (auto it = PRIV(op)->sync_big_writes.begin(); it != PRIV(op)->sync_big_writes.end(); it++) for (auto it = PRIV(op)->sync_big_writes.begin(); it != PRIV(op)->sync_big_writes.end(); it++)
{ {
#ifdef BLOCKSTORE_DEBUG #ifdef BLOCKSTORE_DEBUG
printf("Ack sync big %jx:%jx v%ju\n", it->oid.inode, it->oid.stripe, it->version); printf("Ack sync big %lx:%lx v%lu\n", it->oid.inode, it->oid.stripe, it->version);
#endif #endif
auto & unstab = unstable_writes[it->oid]; auto & unstab = unstable_writes[it->oid];
unstab = unstab < it->version ? it->version : unstab; unstab = unstab < it->version ? it->version : unstab;
@@ -204,7 +203,7 @@ void blockstore_impl_t::ack_sync(blockstore_op_t *op)
for (auto it = PRIV(op)->sync_small_writes.begin(); it != PRIV(op)->sync_small_writes.end(); it++) for (auto it = PRIV(op)->sync_small_writes.begin(); it != PRIV(op)->sync_small_writes.end(); it++)
{ {
#ifdef BLOCKSTORE_DEBUG #ifdef BLOCKSTORE_DEBUG
printf("Ack sync small %jx:%jx v%ju\n", it->oid.inode, it->oid.stripe, it->version); printf("Ack sync small %lx:%lx v%lu\n", it->oid.inode, it->oid.stripe, it->version);
#endif #endif
auto & unstab = unstable_writes[it->oid]; auto & unstab = unstable_writes[it->oid];
unstab = unstab < it->version ? it->version : unstab; unstab = unstab < it->version ? it->version : unstab;
+26 -50
View File
@@ -85,7 +85,7 @@ bool blockstore_impl_t::enqueue_write(blockstore_op_t *op)
// It's allowed to write versions with low numbers over deletes // It's allowed to write versions with low numbers over deletes
// However, we have to flush those deletes first as we use version number for ordering // However, we have to flush those deletes first as we use version number for ordering
#ifdef BLOCKSTORE_DEBUG #ifdef BLOCKSTORE_DEBUG
printf("Write %jx:%jx v%ju over delete (real v%ju) offset=%u len=%u\n", op->oid.inode, op->oid.stripe, version, op->version, op->offset, op->len); printf("Write %lx:%lx v%lu over delete (real v%lu) offset=%u len=%u\n", op->oid.inode, op->oid.stripe, version, op->version, op->offset, op->len);
#endif #endif
wait_del = true; wait_del = true;
PRIV(op)->real_version = op->version; PRIV(op)->real_version = op->version;
@@ -117,7 +117,7 @@ bool blockstore_impl_t::enqueue_write(blockstore_op_t *op)
{ {
// Invalid version requested // Invalid version requested
#ifdef BLOCKSTORE_DEBUG #ifdef BLOCKSTORE_DEBUG
printf("Write %jx:%jx v%ju requested, but we already have v%ju\n", op->oid.inode, op->oid.stripe, op->version, version); printf("Write %lx:%lx v%lu requested, but we already have v%lu\n", op->oid.inode, op->oid.stripe, op->version, version);
#endif #endif
op->retval = -EEXIST; op->retval = -EEXIST;
if (!is_del && alloc_dyn_data) if (!is_del && alloc_dyn_data)
@@ -129,7 +129,7 @@ bool blockstore_impl_t::enqueue_write(blockstore_op_t *op)
} }
bool imm = (op->len < dsk.data_block_size ? (immediate_commit != IMMEDIATE_NONE) : (immediate_commit == IMMEDIATE_ALL)); bool imm = (op->len < dsk.data_block_size ? (immediate_commit != IMMEDIATE_NONE) : (immediate_commit == IMMEDIATE_ALL));
if (wait_big && !is_del && !deleted && op->len < dsk.data_block_size && !imm || if (wait_big && !is_del && !deleted && op->len < dsk.data_block_size && !imm ||
!imm && autosync_writes && unsynced_queued_ops >= autosync_writes) !imm && unsynced_queued_ops >= autosync_writes)
{ {
// Issue an additional sync so that the previous big write can reach the journal // Issue an additional sync so that the previous big write can reach the journal
blockstore_op_t *sync_op = new blockstore_op_t; blockstore_op_t *sync_op = new blockstore_op_t;
@@ -144,9 +144,9 @@ bool blockstore_impl_t::enqueue_write(blockstore_op_t *op)
unsynced_queued_ops++; unsynced_queued_ops++;
#ifdef BLOCKSTORE_DEBUG #ifdef BLOCKSTORE_DEBUG
if (is_del) if (is_del)
printf("Delete %jx:%jx v%ju\n", op->oid.inode, op->oid.stripe, op->version); printf("Delete %lx:%lx v%lu\n", op->oid.inode, op->oid.stripe, op->version);
else if (!wait_del) else if (!wait_del)
printf("Write %jx:%jx v%ju offset=%u len=%u\n", op->oid.inode, op->oid.stripe, op->version, op->offset, op->len); printf("Write %lx:%lx v%lu offset=%u len=%u\n", op->oid.inode, op->oid.stripe, op->version, op->offset, op->len);
#endif #endif
// No strict need to add it into dirty_db here except maybe for listings to return // No strict need to add it into dirty_db here except maybe for listings to return
// correct data when there are inflight operations in the queue // correct data when there are inflight operations in the queue
@@ -286,7 +286,7 @@ int blockstore_impl_t::dequeue_write(blockstore_op_t *op)
} }
// Restore original low version number for unblocked operations // Restore original low version number for unblocked operations
#ifdef BLOCKSTORE_DEBUG #ifdef BLOCKSTORE_DEBUG
printf("Restoring %jx:%jx version: v%ju -> v%ju\n", op->oid.inode, op->oid.stripe, op->version, PRIV(op)->real_version); printf("Restoring %lx:%lx version: v%lu -> v%lu\n", op->oid.inode, op->oid.stripe, op->version, PRIV(op)->real_version);
#endif #endif
auto prev_it = dirty_it; auto prev_it = dirty_it;
if (prev_it != dirty_db.begin()) if (prev_it != dirty_db.begin())
@@ -296,7 +296,7 @@ int blockstore_impl_t::dequeue_write(blockstore_op_t *op)
{ {
// Original version is still invalid // Original version is still invalid
// All subsequent writes to the same object must be canceled too // All subsequent writes to the same object must be canceled too
printf("Tried to write %jx:%jx v%ju after delete (old version v%ju), but already have v%ju\n", printf("Tried to write %lx:%lx v%lu after delete (old version v%lu), but already have v%lu\n",
op->oid.inode, op->oid.stripe, PRIV(op)->real_version, op->version, prev_it->first.version); op->oid.inode, op->oid.stripe, PRIV(op)->real_version, op->version, prev_it->first.version);
cancel_all_writes(op, dirty_it, -EEXIST); cancel_all_writes(op, dirty_it, -EEXIST);
return 2; return 2;
@@ -320,7 +320,7 @@ int blockstore_impl_t::dequeue_write(blockstore_op_t *op)
blockstore_journal_check_t space_check(this); blockstore_journal_check_t space_check(this);
if (!space_check.check_available(op, unsynced_big_write_count + 1, if (!space_check.check_available(op, unsynced_big_write_count + 1,
sizeof(journal_entry_big_write) + dsk.clean_dyn_size, sizeof(journal_entry_big_write) + dsk.clean_dyn_size,
(unstable_writes.size()+unstable_unsynced+((dirty_it->second.state & BS_ST_INSTANT) ? 0 : 1))*journal.block_size)) (unstable_writes.size()+unstable_unsynced)*journal.block_size))
{ {
return 0; return 0;
} }
@@ -348,8 +348,8 @@ int blockstore_impl_t::dequeue_write(blockstore_op_t *op)
if (entry->oid.inode || entry->oid.stripe || entry->version) if (entry->oid.inode || entry->oid.stripe || entry->version)
{ {
printf( printf(
"Fatal error (metadata corruption or bug): tried to write object %jx:%jx v%ju" "Fatal error (metadata corruption or bug): tried to write object %lx:%lx v%lu"
" over a non-zero metadata entry %ju with %jx:%jx v%ju\n", op->oid.inode, " over a non-zero metadata entry %lu with %lx:%lx v%lu\n", op->oid.inode,
op->oid.stripe, op->version, loc, entry->oid.inode, entry->oid.stripe, entry->version op->oid.stripe, op->version, loc, entry->oid.inode, entry->oid.stripe, entry->version
); );
exit(1); exit(1);
@@ -361,7 +361,7 @@ int blockstore_impl_t::dequeue_write(blockstore_op_t *op)
dirty_it->second.state = (dirty_it->second.state & ~BS_ST_WORKFLOW_MASK) | BS_ST_SUBMITTED; dirty_it->second.state = (dirty_it->second.state & ~BS_ST_WORKFLOW_MASK) | BS_ST_SUBMITTED;
#ifdef BLOCKSTORE_DEBUG #ifdef BLOCKSTORE_DEBUG
printf( printf(
"Allocate block %ju for %jx:%jx v%ju\n", "Allocate block %lu for %lx:%lx v%lu\n",
loc, op->oid.inode, op->oid.stripe, op->version loc, op->oid.inode, op->oid.stripe, op->version
); );
#endif #endif
@@ -372,13 +372,13 @@ int blockstore_impl_t::dequeue_write(blockstore_op_t *op)
int vcnt = 0; int vcnt = 0;
if (stripe_offset) if (stripe_offset)
{ {
PRIV(op)->iov_zerofill[vcnt++] = (struct iovec){ zero_object, (size_t)stripe_offset }; PRIV(op)->iov_zerofill[vcnt++] = (struct iovec){ zero_object, stripe_offset };
} }
PRIV(op)->iov_zerofill[vcnt++] = (struct iovec){ op->buf, op->len }; PRIV(op)->iov_zerofill[vcnt++] = (struct iovec){ op->buf, op->len };
if (stripe_end) if (stripe_end)
{ {
stripe_end = dsk.bitmap_granularity - stripe_end; stripe_end = dsk.bitmap_granularity - stripe_end;
PRIV(op)->iov_zerofill[vcnt++] = (struct iovec){ zero_object, (size_t)stripe_end }; PRIV(op)->iov_zerofill[vcnt++] = (struct iovec){ zero_object, stripe_end };
} }
data->iov.iov_len = op->len + stripe_offset + stripe_end; // to check it in the callback data->iov.iov_len = op->len + stripe_offset + stripe_end; // to check it in the callback
data->callback = [this, op](ring_data_t *data) { handle_write_event(data, op); }; data->callback = [this, op](ring_data_t *data) { handle_write_event(data, op); };
@@ -412,7 +412,7 @@ int blockstore_impl_t::dequeue_write(blockstore_op_t *op)
sizeof(journal_entry_big_write) + dsk.clean_dyn_size, 0) sizeof(journal_entry_big_write) + dsk.clean_dyn_size, 0)
|| !space_check.check_available(op, 1, || !space_check.check_available(op, 1,
sizeof(journal_entry_small_write) + dyn_size, sizeof(journal_entry_small_write) + dyn_size,
op->len + (unstable_writes.size()+unstable_unsynced+((dirty_it->second.state & BS_ST_INSTANT) ? 0 : 1))*journal.block_size)) op->len + (unstable_writes.size()+unstable_unsynced)*journal.block_size))
{ {
return 0; return 0;
} }
@@ -436,23 +436,11 @@ int blockstore_impl_t::dequeue_write(blockstore_op_t *op)
journal, op->opcode == BS_OP_WRITE_STABLE ? JE_SMALL_WRITE_INSTANT : JE_SMALL_WRITE, journal, op->opcode == BS_OP_WRITE_STABLE ? JE_SMALL_WRITE_INSTANT : JE_SMALL_WRITE,
sizeof(journal_entry_small_write) + dyn_size sizeof(journal_entry_small_write) + dyn_size
); );
auto jsec = dirty_it->second.journal_sector = journal.sector_info[journal.cur_sector].offset; dirty_it->second.journal_sector = journal.sector_info[journal.cur_sector].offset;
if (!(journal.next_free >= journal.used_start
? (jsec >= journal.used_start && jsec < journal.next_free)
: (jsec >= journal.used_start || jsec < journal.next_free)))
{
printf(
"BUG: journal offset %08jx is used by %jx:%jx v%ju (%ju refs) BUT used_start=%jx next_free=%jx\n",
dirty_it->second.journal_sector, dirty_it->first.oid.inode, dirty_it->first.oid.stripe, dirty_it->first.version,
journal.used_sectors[journal.sector_info[journal.cur_sector].offset],
journal.used_start, journal.next_free
);
abort();
}
journal.used_sectors[journal.sector_info[journal.cur_sector].offset]++; journal.used_sectors[journal.sector_info[journal.cur_sector].offset]++;
#ifdef BLOCKSTORE_DEBUG #ifdef BLOCKSTORE_DEBUG
printf( printf(
"journal offset %08jx is used by %jx:%jx v%ju (%ju refs)\n", "journal offset %08lx is used by %lx:%lx v%lu (%lu refs)\n",
dirty_it->second.journal_sector, dirty_it->first.oid.inode, dirty_it->first.oid.stripe, dirty_it->first.version, dirty_it->second.journal_sector, dirty_it->first.oid.inode, dirty_it->first.oid.stripe, dirty_it->first.version,
journal.used_sectors[journal.sector_info[journal.cur_sector].offset] journal.used_sectors[journal.sector_info[journal.cur_sector].offset]
); );
@@ -466,8 +454,8 @@ int blockstore_impl_t::dequeue_write(blockstore_op_t *op)
journal_used_it->first < next_next_free + op->len) journal_used_it->first < next_next_free + op->len)
{ {
printf( printf(
"BUG: Attempt to overwrite used offset (%jx, %ju refs) of the journal with the object %jx:%jx v%ju: data at %jx, len %x!" "BUG: Attempt to overwrite used offset (%lx, %lu refs) of the journal with the object %lx:%lx v%lu: data at %lx, len %x!"
" Journal used_start=%08jx (%ju refs), next_free=%08jx, dirty_start=%08jx\n", " Journal used_start=%08lx (%lu refs), next_free=%08lx, dirty_start=%08lx\n",
journal_used_it->first, journal_used_it->second, op->oid.inode, op->oid.stripe, op->version, next_next_free, op->len, journal_used_it->first, journal_used_it->second, op->oid.inode, op->oid.stripe, op->version, next_next_free, op->len,
journal.used_start, journal.used_sectors[journal.used_start], journal.next_free, journal.dirty_start journal.used_start, journal.used_sectors[journal.used_start], journal.next_free, journal.dirty_start
); );
@@ -475,7 +463,7 @@ int blockstore_impl_t::dequeue_write(blockstore_op_t *op)
} }
} }
// double check that next_free doesn't cross used_start from the left // double check that next_free doesn't cross used_start from the left
assert(journal.next_free >= journal.used_start && next_next_free >= journal.next_free || next_next_free < journal.used_start); assert(journal.next_free >= journal.used_start || next_next_free < journal.used_start);
journal.next_free = next_next_free; journal.next_free = next_next_free;
je->oid = op->oid; je->oid = op->oid;
je->version = op->version; je->version = op->version;
@@ -517,7 +505,7 @@ int blockstore_impl_t::dequeue_write(blockstore_op_t *op)
if (next_next_free >= journal.len) if (next_next_free >= journal.len)
next_next_free = dsk.journal_block_size; next_next_free = dsk.journal_block_size;
// double check that next_free doesn't cross used_start from the left // double check that next_free doesn't cross used_start from the left
assert(journal.next_free >= journal.used_start && next_next_free >= journal.next_free || next_next_free < journal.used_start); assert(journal.next_free >= journal.used_start || next_next_free < journal.used_start);
journal.next_free = next_next_free; journal.next_free = next_next_free;
if (!(dirty_it->second.state & BS_ST_INSTANT)) if (!(dirty_it->second.state & BS_ST_INSTANT))
{ {
@@ -561,7 +549,7 @@ resume_2:
uint64_t dyn_size = dsk.dirty_dyn_size(op->offset, op->len); uint64_t dyn_size = dsk.dirty_dyn_size(op->offset, op->len);
blockstore_journal_check_t space_check(this); blockstore_journal_check_t space_check(this);
if (!space_check.check_available(op, 1, sizeof(journal_entry_big_write) + dyn_size, if (!space_check.check_available(op, 1, sizeof(journal_entry_big_write) + dyn_size,
(unstable_writes.size()+unstable_unsynced+((dirty_it->second.state & BS_ST_INSTANT) ? 0 : 1))*journal.block_size)) (unstable_writes.size()+unstable_unsynced)*journal.block_size))
{ {
return 0; return 0;
} }
@@ -570,23 +558,11 @@ resume_2:
journal, op->opcode == BS_OP_WRITE_STABLE ? JE_BIG_WRITE_INSTANT : JE_BIG_WRITE, journal, op->opcode == BS_OP_WRITE_STABLE ? JE_BIG_WRITE_INSTANT : JE_BIG_WRITE,
sizeof(journal_entry_big_write) + dyn_size sizeof(journal_entry_big_write) + dyn_size
); );
auto jsec = dirty_it->second.journal_sector = journal.sector_info[journal.cur_sector].offset; dirty_it->second.journal_sector = journal.sector_info[journal.cur_sector].offset;
if (!(journal.next_free >= journal.used_start
? (jsec >= journal.used_start && jsec < journal.next_free)
: (jsec >= journal.used_start || jsec < journal.next_free)))
{
printf(
"BUG: journal offset %08jx is used by %jx:%jx v%ju (%ju refs) BUT used_start=%jx next_free=%jx\n",
dirty_it->second.journal_sector, dirty_it->first.oid.inode, dirty_it->first.oid.stripe, dirty_it->first.version,
journal.used_sectors[journal.sector_info[journal.cur_sector].offset],
journal.used_start, journal.next_free
);
abort();
}
journal.used_sectors[journal.sector_info[journal.cur_sector].offset]++; journal.used_sectors[journal.sector_info[journal.cur_sector].offset]++;
#ifdef BLOCKSTORE_DEBUG #ifdef BLOCKSTORE_DEBUG
printf( printf(
"journal offset %08jx is used by %jx:%jx v%ju (%ju refs)\n", "journal offset %08lx is used by %lx:%lx v%lu (%lu refs)\n",
journal.sector_info[journal.cur_sector].offset, op->oid.inode, op->oid.stripe, op->version, journal.sector_info[journal.cur_sector].offset, op->oid.inode, op->oid.stripe, op->version,
journal.used_sectors[journal.sector_info[journal.cur_sector].offset] journal.used_sectors[journal.sector_info[journal.cur_sector].offset]
); );
@@ -613,11 +589,11 @@ resume_4:
}); });
assert(dirty_it != dirty_db.end()); assert(dirty_it != dirty_db.end());
#ifdef BLOCKSTORE_DEBUG #ifdef BLOCKSTORE_DEBUG
printf("Ack write %jx:%jx v%ju = state 0x%x\n", op->oid.inode, op->oid.stripe, op->version, dirty_it->second.state); printf("Ack write %lx:%lx v%lu = state 0x%x\n", op->oid.inode, op->oid.stripe, op->version, dirty_it->second.state);
#endif #endif
bool is_big = (dirty_it->second.state & BS_ST_TYPE_MASK) == BS_ST_BIG_WRITE; bool is_big = (dirty_it->second.state & BS_ST_TYPE_MASK) == BS_ST_BIG_WRITE;
bool imm = is_big ? (immediate_commit == IMMEDIATE_ALL) : (immediate_commit != IMMEDIATE_NONE); bool imm = is_big ? (immediate_commit == IMMEDIATE_ALL) : (immediate_commit != IMMEDIATE_NONE);
bool is_instant = IS_INSTANT(dirty_it->second.state); bool is_instant = ((dirty_it->second.state & BS_ST_TYPE_MASK) == BS_ST_DELETE || (dirty_it->second.state & BS_ST_INSTANT));
if (imm) if (imm)
{ {
auto & unstab = unstable_writes[op->oid]; auto & unstab = unstable_writes[op->oid];
@@ -806,7 +782,7 @@ int blockstore_impl_t::dequeue_del(blockstore_op_t *op)
journal.used_sectors[journal.sector_info[journal.cur_sector].offset]++; journal.used_sectors[journal.sector_info[journal.cur_sector].offset]++;
#ifdef BLOCKSTORE_DEBUG #ifdef BLOCKSTORE_DEBUG
printf( printf(
"journal offset %08jx is used by %jx:%jx v%ju (%ju refs)\n", "journal offset %08lx is used by %lx:%lx v%lu (%lu refs)\n",
dirty_it->second.journal_sector, dirty_it->first.oid.inode, dirty_it->first.oid.stripe, dirty_it->first.version, dirty_it->second.journal_sector, dirty_it->first.oid.inode, dirty_it->first.oid.stripe, dirty_it->first.version,
journal.used_sectors[journal.sector_info[journal.cur_sector].offset] journal.used_sectors[journal.sector_info[journal.cur_sector].offset]
); );
+1 -1
View File
@@ -77,7 +77,7 @@ struct alloc_osd_t
std::string key = base64_decode(kv["key"].string_value()); std::string key = base64_decode(kv["key"].string_value());
osd_num_t cur_osd; osd_num_t cur_osd;
char null_byte = 0; char null_byte = 0;
int scanned = sscanf(key.c_str() + parent->cli->st_cli.etcd_prefix.length(), "/osd/stats/%ju%c", &cur_osd, &null_byte); int scanned = sscanf(key.c_str() + parent->cli->st_cli.etcd_prefix.length(), "/osd/stats/%lu%c", &cur_osd, &null_byte);
if (scanned != 1 || !cur_osd) if (scanned != 1 || !cur_osd)
{ {
fprintf(stderr, "Invalid key in etcd: %s\n", key.c_str()); fprintf(stderr, "Invalid key in etcd: %s\n", key.c_str());
+1 -1
View File
@@ -11,7 +11,7 @@ void cli_tool_t::change_parent(inode_t cur, inode_t new_parent, cli_result_t *re
if (cur_cfg_it == cli->st_cli.inode_config.end()) if (cur_cfg_it == cli->st_cli.inode_config.end())
{ {
char buf[128]; char buf[128];
snprintf(buf, 128, "Inode 0x%jx disappeared", cur); snprintf(buf, 128, "Inode 0x%lx disappeared", cur);
*result = (cli_result_t){ .err = EIO, .text = buf }; *result = (cli_result_t){ .err = EIO, .text = buf };
return; return;
} }
+4 -4
View File
@@ -160,14 +160,14 @@ struct cli_describe_t
if (op->reply.hdr.retval < 0) if (op->reply.hdr.retval < 0)
{ {
fprintf( fprintf(
stderr, "Failed to describe objects on OSD %ju (retval=%jd)\n", stderr, "Failed to describe objects on OSD %lu (retval=%ld)\n",
osd_num, op->reply.hdr.retval osd_num, op->reply.hdr.retval
); );
} }
else if (op->reply.describe.result_bytes != op->reply.hdr.retval * sizeof(osd_reply_describe_item_t)) else if (op->reply.describe.result_bytes != op->reply.hdr.retval * sizeof(osd_reply_describe_item_t))
{ {
fprintf( fprintf(
stderr, "Invalid response size from OSD %ju (expected %ju bytes, got %ju bytes)\n", stderr, "Invalid response size from OSD %lu (expected %lu bytes, got %lu bytes)\n",
osd_num, op->reply.hdr.retval * sizeof(osd_reply_describe_item_t), op->reply.describe.result_bytes osd_num, op->reply.hdr.retval * sizeof(osd_reply_describe_item_t), op->reply.describe.result_bytes
); );
} }
@@ -178,11 +178,11 @@ struct cli_describe_t
{ {
if (!parent->json_output || parent->is_command_line) if (!parent->json_output || parent->is_command_line)
{ {
#define FMT "{\"inode\":\"0x%jx\",\"stripe\":\"0x%jx\",\"part\":%u,\"osd_num\":%ju%s%s%s}" #define FMT "{\"inode\":\"0x%lx\",\"stripe\":\"0x%lx\",\"part\":%u,\"osd_num\":%lu%s%s%s}"
printf( printf(
(parent->json_output (parent->json_output
? (count > 0 ? ",\n " FMT : " " FMT) ? (count > 0 ? ",\n " FMT : " " FMT)
: "%jx:%jx part %u on OSD %ju%s%s%s\n"), : "%lx:%lx part %u on OSD %lu%s%s%s\n"),
#undef FMT #undef FMT
items[i].inode, items[i].stripe, items[i].inode, items[i].stripe,
items[i].role, items[i].osd_num, items[i].role, items[i].osd_num,
+1 -1
View File
@@ -82,7 +82,7 @@ resume_1:
// osd ID // osd ID
osd_num_t osd_num; osd_num_t osd_num;
char null_byte = 0; char null_byte = 0;
int scanned = sscanf(kv.key.substr(parent->cli->st_cli.etcd_prefix.length()).c_str(), "/osd/stats/%ju%c", &osd_num, &null_byte); int scanned = sscanf(kv.key.substr(parent->cli->st_cli.etcd_prefix.length()).c_str(), "/osd/stats/%lu%c", &osd_num, &null_byte);
if (scanned != 1 || !osd_num || osd_num >= POOL_ID_MAX) if (scanned != 1 || !osd_num || osd_num >= POOL_ID_MAX)
{ {
fprintf(stderr, "Invalid key in etcd: %s\n", kv.key.c_str()); fprintf(stderr, "Invalid key in etcd: %s\n", kv.key.c_str());
+6 -6
View File
@@ -136,7 +136,7 @@ struct cli_fix_t
auto pool_cfg_it = parent->cli->st_cli.pool_config.find(INODE_POOL(obj.inode)); auto pool_cfg_it = parent->cli->st_cli.pool_config.find(INODE_POOL(obj.inode));
if (pool_cfg_it == parent->cli->st_cli.pool_config.end()) if (pool_cfg_it == parent->cli->st_cli.pool_config.end())
{ {
fprintf(stderr, "Object %jx:%jx is from unknown pool\n", obj.inode, obj.stripe); fprintf(stderr, "Object %lx:%lx is from unknown pool\n", obj.inode, obj.stripe);
continue; continue;
} }
auto & pool_cfg = pool_cfg_it->second; auto & pool_cfg = pool_cfg_it->second;
@@ -146,7 +146,7 @@ struct cli_fix_t
!pg_it->second.cur_primary || !(pg_it->second.cur_state & PG_ACTIVE)) !pg_it->second.cur_primary || !(pg_it->second.cur_state & PG_ACTIVE))
{ {
fprintf( fprintf(
stderr, "Object %jx:%jx is from PG %u/%u which is not currently active\n", stderr, "Object %lx:%lx is from PG %u/%u which is not currently active\n",
obj.inode, obj.stripe, pool_cfg_it->first, pg_num obj.inode, obj.stripe, pool_cfg_it->first, pg_num
); );
continue; continue;
@@ -171,7 +171,7 @@ struct cli_fix_t
{ {
if (op->reply.hdr.retval < 0 || op->reply.describe.result_bytes != op->reply.hdr.retval * sizeof(osd_reply_describe_item_t)) if (op->reply.hdr.retval < 0 || op->reply.describe.result_bytes != op->reply.hdr.retval * sizeof(osd_reply_describe_item_t))
{ {
fprintf(stderr, "Failed to describe objects on OSD %ju (retval=%jd)\n", primary_osd, op->reply.hdr.retval); fprintf(stderr, "Failed to describe objects on OSD %lu (retval=%ld)\n", primary_osd, op->reply.hdr.retval);
parent->waiting--; parent->waiting--;
loop(); loop();
} }
@@ -209,7 +209,7 @@ struct cli_fix_t
if (rm_op->reply.hdr.retval < 0) if (rm_op->reply.hdr.retval < 0)
{ {
fprintf( fprintf(
stderr, "Failed to remove object %jx:%jx from OSD %ju (retval=%jd)\n", stderr, "Failed to remove object %lx:%lx from OSD %lu (retval=%ld)\n",
rm_op->req.sec_del.oid.inode, rm_op->req.sec_del.oid.stripe, rm_op->req.sec_del.oid.inode, rm_op->req.sec_del.oid.stripe,
rm_osd_num, rm_op->reply.hdr.retval rm_osd_num, rm_op->reply.hdr.retval
); );
@@ -226,7 +226,7 @@ struct cli_fix_t
else else
{ {
printf( printf(
"Removed %jx:%jx (part %ju) from OSD %ju\n", "Removed %lx:%lx (part %lu) from OSD %lu\n",
rm_op->req.sec_del.oid.inode, rm_op->req.sec_del.oid.stripe & ~STRIPE_MASK, rm_op->req.sec_del.oid.inode, rm_op->req.sec_del.oid.stripe & ~STRIPE_MASK,
rm_op->req.sec_del.oid.stripe & STRIPE_MASK, rm_osd_num rm_op->req.sec_del.oid.stripe & STRIPE_MASK, rm_osd_num
); );
@@ -254,7 +254,7 @@ struct cli_fix_t
if (scrub_op->reply.hdr.retval < 0 && scrub_op->reply.hdr.retval != -ENOENT) if (scrub_op->reply.hdr.retval < 0 && scrub_op->reply.hdr.retval != -ENOENT)
{ {
fprintf( fprintf(
stderr, "Failed to scrub %jx:%jx on OSD %ju (retval=%jd)\n", stderr, "Failed to scrub %lx:%lx on OSD %lu (retval=%ld)\n",
obj.inode, obj.stripe, primary_osd, scrub_op->reply.hdr.retval obj.inode, obj.stripe, primary_osd, scrub_op->reply.hdr.retval
); );
} }
+2 -2
View File
@@ -150,7 +150,7 @@ resume_1:
inode_t only_inode_num; inode_t only_inode_num;
char null_byte = 0; char null_byte = 0;
int scanned = sscanf(kv.key.substr(parent->cli->st_cli.etcd_prefix.length()).c_str(), int scanned = sscanf(kv.key.substr(parent->cli->st_cli.etcd_prefix.length()).c_str(),
"/inode/stats/%u/%ju%c", &pool_id, &only_inode_num, &null_byte); "/inode/stats/%u/%lu%c", &pool_id, &only_inode_num, &null_byte);
if (scanned != 2 || !pool_id || pool_id >= POOL_ID_MAX || INODE_POOL(only_inode_num) != 0) if (scanned != 2 || !pool_id || pool_id >= POOL_ID_MAX || INODE_POOL(only_inode_num) != 0)
{ {
fprintf(stderr, "Invalid key in etcd: %s\n", kv.key.c_str()); fprintf(stderr, "Invalid key in etcd: %s\n", kv.key.c_str());
@@ -456,7 +456,7 @@ std::string format_lat(uint64_t lat)
char buf[256]; char buf[256];
int l = 0; int l = 0;
if (lat < 100) if (lat < 100)
l = snprintf(buf, sizeof(buf), "%ju us", lat); l = snprintf(buf, sizeof(buf), "%lu us", lat);
else if (lat < 500000) else if (lat < 500000)
l = snprintf(buf, sizeof(buf), "%.2f ms", (double)lat/1000); l = snprintf(buf, sizeof(buf), "%.2f ms", (double)lat/1000);
else else
+9 -9
View File
@@ -202,7 +202,7 @@ struct snap_merger_t
if (parent->progress) if (parent->progress)
{ {
printf( printf(
"Merging %zd layer(s) into target %s%s (inode %ju in pool %u)\n", "Merging %ld layer(s) into target %s%s (inode %lu in pool %u)\n",
sources.size(), target_cfg->name.c_str(), sources.size(), target_cfg->name.c_str(),
use_cas ? " online (with CAS)" : "", INODE_NO_POOL(target), INODE_POOL(target) use_cas ? " online (with CAS)" : "", INODE_NO_POOL(target), INODE_POOL(target)
); );
@@ -275,7 +275,7 @@ struct snap_merger_t
processed++; processed++;
if (parent->progress && !(processed % 128)) if (parent->progress && !(processed % 128))
{ {
printf("\rFiltering target blocks: %ju/%ju", processed, to_process); printf("\rFiltering target blocks: %lu/%lu", processed, to_process);
} }
} }
if (in_flight > 0 || oit != merge_offsets.end()) if (in_flight > 0 || oit != merge_offsets.end())
@@ -285,7 +285,7 @@ struct snap_merger_t
} }
if (parent->progress) if (parent->progress)
{ {
printf("\r%ju full blocks of target filtered out\n", to_process-merge_offsets.size()); printf("\r%lu full blocks of target filtered out\n", to_process-merge_offsets.size());
} }
} }
state = 3; state = 3;
@@ -320,7 +320,7 @@ struct snap_merger_t
processed++; processed++;
if (parent->progress && !(processed % 128)) if (parent->progress && !(processed % 128))
{ {
printf("\rOverwriting blocks: %ju/%ju", processed, to_process); printf("\rOverwriting blocks: %lu/%lu", processed, to_process);
} }
} }
if (in_flight == 0 && rwo_error.size()) if (in_flight == 0 && rwo_error.size())
@@ -339,7 +339,7 @@ struct snap_merger_t
} }
if (parent->progress) if (parent->progress)
{ {
printf("\rOverwriting blocks: %ju/%ju\n", to_process, to_process); printf("\rOverwriting blocks: %lu/%lu\n", to_process, to_process);
} }
// Done // Done
result = (cli_result_t){ .text = "Done, layers from "+from_name+" to "+to_name+" merged into "+target_name }; result = (cli_result_t){ .text = "Done, layers from "+from_name+" to "+to_name+" merged into "+target_name };
@@ -384,7 +384,7 @@ struct snap_merger_t
auto & name = parent->cli->st_cli.inode_config.at(src).name; auto & name = parent->cli->st_cli.inode_config.at(src).name;
if (parent->progress) if (parent->progress)
{ {
printf("Got listing of layer %s (inode %ju in pool %u)\n", name.c_str(), INODE_NO_POOL(src), INODE_POOL(src)); printf("Got listing of layer %s (inode %lu in pool %u)\n", name.c_str(), INODE_NO_POOL(src), INODE_POOL(src));
} }
if (delete_source) if (delete_source)
{ {
@@ -416,7 +416,7 @@ struct snap_merger_t
{ {
if (op->retval < 0) if (op->retval < 0)
{ {
fprintf(stderr, "error reading target bitmap at offset %jx: %s\n", op->offset, strerror(-op->retval)); fprintf(stderr, "error reading target bitmap at offset %lx: %s\n", op->offset, strerror(-op->retval));
} }
else else
{ {
@@ -571,7 +571,7 @@ struct snap_merger_t
{ {
if (subop->retval != 0) if (subop->retval != 0)
{ {
fprintf(stderr, "error deleting from layer 0x%jx at offset %jx: %s", subop->inode, subop->offset, strerror(-subop->retval)); fprintf(stderr, "error deleting from layer 0x%lx at offset %lx: %s", subop->inode, subop->offset, strerror(-subop->retval));
} }
delete subop; delete subop;
}; };
@@ -620,7 +620,7 @@ struct snap_merger_t
if (rwo->error_code) if (rwo->error_code)
{ {
char buf[1024]; char buf[1024];
snprintf(buf, 1024, "Error %s target at offset %jx: %s", snprintf(buf, 1024, "Error %s target at offset %lx: %s",
rwo->error_read ? "reading" : "writing", rwo->error_offset, strerror(rwo->error_code)); rwo->error_read ? "reading" : "writing", rwo->error_offset, strerror(rwo->error_code));
rwo_error = std::string(buf); rwo_error = std::string(buf);
} }
+8 -8
View File
@@ -291,7 +291,7 @@ resume_100:
if (it == parent->cli->st_cli.inode_config.end()) if (it == parent->cli->st_cli.inode_config.end())
{ {
char buf[1024]; char buf[1024];
snprintf(buf, 1024, "Parent inode of layer %s (id 0x%jx) not found", cur->name.c_str(), cur->parent_id); snprintf(buf, 1024, "Parent inode of layer %s (id 0x%lx) not found", cur->name.c_str(), cur->parent_id);
state = 100; state = 100;
return; return;
} }
@@ -384,7 +384,7 @@ resume_100:
pool_id_t pool_id = 0; pool_id_t pool_id = 0;
inode_t inode = 0; inode_t inode = 0;
char null_byte = 0; char null_byte = 0;
int scanned = sscanf(kv.key.c_str() + parent->cli->st_cli.etcd_prefix.length()+13, "%u/%ju%c", &pool_id, &inode, &null_byte); int scanned = sscanf(kv.key.c_str() + parent->cli->st_cli.etcd_prefix.length()+13, "%u/%lu%c", &pool_id, &inode, &null_byte);
if (scanned != 2 || !inode) if (scanned != 2 || !inode)
{ {
result = (cli_result_t){ .err = EIO, .text = "Bad key returned from etcd: "+kv.key }; result = (cli_result_t){ .err = EIO, .text = "Bad key returned from etcd: "+kv.key };
@@ -439,7 +439,7 @@ resume_100:
if (child_it == parent->cli->st_cli.inode_config.end()) if (child_it == parent->cli->st_cli.inode_config.end())
{ {
char buf[1024]; char buf[1024];
snprintf(buf, 1024, "Inode 0x%jx disappeared", inverse_child); snprintf(buf, 1024, "Inode 0x%lx disappeared", inverse_child);
result = (cli_result_t){ .err = EIO, .text = std::string(buf) }; result = (cli_result_t){ .err = EIO, .text = std::string(buf) };
state = 100; state = 100;
return; return;
@@ -448,7 +448,7 @@ resume_100:
if (target_it == parent->cli->st_cli.inode_config.end()) if (target_it == parent->cli->st_cli.inode_config.end())
{ {
char buf[1024]; char buf[1024];
snprintf(buf, 1024, "Inode 0x%jx disappeared", inverse_parent); snprintf(buf, 1024, "Inode 0x%lx disappeared", inverse_parent);
result = (cli_result_t){ .err = EIO, .text = std::string(buf) }; result = (cli_result_t){ .err = EIO, .text = std::string(buf) };
state = 100; state = 100;
return; return;
@@ -576,7 +576,7 @@ resume_100:
if (cur_cfg_it == parent->cli->st_cli.inode_config.end()) if (cur_cfg_it == parent->cli->st_cli.inode_config.end())
{ {
char buf[1024]; char buf[1024];
snprintf(buf, 1024, "Inode 0x%jx disappeared", cur); snprintf(buf, 1024, "Inode 0x%lx disappeared", cur);
result = (cli_result_t){ .err = EIO, .text = std::string(buf) }; result = (cli_result_t){ .err = EIO, .text = std::string(buf) };
state = 100; state = 100;
return; return;
@@ -640,7 +640,7 @@ resume_100:
if (child_it == parent->cli->st_cli.inode_config.end()) if (child_it == parent->cli->st_cli.inode_config.end())
{ {
char buf[1024]; char buf[1024];
snprintf(buf, 1024, "Inode 0x%jx disappeared", child_inode); snprintf(buf, 1024, "Inode 0x%lx disappeared", child_inode);
result = (cli_result_t){ .err = EIO, .text = std::string(buf) }; result = (cli_result_t){ .err = EIO, .text = std::string(buf) };
state = 100; state = 100;
return; return;
@@ -649,7 +649,7 @@ resume_100:
if (target_it == parent->cli->st_cli.inode_config.end()) if (target_it == parent->cli->st_cli.inode_config.end())
{ {
char buf[1024]; char buf[1024];
snprintf(buf, 1024, "Inode 0x%jx disappeared", target_inode); snprintf(buf, 1024, "Inode 0x%lx disappeared", target_inode);
result = (cli_result_t){ .err = EIO, .text = std::string(buf) }; result = (cli_result_t){ .err = EIO, .text = std::string(buf) };
state = 100; state = 100;
return; return;
@@ -670,7 +670,7 @@ resume_100:
if (source == parent->cli->st_cli.inode_config.end()) if (source == parent->cli->st_cli.inode_config.end())
{ {
char buf[1024]; char buf[1024];
snprintf(buf, 1024, "Inode 0x%jx disappeared", inode); snprintf(buf, 1024, "Inode 0x%lx disappeared", inode);
result = (cli_result_t){ .err = EIO, .text = std::string(buf) }; result = (cli_result_t){ .err = EIO, .text = std::string(buf) };
state = 100; state = 100;
return; return;
+7 -41
View File
@@ -17,7 +17,6 @@ struct rm_pg_t
uint64_t obj_count = 0, obj_done = 0; uint64_t obj_count = 0, obj_done = 0;
int state = 0; int state = 0;
int in_flight = 0; int in_flight = 0;
bool synced = false;
}; };
struct rm_inode_t struct rm_inode_t
@@ -49,7 +48,6 @@ struct rm_inode_t
.objects = objects, .objects = objects,
.obj_count = objects.size(), .obj_count = objects.size(),
.obj_done = 0, .obj_done = 0,
.synced = parent->cli->get_immediate_commit(inode),
}); });
if (min_offset == 0) if (min_offset == 0)
{ {
@@ -95,7 +93,7 @@ struct rm_inode_t
fprintf(stderr, "Some data may remain after delete on OSDs which are currently down: "); fprintf(stderr, "Some data may remain after delete on OSDs which are currently down: ");
for (int i = 0; i < inactive_osds.size(); i++) for (int i = 0; i < inactive_osds.size(); i++)
{ {
fprintf(stderr, i > 0 ? ", %ju" : "%ju", inactive_osds[i]); fprintf(stderr, i > 0 ? ", %lu" : "%lu", inactive_osds[i]);
} }
fprintf(stderr, "\n"); fprintf(stderr, "\n");
} }
@@ -138,7 +136,7 @@ struct rm_inode_t
cur_list->in_flight--; cur_list->in_flight--;
if (op->reply.hdr.retval < 0) if (op->reply.hdr.retval < 0)
{ {
fprintf(stderr, "Failed to remove object %jx:%jx from PG %u (OSD %ju) (retval=%jd)\n", fprintf(stderr, "Failed to remove object %lx:%lx from PG %u (OSD %lu) (retval=%ld)\n",
op->req.rw.inode, op->req.rw.offset, op->req.rw.inode, op->req.rw.offset,
cur_list->pg_num, cur_list->rm_osd_num, op->reply.hdr.retval); cur_list->pg_num, cur_list->rm_osd_num, op->reply.hdr.retval);
error_count++; error_count++;
@@ -153,37 +151,6 @@ struct rm_inode_t
} }
cur_list->obj_pos++; cur_list->obj_pos++;
} }
if (cur_list->in_flight == 0 && cur_list->obj_pos == cur_list->objects.end() &&
!cur_list->synced)
{
osd_op_t *op = new osd_op_t();
op->op_type = OSD_OP_OUT;
op->peer_fd = parent->cli->msgr.osd_peer_fds.at(cur_list->rm_osd_num);
op->req = (osd_any_op_t){
.sync = {
.header = {
.magic = SECONDARY_OSD_OP_MAGIC,
.id = parent->cli->next_op_id(),
.opcode = OSD_OP_SYNC,
},
},
};
op->callback = [this, cur_list](osd_op_t *op)
{
cur_list->in_flight--;
cur_list->synced = true;
if (op->reply.hdr.retval < 0)
{
fprintf(stderr, "Failed to sync OSD %ju (retval=%jd)\n",
cur_list->rm_osd_num, op->reply.hdr.retval);
error_count++;
}
delete op;
continue_delete();
};
cur_list->in_flight++;
parent->cli->msgr.outbox_push(op);
}
} }
void continue_delete() void continue_delete()
@@ -194,8 +161,7 @@ struct rm_inode_t
} }
for (int i = 0; i < lists.size(); i++) for (int i = 0; i < lists.size(); i++)
{ {
if (!lists[i]->in_flight && lists[i]->obj_pos == lists[i]->objects.end() && if (!lists[i]->in_flight && lists[i]->obj_pos == lists[i]->objects.end())
lists[i]->synced)
{ {
delete lists[i]; delete lists[i];
lists.erase(lists.begin()+i, lists.begin()+i+1); lists.erase(lists.begin()+i, lists.begin()+i+1);
@@ -212,7 +178,7 @@ struct rm_inode_t
} }
if (parent->progress && total_count > 0 && total_done*1000/total_count != total_prev_pct) if (parent->progress && total_count > 0 && total_done*1000/total_count != total_prev_pct)
{ {
fprintf(stderr, "\rRemoved %ju/%ju objects, %ju more PGs to list...", total_done, total_count, pgs_to_list); fprintf(stderr, "\rRemoved %lu/%lu objects, %lu more PGs to list...", total_done, total_count, pgs_to_list);
total_prev_pct = total_done*1000/total_count; total_prev_pct = total_done*1000/total_count;
} }
if (lists_done && !lists.size()) if (lists_done && !lists.size())
@@ -221,11 +187,11 @@ struct rm_inode_t
{ {
fprintf(stderr, "\n"); fprintf(stderr, "\n");
} }
if (parent->progress && (total_done < total_count || inactive_osds.size() > 0 || error_count > 0)) if (parent->progress && (total_done < total_count || inactive_osds.size() > 0))
{ {
fprintf( fprintf(
stderr, "Warning: Pool:%u,ID:%ju inode data may not have been fully removed.\n" stderr, "Warning: Pool:%u,ID:%lu inode data may not have been fully removed.\n"
" Use `vitastor-cli rm-data --pool %u --inode %ju` if you encounter it in listings.\n", " Use `vitastor-cli rm-data --pool %u --inode %lu` if you encounter it in listings.\n",
pool_id, INODE_NO_POOL(inode), pool_id, INODE_NO_POOL(inode) pool_id, INODE_NO_POOL(inode), pool_id, INODE_NO_POOL(inode)
); );
} }
+3 -3
View File
@@ -106,7 +106,7 @@ resume_2:
if (etcd_states[i]["error"].is_null()) if (etcd_states[i]["error"].is_null())
{ {
etcd_alive++; etcd_alive++;
etcd_db_size = etcd_states[i]["dbSize"].uint64_value(); etcd_db_size = etcd_states[i]["dbSizeInUse"].uint64_value();
} }
} }
int mon_count = 0; int mon_count = 0;
@@ -132,7 +132,7 @@ resume_2:
auto kv = parent->cli->st_cli.parse_etcd_kv(osd_stats[i]); auto kv = parent->cli->st_cli.parse_etcd_kv(osd_stats[i]);
osd_num_t stat_osd_num = 0; osd_num_t stat_osd_num = 0;
char null_byte = 0; char null_byte = 0;
int scanned = sscanf(kv.key.c_str() + parent->cli->st_cli.etcd_prefix.size(), "/osd/stats/%ju%c", &stat_osd_num, &null_byte); int scanned = sscanf(kv.key.c_str() + parent->cli->st_cli.etcd_prefix.size(), "/osd/stats/%lu%c", &stat_osd_num, &null_byte);
if (scanned != 1 || !stat_osd_num) if (scanned != 1 || !stat_osd_num)
{ {
fprintf(stderr, "Invalid key in etcd: %s\n", kv.key.c_str()); fprintf(stderr, "Invalid key in etcd: %s\n", kv.key.c_str());
@@ -283,7 +283,7 @@ resume_2:
} }
printf( printf(
" cluster:\n" " cluster:\n"
" etcd: %d / %zd up, %s database size\n" " etcd: %d / %ld up, %s database size\n"
" mon: %d up%s\n" " mon: %d up%s\n"
" osd: %d / %d up\n" " osd: %d / %d up\n"
" \n" " \n"
+9 -9
View File
@@ -6,7 +6,7 @@
#include "cluster_client_impl.h" #include "cluster_client_impl.h"
#include "http_client.h" // json_is_true #include "http_client.h" // json_is_true
cluster_client_t::cluster_client_t(ring_loop_t *ringloop, timerfd_manager_t *tfd, json11::Json & config) cluster_client_t::cluster_client_t(ring_loop_t *ringloop, timerfd_manager_t *tfd, json11::Json config)
{ {
wb = new writeback_cache_t(); wb = new writeback_cache_t();
@@ -353,11 +353,11 @@ void cluster_client_t::on_load_config_hook(json11::Json::object & etcd_global_co
up_wait_retry_interval = config["up_wait_retry_interval"].uint64_value(); up_wait_retry_interval = config["up_wait_retry_interval"].uint64_value();
if (!up_wait_retry_interval) if (!up_wait_retry_interval)
{ {
up_wait_retry_interval = 50; up_wait_retry_interval = 500;
} }
else if (up_wait_retry_interval < 10) else if (up_wait_retry_interval < 50)
{ {
up_wait_retry_interval = 10; up_wait_retry_interval = 50;
} }
// log_level // log_level
log_level = config["log_level"].uint64_value(); log_level = config["log_level"].uint64_value();
@@ -534,7 +534,7 @@ void cluster_client_t::execute_internal(cluster_op_t *op)
return; return;
} }
if (op->opcode == OSD_OP_WRITE && enable_writeback && !(op->flags & OP_FLUSH_BUFFER) && if (op->opcode == OSD_OP_WRITE && enable_writeback && !(op->flags & OP_FLUSH_BUFFER) &&
!op->version /* FIXME no CAS writeback */) !op->version /* no CAS writeback */)
{ {
if (wb->writebacks_active >= client_max_writeback_iodepth) if (wb->writebacks_active >= client_max_writeback_iodepth)
{ {
@@ -555,7 +555,7 @@ void cluster_client_t::execute_internal(cluster_op_t *op)
} }
if (op->opcode == OSD_OP_WRITE && !(op->flags & OP_IMMEDIATE_COMMIT)) if (op->opcode == OSD_OP_WRITE && !(op->flags & OP_IMMEDIATE_COMMIT))
{ {
if (!(op->flags & OP_FLUSH_BUFFER)) if (!(op->flags & OP_FLUSH_BUFFER) && !op->version /* no CAS write-repeat */)
{ {
wb->copy_write(op, CACHE_WRITTEN); wb->copy_write(op, CACHE_WRITTEN);
} }
@@ -1156,15 +1156,15 @@ void cluster_client_t::handle_op_part(cluster_op_part_t *part)
if (op->retval != -EPIPE || log_level > 0) if (op->retval != -EPIPE || log_level > 0)
{ {
fprintf( fprintf(
stderr, "%s operation failed on OSD %ju: retval=%jd (expected %d), dropping connection\n", stderr, "%s operation failed on OSD %lu: retval=%ld (expected %d), dropping connection\n",
osd_op_names[part->op.req.hdr.opcode], part->osd_num, part->op.reply.hdr.retval, expected osd_op_names[part->op.req.hdr.opcode], part->osd_num, part->op.reply.hdr.retval, expected
); );
} }
} }
else else if (log_level > 0)
{ {
fprintf( fprintf(
stderr, "%s operation failed on OSD %ju: retval=%jd (expected %d)\n", stderr, "%s operation failed on OSD %lu: retval=%ld (expected %d)\n",
osd_op_names[part->op.req.hdr.opcode], part->osd_num, part->op.reply.hdr.retval, expected osd_op_names[part->op.req.hdr.opcode], part->osd_num, part->op.reply.hdr.retval, expected
); );
} }
+1 -1
View File
@@ -121,7 +121,7 @@ public:
json11::Json::object cli_config, file_config, etcd_global_config; json11::Json::object cli_config, file_config, etcd_global_config;
json11::Json::object config; json11::Json::object config;
cluster_client_t(ring_loop_t *ringloop, timerfd_manager_t *tfd, json11::Json & config); cluster_client_t(ring_loop_t *ringloop, timerfd_manager_t *tfd, json11::Json config);
~cluster_client_t(); ~cluster_client_t();
void execute(cluster_op_t *op); void execute(cluster_op_t *op);
void execute_raw(osd_num_t osd_num, osd_op_t *op); void execute_raw(osd_num_t osd_num, osd_op_t *op);
+3 -3
View File
@@ -226,7 +226,7 @@ void cluster_client_t::send_list(inode_list_osd_t *cur_list)
{ {
if (op->reply.hdr.retval < 0) if (op->reply.hdr.retval < 0)
{ {
fprintf(stderr, "Failed to get PG %u/%u object list from OSD %ju (retval=%jd), skipping\n", fprintf(stderr, "Failed to get PG %u/%u object list from OSD %lu (retval=%ld), skipping\n",
cur_list->pg->lst->pool_id, cur_list->pg->pg_num, cur_list->osd_num, op->reply.hdr.retval); cur_list->pg->lst->pool_id, cur_list->pg->pg_num, cur_list->osd_num, op->reply.hdr.retval);
} }
else else
@@ -236,7 +236,7 @@ void cluster_client_t::send_list(inode_list_osd_t *cur_list)
// Unstable objects, if present, mean that someone still writes into the inode. Warn the user about it. // Unstable objects, if present, mean that someone still writes into the inode. Warn the user about it.
cur_list->pg->has_unstable = true; cur_list->pg->has_unstable = true;
fprintf( fprintf(
stderr, "[PG %u/%u] Inode still has %ju unstable object versions out of total %ju - is it still open?\n", stderr, "[PG %u/%u] Inode still has %lu unstable object versions out of total %lu - is it still open?\n",
cur_list->pg->lst->pool_id, cur_list->pg->pg_num, op->reply.hdr.retval - op->reply.sec_list.stable_count, cur_list->pg->lst->pool_id, cur_list->pg->pg_num, op->reply.hdr.retval - op->reply.sec_list.stable_count,
op->reply.hdr.retval op->reply.hdr.retval
); );
@@ -244,7 +244,7 @@ void cluster_client_t::send_list(inode_list_osd_t *cur_list)
if (log_level > 0) if (log_level > 0)
{ {
fprintf( fprintf(
stderr, "[PG %u/%u] Got inode object list from OSD %ju: %jd object versions\n", stderr, "[PG %u/%u] Got inode object list from OSD %lu: %ld object versions\n",
cur_list->pg->lst->pool_id, cur_list->pg->pg_num, cur_list->osd_num, op->reply.hdr.retval cur_list->pg->lst->pool_id, cur_list->pg->pg_num, cur_list->osd_num, op->reply.hdr.retval
); );
} }
+12 -12
View File
@@ -47,7 +47,7 @@ void disk_tool_simple_offsets(json11::Json cfg, bool json_output)
if (!bitmap_granularity) if (!bitmap_granularity)
bitmap_granularity = DEFAULT_BITMAP_GRANULARITY; bitmap_granularity = DEFAULT_BITMAP_GRANULARITY;
if (!journal_size) if (!journal_size)
journal_size = 32*1024*1024; journal_size = 16*1024*1024;
if (!device_block_size) if (!device_block_size)
device_block_size = 4096; device_block_size = 4096;
if (!data_csum_type) if (!data_csum_type)
@@ -75,9 +75,9 @@ void disk_tool_simple_offsets(json11::Json cfg, bool json_output)
if (st.st_blksize < device_block_size) if (st.st_blksize < device_block_size)
{ {
fprintf( fprintf(
stderr, "Warning: %s reports %ju byte blocks, but we use %ju." stderr, "Warning: %s reports %lu byte blocks, but we use %lu."
" Set --device_block_size=%ju if you're sure it works well with %ju byte blocks.\n", " Set --device_block_size=%lu if you're sure it works well with %lu byte blocks.\n",
device.c_str(), (uint64_t)st.st_blksize, device_block_size, (uint64_t)st.st_blksize, (uint64_t)st.st_blksize device.c_str(), st.st_blksize, device_block_size, st.st_blksize, st.st_blksize
); );
} }
} }
@@ -99,19 +99,19 @@ void disk_tool_simple_offsets(json11::Json cfg, bool json_output)
if (device_block_size < 512 || device_block_size > 1048576 || if (device_block_size < 512 || device_block_size > 1048576 ||
device_block_size & (device_block_size-1) != 0) device_block_size & (device_block_size-1) != 0)
{ {
fprintf(stderr, "Invalid device block size specified: %ju\n", device_block_size); fprintf(stderr, "Invalid device block size specified: %lu\n", device_block_size);
exit(1); exit(1);
} }
if (data_block_size < device_block_size || data_block_size > MAX_DATA_BLOCK_SIZE || if (data_block_size < device_block_size || data_block_size > MAX_DATA_BLOCK_SIZE ||
data_block_size & (data_block_size-1) != 0) data_block_size & (data_block_size-1) != 0)
{ {
fprintf(stderr, "Invalid object size specified: %ju\n", data_block_size); fprintf(stderr, "Invalid object size specified: %lu\n", data_block_size);
exit(1); exit(1);
} }
if (bitmap_granularity < device_block_size || bitmap_granularity > data_block_size || if (bitmap_granularity < device_block_size || bitmap_granularity > data_block_size ||
bitmap_granularity & (bitmap_granularity-1) != 0) bitmap_granularity & (bitmap_granularity-1) != 0)
{ {
fprintf(stderr, "Invalid bitmap granularity specified: %ju\n", bitmap_granularity); fprintf(stderr, "Invalid bitmap granularity specified: %lu\n", bitmap_granularity);
exit(1); exit(1);
} }
if (csum_block_size && (data_block_size % csum_block_size)) if (csum_block_size && (data_block_size % csum_block_size))
@@ -145,8 +145,8 @@ void disk_tool_simple_offsets(json11::Json cfg, bool json_output)
{ {
// Env // Env
printf( printf(
"meta_block_size=%ju\njournal_block_size=%ju\ndata_size=%ju\n" "meta_block_size=%lu\njournal_block_size=%lu\ndata_size=%lu\n"
"data_device=%s\njournal_offset=%ju\nmeta_offset=%ju\ndata_offset=%ju\n", "data_device=%s\njournal_offset=%lu\nmeta_offset=%lu\ndata_offset=%lu\n",
device_block_size, device_block_size, device_size-data_offset, device_block_size, device_block_size, device_size-data_offset,
device.c_str(), journal_offset, meta_offset, data_offset device.c_str(), journal_offset, meta_offset, data_offset
); );
@@ -160,14 +160,14 @@ void disk_tool_simple_offsets(json11::Json cfg, bool json_output)
} }
if (device_block_size != 4096) if (device_block_size != 4096)
{ {
printf("--meta_block_size %ju\n--journal_block_size %ju\n", device_block_size, device_block_size); printf("--meta_block_size %lu\n--journal_block_size %lu\n", device_block_size, device_block_size);
} }
if (orig_device_size) if (orig_device_size)
{ {
printf("--data_size %ju\n", device_size-data_offset); printf("--data_size %lu\n", device_size-data_offset);
} }
printf( printf(
"--data_device %s\n--journal_offset %ju\n--meta_offset %ju\n--data_offset %ju\n", "--data_device %s\n--journal_offset %lu\n--meta_offset %lu\n--data_offset %lu\n",
device.c_str(), journal_offset, meta_offset, data_offset device.c_str(), journal_offset, meta_offset, data_offset
); );
} }
+1 -1
View File
@@ -167,7 +167,7 @@ static const char *help_text =
" Calculate offsets for old simple&stupid (no superblock) OSD deployment. Options:\n" " Calculate offsets for old simple&stupid (no superblock) OSD deployment. Options:\n"
" --object_size 128k Set blockstore block size\n" " --object_size 128k Set blockstore block size\n"
" --bitmap_granularity 4k Set bitmap granularity\n" " --bitmap_granularity 4k Set bitmap granularity\n"
" --journal_size 32M Set journal size\n" " --journal_size 16M Set journal size\n"
" --data_csum_type none Set data checksum type (crc32c or none)\n" " --data_csum_type none Set data checksum type (crc32c or none)\n"
" --csum_block_size 4k Set data checksum block size\n" " --csum_block_size 4k Set data checksum block size\n"
" --device_block_size 4k Set device block size\n" " --device_block_size 4k Set device block size\n"
+1 -1
View File
@@ -4,7 +4,7 @@
#pragma once #pragma once
#ifndef _LARGEFILE64_SOURCE #ifndef _LARGEFILE64_SOURCE
#define _LARGEFILE64_SOURCE #define _LARGEFILE64_SOURCE 1
#endif #endif
#include <map> #include <map>
+22 -22
View File
@@ -38,7 +38,7 @@ int disk_tool_t::dump_journal()
} }
if (json) if (json)
{ {
printf("%s{\"offset\":\"0x%jx\"", first_block ? "" : ",\n", journal_pos); printf("%s{\"offset\":\"0x%lx\"", first_block ? "" : ",\n", journal_pos);
first_block = false; first_block = false;
} }
if (s == dsk.journal_block_size) if (s == dsk.journal_block_size)
@@ -46,13 +46,13 @@ int disk_tool_t::dump_journal()
if (json) if (json)
printf(",\"type\":\"zero\"}"); printf(",\"type\":\"zero\"}");
else else
printf("offset %08jx: zeroes\n", journal_pos); printf("offset %08lx: zeroes\n", journal_pos);
journal_pos += dsk.journal_block_size; journal_pos += dsk.journal_block_size;
} }
else if (((journal_entry*)journal_buf)->magic == JOURNAL_MAGIC) else if (((journal_entry*)journal_buf)->magic == JOURNAL_MAGIC)
{ {
if (!json) if (!json)
printf("offset %08jx:\n", journal_pos); printf("offset %08lx:\n", journal_pos);
else else
printf(",\"entries\":[\n"); printf(",\"entries\":[\n");
if (journal_pos == 0) if (journal_pos == 0)
@@ -80,9 +80,9 @@ int disk_tool_t::dump_journal()
else else
{ {
if (json) if (json)
printf(",\"type\":\"data\",\"pattern\":\"%08jx\"}", *((uint64_t*)journal_buf)); printf(",\"type\":\"data\",\"pattern\":\"%08lx\"}", *((uint64_t*)journal_buf));
else else
printf("offset %08jx: no magic in the beginning, looks like random data (pattern=%08jx)\n", journal_pos, *((uint64_t*)journal_buf)); printf("offset %08lx: no magic in the beginning, looks like random data (pattern=%08lx)\n", journal_pos, *((uint64_t*)journal_buf));
journal_pos += dsk.journal_block_size; journal_pos += dsk.journal_block_size;
} }
} }
@@ -98,12 +98,12 @@ int disk_tool_t::dump_journal()
if (json && dump_with_blocks) if (json && dump_with_blocks)
first_entry = true; first_entry = true;
if (!json) if (!json)
printf("offset %08jx:\n", journal_pos); printf("offset %08lx:\n", journal_pos);
auto pos = journal_pos; auto pos = journal_pos;
int r = process_journal_block(data, [this, pos](int num, journal_entry *je) int r = process_journal_block(data, [this, pos](int num, journal_entry *je)
{ {
if (json && dump_with_blocks && first_entry) if (json && dump_with_blocks && first_entry)
printf("%s{\"offset\":\"0x%jx\",\"entries\":[\n", first_block ? "" : ",\n", pos); printf("%s{\"offset\":\"0x%lx\",\"entries\":[\n", first_block ? "" : ",\n", pos);
dump_journal_entry(num, je, json); dump_journal_entry(num, je, json);
first_block = false; first_block = false;
}); });
@@ -134,12 +134,12 @@ int disk_tool_t::process_journal(std::function<int(void*)> block_fn)
journal_entry *je = (journal_entry*)(data); journal_entry *je = (journal_entry*)(data);
if (je->magic != JOURNAL_MAGIC || je->type != JE_START || je_crc32(je) != je->crc32) if (je->magic != JOURNAL_MAGIC || je->type != JE_START || je_crc32(je) != je->crc32)
{ {
fprintf(stderr, "offset %08jx: journal superblock is invalid\n", journal_pos); fprintf(stderr, "offset %08lx: journal superblock is invalid\n", journal_pos);
r = 1; r = 1;
} }
else if (je->start.size != JE_START_V0_SIZE && je->start.version != JOURNAL_VERSION_V1 && je->start.version != JOURNAL_VERSION_V2) else if (je->start.size != JE_START_V0_SIZE && je->start.version != JOURNAL_VERSION_V1 && je->start.version != JOURNAL_VERSION_V2)
{ {
fprintf(stderr, "offset %08jx: journal superblock contains version %ju, but I only understand 0, 1 and 2\n", fprintf(stderr, "offset %08lx: journal superblock contains version %lu, but I only understand 0, 1 and 2\n",
journal_pos, je->start.size == JE_START_V0_SIZE ? 0 : je->start.version); journal_pos, je->start.size == JE_START_V0_SIZE ? 0 : je->start.version);
r = 1; r = 1;
} }
@@ -296,7 +296,7 @@ void disk_tool_t::dump_journal_entry(int num, journal_entry *je, bool json)
if (je->type == JE_START) if (je->type == JE_START)
{ {
printf( printf(
json ? ",\"type\":\"start\",\"start\":\"0x%jx\"" : "je_start start=%08jx", json ? ",\"type\":\"start\",\"start\":\"0x%lx\"" : "je_start start=%08lx",
je->start.journal_start je->start.journal_start
); );
if (je->start.data_csum_type) if (je->start.data_csum_type)
@@ -312,15 +312,15 @@ void disk_tool_t::dump_journal_entry(int num, journal_entry *je, bool json)
{ {
auto & sw = je->small_write; auto & sw = je->small_write;
printf( printf(
json ? ",\"type\":\"small_write%s\",\"inode\":\"0x%jx\",\"stripe\":\"0x%jx\",\"ver\":\"%ju\",\"offset\":%u,\"len\":%u,\"loc\":\"0x%jx\"" json ? ",\"type\":\"small_write%s\",\"inode\":\"0x%lx\",\"stripe\":\"0x%lx\",\"ver\":\"%lu\",\"offset\":%u,\"len\":%u,\"loc\":\"0x%lx\""
: "je_small_write%s oid=%jx:%jx ver=%ju offset=%u len=%u loc=%08jx", : "je_small_write%s oid=%lx:%lx ver=%lu offset=%u len=%u loc=%08lx",
je->type == JE_SMALL_WRITE_INSTANT ? "_instant" : "", je->type == JE_SMALL_WRITE_INSTANT ? "_instant" : "",
sw.oid.inode, sw.oid.stripe, sw.version, sw.offset, sw.len, sw.data_offset sw.oid.inode, sw.oid.stripe, sw.version, sw.offset, sw.len, sw.data_offset
); );
if (journal_calc_data_pos != sw.data_offset) if (journal_calc_data_pos != sw.data_offset)
{ {
printf(json ? ",\"bad_loc\":true,\"calc_loc\":\"0x%jx\"" printf(json ? ",\"bad_loc\":true,\"calc_loc\":\"0x%lx\""
: " (mismatched, calculated = %08jx)", journal_pos); : " (mismatched, calculated = %08lx)", journal_pos);
} }
uint32_t data_csum_size = (!je_start.csum_block_size uint32_t data_csum_size = (!je_start.csum_block_size
? 0 ? 0
@@ -367,8 +367,8 @@ void disk_tool_t::dump_journal_entry(int num, journal_entry *je, bool json)
{ {
auto & bw = je->big_write; auto & bw = je->big_write;
printf( printf(
json ? ",\"type\":\"big_write%s\",\"inode\":\"0x%jx\",\"stripe\":\"0x%jx\",\"ver\":\"%ju\",\"offset\":%u,\"len\":%u,\"loc\":\"0x%jx\"" json ? ",\"type\":\"big_write%s\",\"inode\":\"0x%lx\",\"stripe\":\"0x%lx\",\"ver\":\"%lu\",\"offset\":%u,\"len\":%u,\"loc\":\"0x%lx\""
: "je_big_write%s oid=%jx:%jx ver=%ju offset=%u len=%u loc=%08jx", : "je_big_write%s oid=%lx:%lx ver=%lu offset=%u len=%u loc=%08lx",
je->type == JE_BIG_WRITE_INSTANT ? "_instant" : "", je->type == JE_BIG_WRITE_INSTANT ? "_instant" : "",
bw.oid.inode, bw.oid.stripe, bw.version, bw.offset, bw.len, bw.location bw.oid.inode, bw.oid.stripe, bw.version, bw.offset, bw.len, bw.location
); );
@@ -398,24 +398,24 @@ void disk_tool_t::dump_journal_entry(int num, journal_entry *je, bool json)
else if (je->type == JE_STABLE) else if (je->type == JE_STABLE)
{ {
printf( printf(
json ? ",\"type\":\"stable\",\"inode\":\"0x%jx\",\"stripe\":\"0x%jx\",\"ver\":\"%ju\"}" json ? ",\"type\":\"stable\",\"inode\":\"0x%lx\",\"stripe\":\"0x%lx\",\"ver\":\"%lu\"}"
: "je_stable oid=%jx:%jx ver=%ju\n", : "je_stable oid=%lx:%lx ver=%lu\n",
je->stable.oid.inode, je->stable.oid.stripe, je->stable.version je->stable.oid.inode, je->stable.oid.stripe, je->stable.version
); );
} }
else if (je->type == JE_ROLLBACK) else if (je->type == JE_ROLLBACK)
{ {
printf( printf(
json ? ",\"type\":\"rollback\",\"inode\":\"0x%jx\",\"stripe\":\"0x%jx\",\"ver\":\"%ju\"}" json ? ",\"type\":\"rollback\",\"inode\":\"0x%lx\",\"stripe\":\"0x%lx\",\"ver\":\"%lu\"}"
: "je_rollback oid=%jx:%jx ver=%ju\n", : "je_rollback oid=%lx:%lx ver=%lu\n",
je->rollback.oid.inode, je->rollback.oid.stripe, je->rollback.version je->rollback.oid.inode, je->rollback.oid.stripe, je->rollback.version
); );
} }
else if (je->type == JE_DELETE) else if (je->type == JE_DELETE)
{ {
printf( printf(
json ? ",\"type\":\"delete\",\"inode\":\"0x%jx\",\"stripe\":\"0x%jx\",\"ver\":\"%ju\"}" json ? ",\"type\":\"delete\",\"inode\":\"0x%lx\",\"stripe\":\"0x%lx\",\"ver\":\"%lu\"}"
: "je_delete oid=%jx:%jx ver=%ju\n", : "je_delete oid=%lx:%lx ver=%lu\n",
je->del.oid.inode, je->del.oid.stripe, je->del.version je->del.oid.inode, je->del.oid.stripe, je->del.version
); );
} }
+5 -5
View File
@@ -54,7 +54,7 @@ int disk_tool_t::process_meta(std::function<void(blockstore_meta_header_v2_t *)>
else else
{ {
// Unsupported version // Unsupported version
fprintf(stderr, "Metadata format is too new for me (stored version is %ju, max supported %u).\n", hdr->version, BLOCKSTORE_META_FORMAT_V2); fprintf(stderr, "Metadata format is too new for me (stored version is %lu, max supported %u).\n", hdr->version, BLOCKSTORE_META_FORMAT_V2);
free(data); free(data);
close(dsk.meta_fd); close(dsk.meta_fd);
dsk.meta_fd = -1; dsk.meta_fd = -1;
@@ -108,7 +108,7 @@ int disk_tool_t::process_meta(std::function<void(blockstore_meta_header_v2_t *)>
uint32_t *entry_csum = (uint32_t*)((uint8_t*)entry + dsk.clean_entry_size - 4); uint32_t *entry_csum = (uint32_t*)((uint8_t*)entry + dsk.clean_entry_size - 4);
if (*entry_csum != crc32c(0, entry, dsk.clean_entry_size - 4)) if (*entry_csum != crc32c(0, entry, dsk.clean_entry_size - 4))
{ {
fprintf(stderr, "Metadata entry %ju is corrupt (checksum mismatch), skipping\n", block_num); fprintf(stderr, "Metadata entry %lu is corrupt (checksum mismatch), skipping\n", block_num);
continue; continue;
} }
} }
@@ -184,7 +184,7 @@ void disk_tool_t::dump_meta_header(blockstore_meta_header_v2_t *hdr)
} }
else else
{ {
printf("{\"version\":\"0.5\",\"meta_block_size\":%ju,\"entries\":[\n", dsk.meta_block_size); printf("{\"version\":\"0.5\",\"meta_block_size\":%lu,\"entries\":[\n", dsk.meta_block_size);
} }
first_entry = true; first_entry = true;
} }
@@ -192,7 +192,7 @@ void disk_tool_t::dump_meta_header(blockstore_meta_header_v2_t *hdr)
void disk_tool_t::dump_meta_entry(uint64_t block_num, clean_disk_entry *entry, uint8_t *bitmap) void disk_tool_t::dump_meta_entry(uint64_t block_num, clean_disk_entry *entry, uint8_t *bitmap)
{ {
printf( printf(
#define ENTRY_FMT "{\"block\":%ju,\"pool\":%u,\"inode\":\"0x%jx\",\"stripe\":\"0x%jx\",\"version\":%ju" #define ENTRY_FMT "{\"block\":%lu,\"pool\":%u,\"inode\":\"0x%lx\",\"stripe\":\"0x%lx\",\"version\":%lu"
(first_entry ? ENTRY_FMT : (",\n" ENTRY_FMT)), (first_entry ? ENTRY_FMT : (",\n" ENTRY_FMT)),
#undef ENTRY_FMT #undef ENTRY_FMT
block_num, INODE_POOL(entry->oid.inode), INODE_NO_POOL(entry->oid.inode), block_num, INODE_POOL(entry->oid.inode), INODE_NO_POOL(entry->oid.inode),
@@ -265,7 +265,7 @@ int disk_tool_t::write_json_meta(json11::Json meta)
{ {
free(new_meta_buf); free(new_meta_buf);
new_meta_buf = NULL; new_meta_buf = NULL;
fprintf(stderr, "Metadata (data block %ju) doesn't fit into the new area\n", data_block); fprintf(stderr, "Metadata (data block %lu) doesn't fit into the new area\n", data_block);
return 1; return 1;
} }
clean_disk_entry *new_entry = (clean_disk_entry*)(new_meta_buf + clean_disk_entry *new_entry = (clean_disk_entry*)(new_meta_buf +
+11 -21
View File
@@ -8,7 +8,6 @@
int disk_tool_t::prepare_one(std::map<std::string, std::string> options, int is_hdd) int disk_tool_t::prepare_one(std::map<std::string, std::string> options, int is_hdd)
{ {
static const char *allow_additional_params[] = { static const char *allow_additional_params[] = {
"autosync_writes",
"data_io", "data_io",
"meta_io", "meta_io",
"journal_io", "journal_io",
@@ -100,9 +99,12 @@ int disk_tool_t::prepare_one(std::map<std::string, std::string> options, int is_
options["disable_journal_fsync"] = options["disable_data_fsync"]; options["disable_journal_fsync"] = options["disable_data_fsync"];
} }
// Calculate offsets if the same device is used for two or more of data, meta, and journal // Calculate offsets if the same device is used for two or more of data, meta, and journal
if (options["journal_size"] == "" && (options["journal_device"] == "" || options["journal_device"] == options["data_device"])) if (options["journal_size"] == "")
{ {
options["journal_size"] = is_hdd || !json_is_true(options["disable_data_fsync"]) ? "128M" : "32M"; if (options["journal_device"] == "")
options["journal_size"] = is_hdd ? "128M" : "32M";
else if (is_hdd)
options["journal_size"] = DEFAULT_HYBRID_JOURNAL;
} }
bool is_hybrid = is_hdd && options["journal_device"] != "" && options["journal_device"] != options["data_device"]; bool is_hybrid = is_hdd && options["journal_device"] != "" && options["journal_device"] != options["data_device"];
if (is_hdd) if (is_hdd)
@@ -112,15 +114,6 @@ int disk_tool_t::prepare_one(std::map<std::string, std::string> options, int is_
if (is_hybrid && options["throttle_small_writes"] == "") if (is_hybrid && options["throttle_small_writes"] == "")
options["throttle_small_writes"] = "1"; options["throttle_small_writes"] = "1";
} }
else if (!json_is_true(options["disable_data_fsync"]))
{
if (options.find("min_flusher_count") == options.end())
options["min_flusher_count"] = "32";
if (options.find("max_flusher_count") == options.end())
options["max_flusher_count"] = "256";
if (options.find("autosync_writes") == options.end())
options["autosync_writes"] = "512";
}
json11::Json::object sb; json11::Json::object sb;
blockstore_disk_t dsk; blockstore_disk_t dsk;
try try
@@ -210,10 +203,10 @@ int disk_tool_t::prepare_one(std::map<std::string, std::string> options, int is_
desc += " with metadata on "+realpath_str(options["meta_device"]); desc += " with metadata on "+realpath_str(options["meta_device"]);
if (sep_j) if (sep_j)
desc += (sep_m ? " and journal on " : " with journal on ") + realpath_str(options["journal_device"]); desc += (sep_m ? " and journal on " : " with journal on ") + realpath_str(options["journal_device"]);
fprintf(stderr, "Initialized OSD %ju on %s\n", osd_num, desc.c_str()); fprintf(stderr, "Initialized OSD %lu on %s\n", osd_num, desc.c_str());
if (shell_exec({ "systemctl", "enable", "--now", "vitastor-osd@"+std::to_string(osd_num) }, "", NULL, NULL) != 0) if (shell_exec({ "systemctl", "enable", "--now", "vitastor-osd@"+std::to_string(osd_num) }, "", NULL, NULL) != 0)
{ {
fprintf(stderr, "Failed to enable systemd unit vitastor-osd@%ju\n", osd_num); fprintf(stderr, "Failed to enable systemd unit vitastor-osd@%lu\n", osd_num);
return 1; return 1;
} }
return 0; return 0;
@@ -337,7 +330,7 @@ json11::Json disk_tool_t::add_partitions(vitastor_dev_info_t & devinfo, std::vec
std::string out; std::string out;
if (shell_exec({ "sfdisk", "--no-reread", "--force", devinfo.path }, script, &out, NULL) != 0) if (shell_exec({ "sfdisk", "--no-reread", "--force", devinfo.path }, script, &out, NULL) != 0)
{ {
fprintf(stderr, "Failed to add %zu partition(s) with sfdisk\n", sizes.size()); fprintf(stderr, "Failed to add %lu partition(s) with sfdisk\n", sizes.size());
return {}; return {};
} }
// Get new partition table and find created partitions // Get new partition table and find created partitions
@@ -352,7 +345,7 @@ json11::Json disk_tool_t::add_partitions(vitastor_dev_info_t & devinfo, std::vec
} }
if (new_parts.size() != sizes.size()) if (new_parts.size() != sizes.size())
{ {
fprintf(stderr, "Failed to add %zu partition(s) with sfdisk: new partitions not found in table\n", sizes.size()); fprintf(stderr, "Failed to add %lu partition(s) with sfdisk: new partitions not found in table\n", sizes.size());
return {}; return {};
} }
// Check if new nodes exist and run partprobe if not // Check if new nodes exist and run partprobe if not
@@ -456,7 +449,7 @@ std::vector<std::string> disk_tool_t::get_new_data_parts(vitastor_dev_info_t & d
bool is_journal = sb["params"]["journal_device"].string_value() == part_path; bool is_journal = sb["params"]["journal_device"].string_value() == part_path;
bool is_data = sb["params"]["data_device"].string_value() == part_path; bool is_data = sb["params"]["data_device"].string_value() == part_path;
fprintf( fprintf(
stderr, "%s is already initialized for OSD %ju%s, skipping\n", stderr, "%s is already initialized for OSD %lu%s, skipping\n",
part["node"].string_value().c_str(), sb["params"]["osd_num"].uint64_value(), part["node"].string_value().c_str(), sb["params"]["osd_num"].uint64_value(),
(is_data ? " data" : (is_meta ? " meta" : (is_journal ? " journal" : ""))) (is_data ? " data" : (is_meta ? " meta" : (is_journal ? " journal" : "")))
); );
@@ -539,7 +532,7 @@ int disk_tool_t::get_meta_partition(std::vector<vitastor_dev_info_t> & ssds, std
if (sel < 0) if (sel < 0)
{ {
fprintf( fprintf(
stderr, "Could not find free space for new SSD journal and metadata (need %ju + %ju MiB)\n", stderr, "Could not find free space for new SSD journal and metadata (need %lu + %lu MiB)\n",
meta_size/1024/1024, journal_size/1024/1024 meta_size/1024/1024, journal_size/1024/1024
); );
return 1; return 1;
@@ -623,7 +616,6 @@ int disk_tool_t::prepare(std::vector<std::string> devices)
options.erase("disable_meta_fsync"); options.erase("disable_meta_fsync");
options.erase("disable_journal_fsync"); options.erase("disable_journal_fsync");
} }
auto journal_size = options["journal_size"];
for (auto & dev: devinfo) for (auto & dev: devinfo)
{ {
if (!hybrid || dev.is_hdd) if (!hybrid || dev.is_hdd)
@@ -641,13 +633,11 @@ int disk_tool_t::prepare(std::vector<std::string> devices)
{ {
return 1; return 1;
} }
options.erase("journal_size");
} }
// Treat all disks as SSDs if not in the hybrid mode // Treat all disks as SSDs if not in the hybrid mode
prepare_one(options, dev.is_hdd ? 1 : 0); prepare_one(options, dev.is_hdd ? 1 : 0);
if (hybrid) if (hybrid)
{ {
options["journal_size"] = journal_size;
options.erase("journal_device"); options.erase("journal_device");
options.erase("meta_device"); options.erase("meta_device");
} }
+3 -3
View File
@@ -184,7 +184,7 @@ void disk_tool_t::resize_init(blockstore_meta_header_v2_t *hdr)
} }
if (new_meta_len < dsk.meta_block_size*new_meta_blocks) if (new_meta_len < dsk.meta_block_size*new_meta_blocks)
{ {
fprintf(stderr, "New metadata area size is too small, should be at least %ju bytes\n", dsk.meta_block_size*new_meta_blocks); fprintf(stderr, "New metadata area size is too small, should be at least %lu bytes\n", dsk.meta_block_size*new_meta_blocks);
exit(1); exit(1);
} }
// Check that new metadata, journal and data areas don't overlap // Check that new metadata, journal and data areas don't overlap
@@ -289,7 +289,7 @@ int disk_tool_t::resize_copy_data()
if (data->res != dsk.data_block_size) if (data->res != dsk.data_block_size)
{ {
fprintf( fprintf(
stderr, "Failed to read %u bytes at %ju from %s: %s\n", dsk.data_block_size, stderr, "Failed to read %u bytes at %lu from %s: %s\n", dsk.data_block_size,
dsk.data_offset + moving_blocks[i].old_loc*dsk.data_block_size, dsk.data_device.c_str(), dsk.data_offset + moving_blocks[i].old_loc*dsk.data_block_size, dsk.data_device.c_str(),
data->res < 0 ? strerror(-data->res) : "short read" data->res < 0 ? strerror(-data->res) : "short read"
); );
@@ -314,7 +314,7 @@ int disk_tool_t::resize_copy_data()
if (data->res != dsk.data_block_size) if (data->res != dsk.data_block_size)
{ {
fprintf( fprintf(
stderr, "Failed to write %u bytes at %ju to %s: %s\n", dsk.data_block_size, stderr, "Failed to write %u bytes at %lu to %s: %s\n", dsk.data_block_size,
dsk.data_offset + moving_blocks[i].new_loc*dsk.data_block_size, dsk.data_device.c_str(), dsk.data_offset + moving_blocks[i].new_loc*dsk.data_block_size, dsk.data_device.c_str(),
data->res < 0 ? strerror(-data->res) : "short write" data->res < 0 ? strerror(-data->res) : "short write"
); );
+4 -4
View File
@@ -43,8 +43,8 @@ int disk_tool_t::udev_import(std::string device)
} }
uint64_t osd_num = sb["params"]["osd_num"].uint64_value(); uint64_t osd_num = sb["params"]["osd_num"].uint64_value();
// Print variables for udev // Print variables for udev
printf("VITASTOR_OSD_NUM=%ju\n", osd_num); printf("VITASTOR_OSD_NUM=%lu\n", osd_num);
printf("VITASTOR_ALIAS=osd%ju-%s\n", osd_num, sb["device_type"].string_value().c_str()); printf("VITASTOR_ALIAS=osd%lu-%s\n", osd_num, sb["device_type"].string_value().c_str());
printf("VITASTOR_DATA_DEVICE=%s\n", udev_escape(sb["params"]["data_device"].string_value()).c_str()); printf("VITASTOR_DATA_DEVICE=%s\n", udev_escape(sb["params"]["data_device"].string_value()).c_str());
if (sb["real_meta_device"].string_value() != "" && sb["real_meta_device"] != sb["real_data_device"]) if (sb["real_meta_device"].string_value() != "" && sb["real_meta_device"] != sb["real_data_device"])
printf("VITASTOR_META_DEVICE=%s\n", udev_escape(sb["params"]["meta_device"].string_value()).c_str()); printf("VITASTOR_META_DEVICE=%s\n", udev_escape(sb["params"]["meta_device"].string_value()).c_str());
@@ -466,12 +466,12 @@ int disk_tool_t::purge_devices(const std::vector<std::string> & devices)
close(fd); close(fd);
if (r != 0) if (r != 0)
{ {
fprintf(stderr, "Failed to clear OSD %ju %s device %s superblock: %s\n", fprintf(stderr, "Failed to clear OSD %lu %s device %s superblock: %s\n",
sb["params"]["osd_num"].uint64_value(), dev_type.c_str(), dev.c_str(), strerror(errno)); sb["params"]["osd_num"].uint64_value(), dev_type.c_str(), dev.c_str(), strerror(errno));
} }
else else
{ {
fprintf(stderr, "OSD %ju %s device %s superblock cleared\n", fprintf(stderr, "OSD %lu %s device %s superblock cleared\n",
sb["params"]["osd_num"].uint64_value(), dev_type.c_str(), dev.c_str()); sb["params"]["osd_num"].uint64_value(), dev_type.c_str(), dev.c_str());
} }
if (sb["params"][dev_type+"_device"].string_value().substr(0, 22) == "/dev/disk/by-partuuid/") if (sb["params"][dev_type+"_device"].string_value().substr(0, 22) == "/dev/disk/by-partuuid/")
+2 -2
View File
@@ -12,9 +12,9 @@ uint64_t sscanf_json(const char *fmt, const json11::Json & str)
{ {
uint64_t value = 0; uint64_t value = 0;
if (fmt) if (fmt)
sscanf(str.string_value().c_str(), "%jx", &value); sscanf(str.string_value().c_str(), "%lx", &value);
else if (str.string_value().size() > 2 && (str.string_value()[0] == '0' && str.string_value()[1] == 'x')) else if (str.string_value().size() > 2 && (str.string_value()[0] == '0' && str.string_value()[1] == 'x'))
sscanf(str.string_value().c_str(), "0x%jx", &value); sscanf(str.string_value().c_str(), "0x%lx", &value);
else else
value = str.uint64_value(); value = str.uint64_value();
return value; return value;
+12 -12
View File
@@ -333,7 +333,7 @@ void etcd_state_client_t::start_etcd_watcher()
etcd_watch_ws = NULL; etcd_watch_ws = NULL;
} }
if (this->log_level > 1) if (this->log_level > 1)
fprintf(stderr, "Trying to connect to etcd websocket at %s, watch from revision %ju\n", etcd_address.c_str(), etcd_watch_revision); fprintf(stderr, "Trying to connect to etcd websocket at %s, watch from revision %lu\n", etcd_address.c_str(), etcd_watch_revision);
etcd_watch_ws = open_websocket(tfd, etcd_address, etcd_api_path+"/watch", etcd_slow_timeout, etcd_watch_ws = open_websocket(tfd, etcd_address, etcd_api_path+"/watch", etcd_slow_timeout,
[this, cur_addr = selected_etcd_address](const http_response_t *msg) [this, cur_addr = selected_etcd_address](const http_response_t *msg)
{ {
@@ -357,7 +357,7 @@ void etcd_state_client_t::start_etcd_watcher()
watch_id == ETCD_OSD_STATE_WATCH_ID) watch_id == ETCD_OSD_STATE_WATCH_ID)
etcd_watches_initialised++; etcd_watches_initialised++;
if (etcd_watches_initialised == ETCD_TOTAL_WATCHES && this->log_level > 0) if (etcd_watches_initialised == ETCD_TOTAL_WATCHES && this->log_level > 0)
fprintf(stderr, "Successfully subscribed to etcd at %s, revision %ju\n", cur_addr.c_str(), etcd_watch_revision); fprintf(stderr, "Successfully subscribed to etcd at %s, revision %lu\n", cur_addr.c_str(), etcd_watch_revision);
} }
if (data["result"]["canceled"].bool_value()) if (data["result"]["canceled"].bool_value())
{ {
@@ -371,7 +371,7 @@ void etcd_state_client_t::start_etcd_watcher()
// check to not trigger on_reload_hook multiple times // check to not trigger on_reload_hook multiple times
if (etcd_watch_ws != NULL) if (etcd_watch_ws != NULL)
{ {
fprintf(stderr, "Revisions before %ju were compacted by etcd, reloading state\n", fprintf(stderr, "Revisions before %lu were compacted by etcd, reloading state\n",
data["result"]["compact_revision"].uint64_value()); data["result"]["compact_revision"].uint64_value());
http_close(etcd_watch_ws); http_close(etcd_watch_ws);
etcd_watch_ws = NULL; etcd_watch_ws = NULL;
@@ -382,7 +382,7 @@ void etcd_state_client_t::start_etcd_watcher()
} }
else else
{ {
fprintf(stderr, "Revisions before %ju were compacted by etcd, exiting\n", fprintf(stderr, "Revisions before %lu were compacted by etcd, exiting\n",
data["result"]["compact_revision"].uint64_value()); data["result"]["compact_revision"].uint64_value());
exit(1); exit(1);
} }
@@ -646,7 +646,7 @@ void etcd_state_client_t::load_pgs()
etcd_watch_revision = data["header"]["revision"].uint64_value()+1; etcd_watch_revision = data["header"]["revision"].uint64_value()+1;
if (this->log_level > 3) if (this->log_level > 3)
{ {
fprintf(stderr, "Loaded revision %ju of PG configuration\n", etcd_watch_revision-1); fprintf(stderr, "Loaded revision %lu of PG configuration\n", etcd_watch_revision-1);
} }
} }
for (auto & res: data["responses"].array_items()) for (auto & res: data["responses"].array_items())
@@ -740,7 +740,7 @@ void etcd_state_client_t::clean_nonexistent_pgs()
{ {
if (seen_peers.find(peer_item.first) == seen_peers.end()) if (seen_peers.find(peer_item.first) == seen_peers.end())
{ {
fprintf(stderr, "OSD %ju state disappeared after reload, forgetting it\n", peer_item.first); fprintf(stderr, "OSD %lu state disappeared after reload, forgetting it\n", peer_item.first);
parse_state((etcd_kv_t){ parse_state((etcd_kv_t){
.key = etcd_prefix+"/osd/state/"+std::to_string(peer_item.first), .key = etcd_prefix+"/osd/state/"+std::to_string(peer_item.first),
}); });
@@ -890,7 +890,7 @@ void etcd_state_client_t::parse_state(const etcd_kv_t & kv)
{ {
if (pg_item.second.target_set.size() != parsed_cfg.pg_size) if (pg_item.second.target_set.size() != parsed_cfg.pg_size)
{ {
fprintf(stderr, "Pool %u PG %u configuration is invalid: osd_set size %zu != pool pg_size %ju\n", fprintf(stderr, "Pool %u PG %u configuration is invalid: osd_set size %lu != pool pg_size %lu\n",
pool_id, pg_item.first, pg_item.second.target_set.size(), parsed_cfg.pg_size); pool_id, pg_item.first, pg_item.second.target_set.size(), parsed_cfg.pg_size);
pg_item.second.pause = true; pg_item.second.pause = true;
} }
@@ -936,7 +936,7 @@ void etcd_state_client_t::parse_state(const etcd_kv_t & kv)
} }
if (parsed_cfg.target_set.size() != pool_config[pool_id].pg_size) if (parsed_cfg.target_set.size() != pool_config[pool_id].pg_size)
{ {
fprintf(stderr, "Pool %u PG %u configuration is invalid: osd_set size %zu != pool pg_size %ju\n", fprintf(stderr, "Pool %u PG %u configuration is invalid: osd_set size %lu != pool pg_size %lu\n",
pool_id, pg_num, parsed_cfg.target_set.size(), pool_config[pool_id].pg_size); pool_id, pg_num, parsed_cfg.target_set.size(), pool_config[pool_id].pg_size);
parsed_cfg.pause = true; parsed_cfg.pause = true;
} }
@@ -950,7 +950,7 @@ void etcd_state_client_t::parse_state(const etcd_kv_t & kv)
if (pg_it->second.config_exists && pg_it->first != ++n) if (pg_it->second.config_exists && pg_it->first != ++n)
{ {
fprintf( fprintf(
stderr, "Invalid pool %u PG configuration: PG numbers don't cover whole 1..%zu range\n", stderr, "Invalid pool %u PG configuration: PG numbers don't cover whole 1..%lu range\n",
pool_item.second.id, pool_item.second.pg_config.size() pool_item.second.id, pool_item.second.pg_config.size()
); );
for (pg_it = pool_item.second.pg_config.begin(); pg_it != pool_item.second.pg_config.end(); pg_it++) for (pg_it = pool_item.second.pg_config.begin(); pg_it != pool_item.second.pg_config.end(); pg_it++)
@@ -1066,7 +1066,7 @@ void etcd_state_client_t::parse_state(const etcd_kv_t & kv)
(state & PG_PEERING) && state != PG_PEERING || (state & PG_PEERING) && state != PG_PEERING ||
(state & PG_INCOMPLETE) && state != PG_INCOMPLETE) (state & PG_INCOMPLETE) && state != PG_INCOMPLETE)
{ {
fprintf(stderr, "Unexpected pool %u PG %u state in etcd: primary=%ju, state=%s\n", pool_id, pg_num, cur_primary, value["state"].dump().c_str()); fprintf(stderr, "Unexpected pool %u PG %u state in etcd: primary=%lu, state=%s\n", pool_id, pg_num, cur_primary, value["state"].dump().c_str());
return; return;
} }
pg_cfg.cur_primary = cur_primary; pg_cfg.cur_primary = cur_primary;
@@ -1102,7 +1102,7 @@ void etcd_state_client_t::parse_state(const etcd_kv_t & kv)
uint64_t pool_id = 0; uint64_t pool_id = 0;
uint64_t inode_num = 0; uint64_t inode_num = 0;
char null_byte = 0; char null_byte = 0;
int scanned = sscanf(key.c_str() + etcd_prefix.length()+14, "%ju/%ju%c", &pool_id, &inode_num, &null_byte); int scanned = sscanf(key.c_str() + etcd_prefix.length()+14, "%lu/%lu%c", &pool_id, &inode_num, &null_byte);
if (scanned != 2 || !pool_id || pool_id >= POOL_ID_MAX || !inode_num || (inode_num >> (64-POOL_ID_BITS))) if (scanned != 2 || !pool_id || pool_id >= POOL_ID_MAX || !inode_num || (inode_num >> (64-POOL_ID_BITS)))
{ {
fprintf(stderr, "Bad etcd key %s, ignoring\n", key.c_str()); fprintf(stderr, "Bad etcd key %s, ignoring\n", key.c_str());
@@ -1145,7 +1145,7 @@ void etcd_state_client_t::parse_state(const etcd_kv_t & kv)
else if (parent_pool_id >= POOL_ID_MAX) else if (parent_pool_id >= POOL_ID_MAX)
{ {
fprintf( fprintf(
stderr, "Inode %ju/%ju parent_pool value is invalid, ignoring parent setting\n", stderr, "Inode %lu/%lu parent_pool value is invalid, ignoring parent setting\n",
inode_num >> (64-POOL_ID_BITS), inode_num & (((uint64_t)1 << (64-POOL_ID_BITS)) - 1) inode_num >> (64-POOL_ID_BITS), inode_num & (((uint64_t)1 << (64-POOL_ID_BITS)) - 1)
); );
parent_inode_num = 0; parent_inode_num = 0;
+1 -1
View File
@@ -28,7 +28,7 @@ struct etcd_kv_t
{ {
std::string key; std::string key;
json11::Json value; json11::Json value;
uint64_t mod_revision = 0; uint64_t mod_revision;
}; };
struct pg_config_t struct pg_config_t
+5 -6
View File
@@ -377,7 +377,7 @@ static void io_callback(void *opaque, long retval)
bsd->completed.push_back(io); bsd->completed.push_back(io);
if (bsd->trace) if (bsd->trace)
{ {
printf("--- %s 0x%jx retval=%ld\n", io->ddir == DDIR_READ ? "READ" : printf("--- %s 0x%lx retval=%ld\n", io->ddir == DDIR_READ ? "READ" :
(io->ddir == DDIR_WRITE ? "WRITE" : "SYNC"), (uint64_t)io, retval); (io->ddir == DDIR_WRITE ? "WRITE" : "SYNC"), (uint64_t)io, retval);
} }
} }
@@ -405,11 +405,10 @@ static enum fio_q_status sec_queue(struct thread_data *td, struct io_u *io)
bsd->inflight++; bsd->inflight++;
uint64_t inode = opt->image ? vitastor_c_inode_get_num(bsd->watch) : opt->inode; uint64_t inode = opt->image ? vitastor_c_inode_get_num(bsd->watch) : opt->inode;
assert(io->xfer_buflen < (size_t)-1);
switch (io->ddir) switch (io->ddir)
{ {
case DDIR_READ: case DDIR_READ:
iov = { .iov_base = io->xfer_buf, .iov_len = (size_t)io->xfer_buflen }; iov = { .iov_base = io->xfer_buf, .iov_len = io->xfer_buflen };
vitastor_c_read(bsd->cli, inode, io->offset, io->xfer_buflen, &iov, 1, read_callback, io); vitastor_c_read(bsd->cli, inode, io->offset, io->xfer_buflen, &iov, 1, read_callback, io);
bsd->last_sync = false; bsd->last_sync = false;
break; break;
@@ -437,7 +436,7 @@ static enum fio_q_status sec_queue(struct thread_data *td, struct io_u *io)
io->error = EROFS; io->error = EROFS;
return FIO_Q_COMPLETED; return FIO_Q_COMPLETED;
} }
iov = { .iov_base = io->xfer_buf, .iov_len = (size_t)io->xfer_buflen }; iov = { .iov_base = io->xfer_buf, .iov_len = io->xfer_buflen };
vitastor_c_write(bsd->cli, inode, io->offset, io->xfer_buflen, 0, &iov, 1, io_callback, io); vitastor_c_write(bsd->cli, inode, io->offset, io->xfer_buflen, 0, &iov, 1, io_callback, io);
bsd->last_sync = false; bsd->last_sync = false;
break; break;
@@ -454,11 +453,11 @@ static enum fio_q_status sec_queue(struct thread_data *td, struct io_u *io)
{ {
if (io->ddir == DDIR_SYNC) if (io->ddir == DDIR_SYNC)
{ {
printf("+++ SYNC 0x%jx\n", (uint64_t)io); printf("+++ SYNC 0x%lx\n", (uint64_t)io);
} }
else else
{ {
printf("+++ %s 0x%jx 0x%llx+%jx\n", printf("+++ %s 0x%lx 0x%llx+%lx\n",
io->ddir == DDIR_READ ? "READ" : "WRITE", io->ddir == DDIR_READ ? "READ" : "WRITE",
(uint64_t)io, io->offset, (uint64_t)io->xfer_buflen); (uint64_t)io, io->offset, (uint64_t)io->xfer_buflen);
} }
+8 -10
View File
@@ -310,8 +310,7 @@ static enum fio_q_status sec_queue(struct thread_data *td, struct io_u *io)
int iovcnt = 1, wtotal = OSD_PACKET_SIZE; int iovcnt = 1, wtotal = OSD_PACKET_SIZE;
if (io->ddir == DDIR_WRITE) if (io->ddir == DDIR_WRITE)
{ {
assert(io->xfer_buflen <= 0x7fffffff); iov[iovcnt++] = { .iov_base = io->xfer_buf, .iov_len = io->xfer_buflen };
iov[iovcnt++] = { .iov_base = io->xfer_buf, .iov_len = (size_t)io->xfer_buflen };
wtotal += io->xfer_buflen; wtotal += io->xfer_buflen;
} }
if (sendv_blocking(bsd->connect_fd, iov, iovcnt, if (sendv_blocking(bsd->connect_fd, iov, iovcnt,
@@ -342,13 +341,13 @@ static int sec_getevents(struct thread_data *td, unsigned int min, unsigned int
read_blocking(bsd->connect_fd, reply.buf, OSD_PACKET_SIZE); read_blocking(bsd->connect_fd, reply.buf, OSD_PACKET_SIZE);
if (reply.hdr.magic != SECONDARY_OSD_REPLY_MAGIC) if (reply.hdr.magic != SECONDARY_OSD_REPLY_MAGIC)
{ {
fprintf(stderr, "bad reply: magic = %jx instead of %jx\n", reply.hdr.magic, SECONDARY_OSD_REPLY_MAGIC); fprintf(stderr, "bad reply: magic = %lx instead of %lx\n", reply.hdr.magic, SECONDARY_OSD_REPLY_MAGIC);
exit(1); exit(1);
} }
auto it = bsd->queue.find(reply.hdr.id); auto it = bsd->queue.find(reply.hdr.id);
if (it == bsd->queue.end()) if (it == bsd->queue.end())
{ {
fprintf(stderr, "bad reply: op id %jx missing in local queue\n", reply.hdr.id); fprintf(stderr, "bad reply: op id %lx missing in local queue\n", reply.hdr.id);
exit(1); exit(1);
} }
io_u* io = it->second->fio_op; io_u* io = it->second->fio_op;
@@ -358,7 +357,7 @@ static int sec_getevents(struct thread_data *td, unsigned int min, unsigned int
{ {
if (reply.hdr.retval != io->xfer_buflen) if (reply.hdr.retval != io->xfer_buflen)
{ {
fprintf(stderr, "Short read: retval = %jd instead of %ju\n", reply.hdr.retval, (uint64_t)io->xfer_buflen); fprintf(stderr, "Short read: retval = %ld instead of %lu\n", reply.hdr.retval, (uint64_t)io->xfer_buflen);
exit(1); exit(1);
} }
// Support bitmap // Support bitmap
@@ -372,8 +371,7 @@ static int sec_getevents(struct thread_data *td, unsigned int min, unsigned int
else else
iov[iovcnt++] = { .iov_base = (void*)(bitmap = (uint64_t)malloc(reply.sec_rw.attr_len)), .iov_len = reply.sec_rw.attr_len }; iov[iovcnt++] = { .iov_base = (void*)(bitmap = (uint64_t)malloc(reply.sec_rw.attr_len)), .iov_len = reply.sec_rw.attr_len };
} }
assert(io->xfer_buflen <= 0x7FFFFFFF); iov[iovcnt++] = { .iov_base = io->xfer_buf, .iov_len = io->xfer_buflen };
iov[iovcnt++] = { .iov_base = io->xfer_buf, .iov_len = (size_t)io->xfer_buflen };
readv_blocking(bsd->connect_fd, iov, iovcnt); readv_blocking(bsd->connect_fd, iov, iovcnt);
if (reply.sec_rw.attr_len > 8) if (reply.sec_rw.attr_len > 8)
{ {
@@ -384,7 +382,7 @@ static int sec_getevents(struct thread_data *td, unsigned int min, unsigned int
{ {
if (reply.hdr.retval != io->xfer_buflen) if (reply.hdr.retval != io->xfer_buflen)
{ {
fprintf(stderr, "Short write: retval = %jd instead of %ju\n", reply.hdr.retval, (uint64_t)io->xfer_buflen); fprintf(stderr, "Short write: retval = %ld instead of %lu\n", reply.hdr.retval, (uint64_t)io->xfer_buflen);
exit(1); exit(1);
} }
} }
@@ -392,13 +390,13 @@ static int sec_getevents(struct thread_data *td, unsigned int min, unsigned int
{ {
if (reply.hdr.retval != 0) if (reply.hdr.retval != 0)
{ {
fprintf(stderr, "Sync failed: retval = %jd\n", reply.hdr.retval); fprintf(stderr, "Sync failed: retval = %ld\n", reply.hdr.retval);
exit(1); exit(1);
} }
} }
if (opt->trace) if (opt->trace)
{ {
printf("--- %s # %ju\n", io->ddir == DDIR_READ ? "READ" : printf("--- %s # %ld\n", io->ddir == DDIR_READ ? "READ" :
(io->ddir == DDIR_WRITE ? "WRITE" : "SYNC"), reply.hdr.id); (io->ddir == DDIR_WRITE ? "WRITE" : "SYNC"), reply.hdr.id);
} }
bsd->completed.push_back(io); bsd->completed.push_back(io);
+401
View File
@@ -0,0 +1,401 @@
// Copyright (c) Vitaliy Filippov, 2019+
// License: VNPL-1.1 (see README.md for details)
//
// Vitastor shared key/value database test CLI
#define _XOPEN_SOURCE
#include <limits.h>
#include <netinet/tcp.h>
#include <sys/epoll.h>
#include <unistd.h>
#include <fcntl.h>
//#include <signal.h>
#include "epoll_manager.h"
#include "str_util.h"
#include "kv_db.h"
const char *exe_name = NULL;
class kv_cli_t
{
public:
kv_dbw_t *db = NULL;
ring_loop_t *ringloop = NULL;
epoll_manager_t *epmgr = NULL;
cluster_client_t *cli = NULL;
bool interactive = false;
int in_progress = 0;
char *cur_cmd = NULL;
int cur_cmd_size = 0, cur_cmd_alloc = 0;
bool finished = false, eof = false;
json11::Json::object cfg;
~kv_cli_t();
static json11::Json::object parse_args(int narg, const char *args[]);
void run(const json11::Json::object & cfg);
void read_cmd();
void next_cmd();
void handle_cmd(const std::string & cmd, std::function<void()> cb);
};
kv_cli_t::~kv_cli_t()
{
if (cur_cmd)
{
free(cur_cmd);
cur_cmd = NULL;
}
cur_cmd_alloc = 0;
if (db)
delete db;
if (cli)
{
cli->flush();
delete cli;
}
if (epmgr)
delete epmgr;
if (ringloop)
delete ringloop;
}
json11::Json::object kv_cli_t::parse_args(int narg, const char *args[])
{
json11::Json::object cfg;
for (int i = 1; i < narg; i++)
{
if (!strcmp(args[i], "-h") || !strcmp(args[i], "--help"))
{
printf(
"Vitastor Key/Value CLI\n"
"(c) Vitaliy Filippov, 2023+ (VNPL-1.1)\n"
"\n"
"USAGE: %s [--etcd_address ADDR] [OTHER OPTIONS]\n",
exe_name
);
exit(0);
}
else if (args[i][0] == '-' && args[i][1] == '-')
{
const char *opt = args[i]+2;
cfg[opt] = !strcmp(opt, "json") || i == narg-1 ? "1" : args[++i];
}
}
return cfg;
}
void kv_cli_t::run(const json11::Json::object & cfg)
{
// Create client
ringloop = new ring_loop_t(512);
epmgr = new epoll_manager_t(ringloop);
cli = new cluster_client_t(ringloop, epmgr->tfd, cfg);
db = new kv_dbw_t(cli);
// Load image metadata
while (!cli->is_ready())
{
ringloop->loop();
if (cli->is_ready())
break;
ringloop->wait();
}
// Run
fcntl(0, F_SETFL, fcntl(0, F_GETFL, 0) | O_NONBLOCK);
try
{
epmgr->tfd->set_fd_handler(0, false, [this](int fd, int events)
{
if (events & EPOLLIN)
{
read_cmd();
}
if (events & EPOLLRDHUP)
{
epmgr->tfd->set_fd_handler(0, false, NULL);
finished = true;
}
});
interactive = true;
printf("> ");
}
catch (std::exception & e)
{
// Can't add to epoll, STDIN is probably a file
read_cmd();
}
while (!finished)
{
ringloop->loop();
if (!finished)
ringloop->wait();
}
// Destroy the client
delete db;
db = NULL;
cli->flush();
delete cli;
delete epmgr;
delete ringloop;
cli = NULL;
epmgr = NULL;
ringloop = NULL;
}
void kv_cli_t::read_cmd()
{
if (!cur_cmd_alloc)
{
cur_cmd_alloc = 65536;
cur_cmd = (char*)malloc_or_die(cur_cmd_alloc);
}
while (cur_cmd_size < cur_cmd_alloc)
{
int r = read(0, cur_cmd+cur_cmd_size, cur_cmd_alloc-cur_cmd_size);
if (r < 0 && errno != EAGAIN)
fprintf(stderr, "Error reading from stdin: %s\n", strerror(errno));
if (r > 0)
cur_cmd_size += r;
if (r == 0)
eof = true;
if (r <= 0)
break;
}
next_cmd();
}
void kv_cli_t::next_cmd()
{
if (in_progress > 0)
{
return;
}
int pos = 0;
for (; pos < cur_cmd_size; pos++)
{
if (cur_cmd[pos] == '\n' || cur_cmd[pos] == '\r')
{
auto cmd = trim(std::string(cur_cmd, pos));
pos++;
memmove(cur_cmd, cur_cmd+pos, cur_cmd_size-pos);
cur_cmd_size -= pos;
in_progress++;
handle_cmd(cmd, [this]()
{
in_progress--;
if (interactive)
printf("> ");
next_cmd();
if (!in_progress)
read_cmd();
});
break;
}
}
if (eof && !in_progress)
{
finished = true;
}
}
void kv_cli_t::handle_cmd(const std::string & cmd, std::function<void()> cb)
{
if (cmd == "")
{
cb();
return;
}
auto pos = cmd.find_first_of(" \t");
if (pos != std::string::npos)
{
while (pos < cmd.size()-1 && (cmd[pos+1] == ' ' || cmd[pos+1] == '\t'))
pos++;
}
auto opname = strtolower(pos == std::string::npos ? cmd : cmd.substr(0, pos));
if (opname == "open")
{
uint64_t pool_id = 0;
inode_t inode_id = 0;
uint32_t kv_block_size = 0;
int scanned = sscanf(cmd.c_str() + pos+1, "%lu %lu %u", &pool_id, &inode_id, &kv_block_size);
if (scanned == 2)
{
kv_block_size = 4096;
}
if (scanned < 2 || !pool_id || !inode_id || !kv_block_size || (kv_block_size & (kv_block_size-1)) != 0)
{
fprintf(stderr, "Usage: open <pool_id> <inode_id> [block_size]. Block size must be a power of 2. Default is 4096.\n");
cb();
return;
}
cfg["kv_block_size"] = (uint64_t)kv_block_size;
db->open(INODE_WITH_POOL(pool_id, inode_id), cfg, [=](int res)
{
if (res < 0)
fprintf(stderr, "Error opening index: %s (code %d)\n", strerror(-res), res);
else
printf("Index opened. Current size: %lu bytes\n", db->get_size());
cb();
});
}
else if (opname == "config")
{
auto pos2 = cmd.find_first_of(" \t", pos+1);
if (pos2 == std::string::npos)
{
fprintf(stderr, "Usage: config <property> <value>\n");
cb();
return;
}
auto key = trim(cmd.substr(pos+1, pos2-pos-1));
auto value = parse_size(trim(cmd.substr(pos2+1)));
if (key != "kv_memory_limit" &&
key != "kv_allocate_blocks" &&
key != "kv_evict_max_misses" &&
key != "kv_evict_attempts_per_level" &&
key != "kv_evict_unused_age" &&
key != "kv_log_level")
{
fprintf(
stderr, "Allowed properties: kv_memory_limit, kv_allocate_blocks,"
" kv_evict_max_misses, kv_evict_attempts_per_level, kv_evict_unused_age, kv_log_level\n"
);
}
else
{
cfg[key] = value;
db->set_config(cfg);
}
cb();
}
else if (opname == "get" || opname == "set" || opname == "del")
{
if (opname == "get" || opname == "del")
{
if (pos == std::string::npos)
{
fprintf(stderr, "Usage: %s <key>\n", opname.c_str());
cb();
return;
}
auto key = trim(cmd.substr(pos+1));
if (opname == "get")
{
db->get(key, [this, cb](int res, const std::string & value)
{
if (res < 0)
fprintf(stderr, "Error: %s (code %d)\n", strerror(-res), res);
else
{
write(1, value.c_str(), value.size());
write(1, "\n", 1);
}
cb();
});
}
else
{
db->del(key, [this, cb](int res)
{
if (res < 0)
fprintf(stderr, "Error: %s (code %d)\n", strerror(-res), res);
else
printf("OK\n");
cb();
});
}
}
else
{
auto pos2 = cmd.find_first_of(" \t", pos+1);
if (pos2 == std::string::npos)
{
fprintf(stderr, "Usage: set <key> <value>\n");
cb();
return;
}
auto key = trim(cmd.substr(pos+1, pos2-pos-1));
auto value = trim(cmd.substr(pos2+1));
db->set(key, value, [this, cb](int res)
{
if (res < 0)
fprintf(stderr, "Error: %s (code %d)\n", strerror(-res), res);
else
printf("OK\n");
cb();
});
}
}
else if (opname == "list")
{
std::string start, end;
if (pos != std::string::npos)
{
auto pos2 = cmd.find_first_of(" \t", pos+1);
if (pos2 != std::string::npos)
{
start = trim(cmd.substr(pos+1, pos2-pos-1));
end = trim(cmd.substr(pos2+1));
}
else
{
start = trim(cmd.substr(pos+1));
}
}
void *handle = db->list_start(start);
db->list_next(handle, [=](int res, const std::string & key, const std::string & value)
{
if (res < 0)
{
if (res != -ENOENT)
{
fprintf(stderr, "Error: %s (code %d)\n", strerror(-res), res);
}
db->list_close(handle);
cb();
}
else
{
printf("%s = %s\n", key.c_str(), value.c_str());
db->list_next(handle, NULL);
}
});
}
else if (opname == "close")
{
db->close([=]()
{
printf("Index closed\n");
cb();
});
}
else if (opname == "quit" || opname == "q")
{
::close(0);
finished = true;
}
else
{
fprintf(
stderr, "Unknown operation: %s. Supported operations:\n"
"open <pool_id> <inode_id> [block_size]\n"
"config <property> <value>\n"
"get <key>\nset <key> <value>\ndel <key>\nlist [<start> [end]]\n"
"close\nquit\n", opname.c_str()
);
cb();
}
}
int main(int narg, const char *args[])
{
setvbuf(stdout, NULL, _IONBF, 0);
setvbuf(stderr, NULL, _IONBF, 0);
exe_name = args[0];
kv_cli_t *p = new kv_cli_t();
p->run(kv_cli_t::parse_args(narg, args));
delete p;
return 0;
}
+2068
View File
File diff suppressed because it is too large Load Diff
+39
View File
@@ -0,0 +1,39 @@
// Copyright (c) Vitaliy Filippov, 2019+
// License: VNPL-1.1 (see README.md for details)
//
// Vitastor shared key/value database
// Parallel optimistic B-Tree O:-)
#pragma once
#include "cluster_client.h"
struct kv_db_t;
struct kv_dbw_t
{
kv_dbw_t(cluster_client_t *cli);
~kv_dbw_t();
void open(inode_t inode_id, json11::Json cfg, std::function<void(int)> cb);
void set_config(json11::Json cfg);
void close(std::function<void()> cb);
uint64_t get_size();
void get(const std::string & key, std::function<void(int res, const std::string & value)> cb,
bool allow_old_cached = false);
void set(const std::string & key, const std::string & value, std::function<void(int res)> cb,
std::function<bool(int res, const std::string & value)> cas_compare = NULL);
void del(const std::string & key, std::function<void(int res)> cb,
std::function<bool(int res, const std::string & value)> cas_compare = NULL);
void update(const std::string & key,
std::function<int(int res, const std::string & old_value, std::string & new_value)> cas_compare,
std::function<bool(int res)> cb);
void* list_start(const std::string & start);
void list_next(void *handle, std::function<void(int res, const std::string & key, const std::string & value)> cb);
void list_close(void *handle);
kv_db_t *db;
};
+697
View File
@@ -0,0 +1,697 @@
// Copyright (c) Vitaliy Filippov, 2019+
// License: VNPL-1.1 (see README.md for details)
//
// Vitastor shared key/value database stress tester / benchmark
#define _XOPEN_SOURCE
#include <limits.h>
#include <netinet/tcp.h>
#include <sys/epoll.h>
#include <unistd.h>
#include <fcntl.h>
//#include <signal.h>
#include "epoll_manager.h"
#include "str_util.h"
#include "kv_db.h"
const char *exe_name = NULL;
struct kv_test_listing_t
{
uint64_t count = 0, done = 0;
void *handle = NULL;
std::string next_after;
std::set<std::string> inflights;
timespec tv_begin;
bool error = false;
};
struct kv_test_lat_t
{
const char *name = NULL;
uint64_t usec = 0, count = 0;
};
struct kv_test_stat_t
{
kv_test_lat_t get, add, update, del, list;
uint64_t list_keys = 0;
};
class kv_test_t
{
public:
// Config
json11::Json::object kv_cfg;
std::string key_prefix, key_suffix;
uint64_t inode_id = 0;
uint64_t op_count = 1000000;
uint64_t runtime_sec = 0;
uint64_t parallelism = 4;
uint64_t reopen_prob = 1;
uint64_t get_prob = 30000;
uint64_t add_prob = 20000;
uint64_t update_prob = 20000;
uint64_t del_prob = 5000;
uint64_t list_prob = 300;
uint64_t min_key_len = 10;
uint64_t max_key_len = 70;
uint64_t min_value_len = 50;
uint64_t max_value_len = 300;
uint64_t min_list_count = 10;
uint64_t max_list_count = 1000;
uint64_t print_stats_interval = 1;
bool json_output = false;
uint64_t log_level = 1;
bool trace = false;
bool stop_on_error = false;
// FIXME: Multiple clients
kv_test_stat_t stat, prev_stat;
timespec prev_stat_time, start_stat_time;
// State
kv_dbw_t *db = NULL;
ring_loop_t *ringloop = NULL;
epoll_manager_t *epmgr = NULL;
cluster_client_t *cli = NULL;
ring_consumer_t consumer;
bool finished = false;
uint64_t total_prob = 0;
uint64_t ops_sent = 0, ops_done = 0;
int stat_timer_id = -1;
int in_progress = 0;
bool reopening = false;
std::set<kv_test_listing_t*> listings;
std::set<std::string> changing_keys;
std::map<std::string, std::string> values;
~kv_test_t();
static json11::Json::object parse_args(int narg, const char *args[]);
void parse_config(json11::Json cfg);
void run(json11::Json cfg);
void loop();
void print_stats(kv_test_stat_t & prev_stat, timespec & prev_stat_time);
void print_total_stats();
void start_change(const std::string & key);
void stop_change(const std::string & key);
void add_stat(kv_test_lat_t & stat, timespec tv_begin);
};
kv_test_t::~kv_test_t()
{
if (db)
delete db;
if (cli)
{
cli->flush();
delete cli;
}
if (epmgr)
delete epmgr;
if (ringloop)
delete ringloop;
}
json11::Json::object kv_test_t::parse_args(int narg, const char *args[])
{
json11::Json::object cfg;
for (int i = 1; i < narg; i++)
{
if (!strcmp(args[i], "-h") || !strcmp(args[i], "--help"))
{
printf(
"Vitastor Key/Value DB stress tester / benchmark\n"
"(c) Vitaliy Filippov, 2023+ (VNPL-1.1)\n"
"\n"
"USAGE: %s --pool_id POOL_ID --inode_id INODE_ID [OPTIONS]\n"
" --op_count 1000000\n"
" Total operations to run during test. 0 means unlimited\n"
" --key_prefix \"\"\n"
" Prefix for all keys read or written (to avoid collisions)\n"
" --key_suffix \"\"\n"
" Suffix for all keys read or written (to avoid collisions, but scan all DB)\n"
" --runtime 0\n"
" Run for this number of seconds. 0 means unlimited\n"
" --parallelism 4\n"
" Run this number of operations in parallel\n"
" --get_prob 30000\n"
" Fraction of key retrieve operations\n"
" --add_prob 20000\n"
" Fraction of key addition operations\n"
" --update_prob 20000\n"
" Fraction of key update operations\n"
" --del_prob 30000\n"
" Fraction of key delete operations\n"
" --list_prob 300\n"
" Fraction of listing operations\n"
" --min_key_len 10\n"
" Minimum key size in bytes\n"
" --max_key_len 70\n"
" Maximum key size in bytes\n"
" --min_value_len 50\n"
" Minimum value size in bytes\n"
" --max_value_len 300\n"
" Maximum value size in bytes\n"
" --min_list_count 10\n"
" Minimum number of keys read in listing (0 = all keys)\n"
" --max_list_count 1000\n"
" Maximum number of keys read in listing\n"
" --print_stats 1\n"
" Print operation statistics every this number of seconds\n"
" --json\n"
" JSON output\n"
" --stop_on_error 0\n"
" Stop on first execution error, mismatch, lost key or extra key during listing\n"
" --kv_memory_limit 128M\n"
" Maximum memory to use for vitastor-kv index cache\n"
" --kv_allocate_blocks 4\n"
" Number of PG blocks used for new tree block allocation in parallel\n"
" --kv_evict_max_misses 10\n"
" Eviction algorithm parameter: retry eviction from another random spot\n"
" if this number of keys is used currently or was used recently\n"
" --kv_evict_attempts_per_level 3\n"
" Retry eviction at most this number of times per tree level, starting\n"
" with bottom-most levels\n"
" --kv_evict_unused_age 1000\n"
" Evict only keys unused during this number of last operations\n"
" --kv_log_level 1\n"
" Log level. 0 = errors, 1 = warnings, 10 = trace operations\n",
exe_name
);
exit(0);
}
else if (args[i][0] == '-' && args[i][1] == '-')
{
const char *opt = args[i]+2;
cfg[opt] = !strcmp(opt, "json") || i == narg-1 ? "1" : args[++i];
}
}
return cfg;
}
void kv_test_t::parse_config(json11::Json cfg)
{
inode_id = INODE_WITH_POOL(cfg["pool_id"].uint64_value(), cfg["inode_id"].uint64_value());
if (cfg["op_count"].uint64_value() > 0)
op_count = cfg["op_count"].uint64_value();
key_prefix = cfg["key_prefix"].string_value();
key_suffix = cfg["key_suffix"].string_value();
if (cfg["runtime"].uint64_value() > 0)
runtime_sec = cfg["runtime"].uint64_value();
if (cfg["parallelism"].uint64_value() > 0)
parallelism = cfg["parallelism"].uint64_value();
if (!cfg["reopen_prob"].is_null())
reopen_prob = cfg["reopen_prob"].uint64_value();
if (!cfg["get_prob"].is_null())
get_prob = cfg["get_prob"].uint64_value();
if (!cfg["add_prob"].is_null())
add_prob = cfg["add_prob"].uint64_value();
if (!cfg["update_prob"].is_null())
update_prob = cfg["update_prob"].uint64_value();
if (!cfg["del_prob"].is_null())
del_prob = cfg["del_prob"].uint64_value();
if (!cfg["list_prob"].is_null())
list_prob = cfg["list_prob"].uint64_value();
if (!cfg["min_key_len"].is_null())
min_key_len = cfg["min_key_len"].uint64_value();
if (cfg["max_key_len"].uint64_value() > 0)
max_key_len = cfg["max_key_len"].uint64_value();
if (!cfg["min_value_len"].is_null())
min_value_len = cfg["min_value_len"].uint64_value();
if (cfg["max_value_len"].uint64_value() > 0)
max_value_len = cfg["max_value_len"].uint64_value();
if (!cfg["min_list_count"].is_null())
min_list_count = cfg["min_list_count"].uint64_value();
if (!cfg["max_list_count"].is_null())
max_list_count = cfg["max_list_count"].uint64_value();
if (!cfg["print_stats"].is_null())
print_stats_interval = cfg["print_stats"].uint64_value();
if (!cfg["json"].is_null())
json_output = true;
if (!cfg["stop_on_error"].is_null())
stop_on_error = cfg["stop_on_error"].bool_value();
if (!cfg["kv_memory_limit"].is_null())
kv_cfg["kv_memory_limit"] = cfg["kv_memory_limit"];
if (!cfg["kv_allocate_blocks"].is_null())
kv_cfg["kv_allocate_blocks"] = cfg["kv_allocate_blocks"];
if (!cfg["kv_evict_max_misses"].is_null())
kv_cfg["kv_evict_max_misses"] = cfg["kv_evict_max_misses"];
if (!cfg["kv_evict_attempts_per_level"].is_null())
kv_cfg["kv_evict_attempts_per_level"] = cfg["kv_evict_attempts_per_level"];
if (!cfg["kv_evict_unused_age"].is_null())
kv_cfg["kv_evict_unused_age"] = cfg["kv_evict_unused_age"];
if (!cfg["kv_log_level"].is_null())
{
log_level = cfg["kv_log_level"].uint64_value();
trace = log_level >= 10;
kv_cfg["kv_log_level"] = cfg["kv_log_level"];
}
total_prob = reopen_prob+get_prob+add_prob+update_prob+del_prob+list_prob;
stat.get.name = "get";
stat.add.name = "add";
stat.update.name = "update";
stat.del.name = "del";
stat.list.name = "list";
}
void kv_test_t::run(json11::Json cfg)
{
srand48(time(NULL));
parse_config(cfg);
// Create client
ringloop = new ring_loop_t(512);
epmgr = new epoll_manager_t(ringloop);
cli = new cluster_client_t(ringloop, epmgr->tfd, cfg);
db = new kv_dbw_t(cli);
// Load image metadata
while (!cli->is_ready())
{
ringloop->loop();
if (cli->is_ready())
break;
ringloop->wait();
}
// Run
reopening = true;
db->open(inode_id, kv_cfg, [this](int res)
{
reopening = false;
if (res < 0)
{
fprintf(stderr, "ERROR: Open index: %d (%s)\n", res, strerror(-res));
exit(1);
}
if (trace)
printf("Index opened\n");
ringloop->wakeup();
});
consumer.loop = [this]() { loop(); };
ringloop->register_consumer(&consumer);
if (print_stats_interval)
stat_timer_id = epmgr->tfd->set_timer(print_stats_interval*1000, true, [this](int) { print_stats(prev_stat, prev_stat_time); });
clock_gettime(CLOCK_REALTIME, &start_stat_time);
prev_stat_time = start_stat_time;
while (!finished)
{
ringloop->loop();
if (!finished)
ringloop->wait();
}
if (stat_timer_id >= 0)
epmgr->tfd->clear_timer(stat_timer_id);
ringloop->unregister_consumer(&consumer);
// Print total stats
print_total_stats();
// Destroy the client
delete db;
db = NULL;
cli->flush();
delete cli;
delete epmgr;
delete ringloop;
cli = NULL;
epmgr = NULL;
ringloop = NULL;
}
static const char *base64_chars = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789@+/";
std::string random_str(int len)
{
std::string str;
str.resize(len);
for (int i = 0; i < len; i++)
{
str[i] = base64_chars[lrand48() % 64];
}
return str;
}
void kv_test_t::loop()
{
if (reopening)
{
return;
}
if (ops_done >= op_count)
{
finished = true;
}
while (!finished && ops_sent < op_count && in_progress < parallelism)
{
uint64_t dice = (lrand48() % total_prob);
if (dice < reopen_prob)
{
reopening = true;
db->close([this]()
{
if (trace)
printf("Index closed\n");
db->open(inode_id, kv_cfg, [this](int res)
{
reopening = false;
if (res < 0)
{
fprintf(stderr, "ERROR: Reopen index: %d (%s)\n", res, strerror(-res));
finished = true;
return;
}
if (trace)
printf("Index reopened\n");
ringloop->wakeup();
});
});
return;
}
else if (dice < reopen_prob+get_prob)
{
// get existing
auto key = random_str(max_key_len);
auto k_it = values.lower_bound(key);
if (k_it == values.end())
continue;
key = k_it->first;
if (changing_keys.find(key) != changing_keys.end())
continue;
in_progress++;
ops_sent++;
if (trace)
printf("get %s\n", key.c_str());
timespec tv_begin;
clock_gettime(CLOCK_REALTIME, &tv_begin);
db->get(key, [this, key, tv_begin](int res, const std::string & value)
{
add_stat(stat.get, tv_begin);
ops_done++;
in_progress--;
auto it = values.find(key);
if (res != (it == values.end() ? -ENOENT : 0))
{
fprintf(stderr, "ERROR: get %s: %d (%s)\n", key.c_str(), res, strerror(-res));
if (stop_on_error)
exit(1);
}
else if (it != values.end() && value != it->second)
{
fprintf(stderr, "ERROR: get %s: mismatch: %s vs %s\n", key.c_str(), value.c_str(), it->second.c_str());
if (stop_on_error)
exit(1);
}
ringloop->wakeup();
});
}
else if (dice < reopen_prob+get_prob+add_prob+update_prob)
{
bool is_add = false;
std::string key;
if (dice < reopen_prob+get_prob+add_prob)
{
// add
is_add = true;
uint64_t key_len = min_key_len + (max_key_len > min_key_len ? lrand48() % (max_key_len-min_key_len) : 0);
key = key_prefix + random_str(key_len) + key_suffix;
}
else
{
// update
key = random_str(max_key_len);
auto k_it = values.lower_bound(key);
if (k_it == values.end())
continue;
key = k_it->first;
}
if (changing_keys.find(key) != changing_keys.end())
continue;
uint64_t value_len = min_value_len + (max_value_len > min_value_len ? lrand48() % (max_value_len-min_value_len) : 0);
auto value = random_str(value_len);
start_change(key);
ops_sent++;
in_progress++;
if (trace)
printf("set %s = %s\n", key.c_str(), value.c_str());
timespec tv_begin;
clock_gettime(CLOCK_REALTIME, &tv_begin);
db->set(key, value, [this, key, value, tv_begin, is_add](int res)
{
add_stat(is_add ? stat.add : stat.update, tv_begin);
stop_change(key);
ops_done++;
in_progress--;
if (res != 0)
{
fprintf(stderr, "ERROR: set %s = %s: %d (%s)\n", key.c_str(), value.c_str(), res, strerror(-res));
if (stop_on_error)
exit(1);
}
else
{
values[key] = value;
}
ringloop->wakeup();
}, NULL);
}
else if (dice < reopen_prob+get_prob+add_prob+update_prob+del_prob)
{
// delete
auto key = random_str(max_key_len);
auto k_it = values.lower_bound(key);
if (k_it == values.end())
continue;
key = k_it->first;
if (changing_keys.find(key) != changing_keys.end())
continue;
start_change(key);
ops_sent++;
in_progress++;
if (trace)
printf("del %s\n", key.c_str());
timespec tv_begin;
clock_gettime(CLOCK_REALTIME, &tv_begin);
db->del(key, [this, key, tv_begin](int res)
{
add_stat(stat.del, tv_begin);
stop_change(key);
ops_done++;
in_progress--;
if (res != 0)
{
fprintf(stderr, "ERROR: del %s: %d (%s)\n", key.c_str(), res, strerror(-res));
if (stop_on_error)
exit(1);
}
else
{
values.erase(key);
}
ringloop->wakeup();
}, NULL);
}
else if (dice < reopen_prob+get_prob+add_prob+update_prob+del_prob+list_prob)
{
// list
ops_sent++;
in_progress++;
auto key = random_str(max_key_len);
auto lst = new kv_test_listing_t;
auto k_it = values.lower_bound(key);
lst->count = min_list_count + (max_list_count > min_list_count ? lrand48() % (max_list_count-min_list_count) : 0);
lst->handle = db->list_start(k_it == values.begin() ? key_prefix : key);
lst->next_after = k_it == values.begin() ? key_prefix : key;
lst->inflights = changing_keys;
listings.insert(lst);
if (trace)
printf("list from %s\n", key.c_str());
clock_gettime(CLOCK_REALTIME, &lst->tv_begin);
db->list_next(lst->handle, [this, lst](int res, const std::string & key, const std::string & value)
{
if (log_level >= 11)
printf("list: %s = %s\n", key.c_str(), value.c_str());
if (res >= 0 && key_prefix.size() && (key.size() < key_prefix.size() ||
key.substr(0, key_prefix.size()) != key_prefix))
{
// stop at this key
res = -ENOENT;
}
if (res < 0 || (lst->count > 0 && lst->done >= lst->count))
{
add_stat(stat.list, lst->tv_begin);
if (res == 0)
{
// ok (done >= count)
}
else if (res != -ENOENT)
{
fprintf(stderr, "ERROR: list: %d (%s)\n", res, strerror(-res));
lst->error = true;
}
else
{
auto k_it = lst->next_after == "" ? values.begin() : values.upper_bound(lst->next_after);
while (k_it != values.end())
{
while (k_it != values.end() && lst->inflights.find(k_it->first) != lst->inflights.end())
k_it++;
if (k_it != values.end())
{
fprintf(stderr, "ERROR: list: missing key %s\n", (k_it++)->first.c_str());
lst->error = true;
}
}
}
if (lst->error && stop_on_error)
exit(1);
ops_done++;
in_progress--;
db->list_close(lst->handle);
delete lst;
listings.erase(lst);
ringloop->wakeup();
}
else
{
stat.list_keys++;
// Do not check modified keys in listing
// Listing may return their old or new state
if ((!key_suffix.size() || key.size() >= key_suffix.size() &&
key.substr(key.size()-key_suffix.size()) == key_suffix) &&
lst->inflights.find(key) == lst->inflights.end())
{
lst->done++;
auto k_it = lst->next_after == "" ? values.begin() : values.upper_bound(lst->next_after);
while (true)
{
while (k_it != values.end() && lst->inflights.find(k_it->first) != lst->inflights.end())
{
k_it++;
}
if (k_it == values.end() || k_it->first > key)
{
fprintf(stderr, "ERROR: list: extra key %s\n", key.c_str());
lst->error = true;
break;
}
else if (k_it->first < key)
{
fprintf(stderr, "ERROR: list: missing key %s\n", k_it->first.c_str());
lst->error = true;
lst->next_after = k_it->first;
k_it++;
}
else
{
if (k_it->second != value)
{
fprintf(stderr, "ERROR: list: mismatch: %s = %s but should be %s\n",
key.c_str(), value.c_str(), k_it->second.c_str());
lst->error = true;
}
lst->next_after = k_it->first;
break;
}
}
}
db->list_next(lst->handle, NULL);
}
});
}
}
}
void kv_test_t::add_stat(kv_test_lat_t & stat, timespec tv_begin)
{
timespec tv_end;
clock_gettime(CLOCK_REALTIME, &tv_end);
int64_t usec = (tv_end.tv_sec - tv_begin.tv_sec)*1000000 +
(tv_end.tv_nsec - tv_begin.tv_nsec)/1000;
if (usec > 0)
{
stat.usec += usec;
stat.count++;
}
}
void kv_test_t::print_stats(kv_test_stat_t & prev_stat, timespec & prev_stat_time)
{
timespec cur_stat_time;
clock_gettime(CLOCK_REALTIME, &cur_stat_time);
int64_t usec = (cur_stat_time.tv_sec - prev_stat_time.tv_sec)*1000000 +
(cur_stat_time.tv_nsec - prev_stat_time.tv_nsec)/1000;
if (usec > 0)
{
kv_test_lat_t *lats[] = { &stat.get, &stat.add, &stat.update, &stat.del, &stat.list };
kv_test_lat_t *prev[] = { &prev_stat.get, &prev_stat.add, &prev_stat.update, &prev_stat.del, &prev_stat.list };
if (!json_output)
{
char buf[128] = { 0 };
for (int i = 0; i < sizeof(lats)/sizeof(lats[0]); i++)
{
snprintf(buf, sizeof(buf)-1, "%.1f %s/s (%lu us)", (lats[i]->count-prev[i]->count)*1000000.0/usec,
lats[i]->name, (lats[i]->usec-prev[i]->usec)/(lats[i]->count-prev[i]->count > 0 ? lats[i]->count-prev[i]->count : 1));
int k;
for (k = strlen(buf); k < strlen(lats[i]->name)+21; k++)
buf[k] = ' ';
buf[k] = 0;
printf("%s", buf);
}
printf("\n");
}
else
{
int64_t runtime = (cur_stat_time.tv_sec - start_stat_time.tv_sec)*1000000 +
(cur_stat_time.tv_nsec - start_stat_time.tv_nsec)/1000;
printf("{\"runtime\":%.1f", (double)runtime/1000000.0);
for (int i = 0; i < sizeof(lats)/sizeof(lats[0]); i++)
{
if (lats[i]->count > prev[i]->count)
{
printf(
",\"%s\":{\"avg\":{\"iops\":%.1f,\"usec\":%lu},\"total\":{\"count\":%lu,\"usec\":%lu}}",
lats[i]->name, (lats[i]->count-prev[i]->count)*1000000.0/usec,
(lats[i]->usec-prev[i]->usec)/(lats[i]->count-prev[i]->count),
lats[i]->count, lats[i]->usec
);
}
}
printf("}\n");
}
}
prev_stat = stat;
prev_stat_time = cur_stat_time;
}
void kv_test_t::print_total_stats()
{
if (!json_output)
printf("Total:\n");
kv_test_stat_t start_stats;
timespec start_stat_time = this->start_stat_time;
print_stats(start_stats, start_stat_time);
}
void kv_test_t::start_change(const std::string & key)
{
changing_keys.insert(key);
for (auto lst: listings)
{
lst->inflights.insert(key);
}
}
void kv_test_t::stop_change(const std::string & key)
{
changing_keys.erase(key);
}
int main(int narg, const char *args[])
{
setvbuf(stdout, NULL, _IONBF, 0);
setvbuf(stderr, NULL, _IONBF, 0);
exe_name = args[0];
kv_test_t *p = new kv_test_t();
p->run(kv_test_t::parse_args(narg, args));
delete p;
return 0;
}
+4 -4
View File
@@ -11,7 +11,7 @@ inline void* memalign_or_die(size_t alignment, size_t size)
void *buf = memalign(alignment, size); void *buf = memalign(alignment, size);
if (!buf) if (!buf)
{ {
printf("Failed to allocate %zu bytes\n", size); printf("Failed to allocate %lu bytes\n", size);
exit(1); exit(1);
} }
return buf; return buf;
@@ -22,7 +22,7 @@ inline void* malloc_or_die(size_t size)
void *buf = malloc(size); void *buf = malloc(size);
if (!buf) if (!buf)
{ {
printf("Failed to allocate %zu bytes\n", size); printf("Failed to allocate %lu bytes\n", size);
exit(1); exit(1);
} }
return buf; return buf;
@@ -33,7 +33,7 @@ inline void* realloc_or_die(void *ptr, size_t size)
void *buf = realloc(ptr, size); void *buf = realloc(ptr, size);
if (!buf) if (!buf)
{ {
printf("Failed to allocate %zu bytes\n", size); printf("Failed to allocate %lu bytes\n", size);
exit(1); exit(1);
} }
return buf; return buf;
@@ -44,7 +44,7 @@ inline void* calloc_or_die(size_t nmemb, size_t size)
void *buf = calloc(nmemb, size); void *buf = calloc(nmemb, size);
if (!buf) if (!buf)
{ {
printf("Failed to allocate %zu bytes\n", size * nmemb); printf("Failed to allocate %lu bytes\n", size * nmemb);
exit(1); exit(1);
} }
return buf; return buf;
+29 -25
View File
@@ -27,13 +27,13 @@ void osd_messenger_t::init()
if (!rdma_context) if (!rdma_context)
{ {
if (log_level > 0) if (log_level > 0)
fprintf(stderr, "[OSD %ju] Couldn't initialize RDMA, proceeding with TCP only\n", osd_num); fprintf(stderr, "[OSD %lu] Couldn't initialize RDMA, proceeding with TCP only\n", osd_num);
} }
else else
{ {
rdma_max_sge = rdma_max_sge < rdma_context->attrx.orig_attr.max_sge rdma_max_sge = rdma_max_sge < rdma_context->attrx.orig_attr.max_sge
? rdma_max_sge : rdma_context->attrx.orig_attr.max_sge; ? rdma_max_sge : rdma_context->attrx.orig_attr.max_sge;
fprintf(stderr, "[OSD %ju] RDMA initialized successfully\n", osd_num); fprintf(stderr, "[OSD %lu] RDMA initialized successfully\n", osd_num);
fcntl(rdma_context->channel->fd, F_SETFL, fcntl(rdma_context->channel->fd, F_GETFL, 0) | O_NONBLOCK); fcntl(rdma_context->channel->fd, F_SETFL, fcntl(rdma_context->channel->fd, F_GETFL, 0) | O_NONBLOCK);
tfd->set_fd_handler(rdma_context->channel->fd, false, [this](int notify_fd, int epoll_events) tfd->set_fd_handler(rdma_context->channel->fd, false, [this](int notify_fd, int epoll_events)
{ {
@@ -45,12 +45,11 @@ void osd_messenger_t::init()
#endif #endif
keepalive_timer_id = tfd->set_timer(1000, true, [this](int) keepalive_timer_id = tfd->set_timer(1000, true, [this](int)
{ {
auto cl_it = clients.begin(); std::vector<int> to_stop;
while (cl_it != clients.end()) std::vector<osd_op_t*> to_ping;
for (auto cl_it = clients.begin(); cl_it != clients.end(); cl_it++)
{ {
auto cl = cl_it->second; auto cl = cl_it->second;
cl_it++;
auto peer_fd = cl->peer_fd;
if (!cl->osd_num || cl->peer_state != PEER_CONNECTED && cl->peer_state != PEER_RDMA) if (!cl->osd_num || cl->peer_state != PEER_CONNECTED && cl->peer_state != PEER_RDMA)
{ {
// Do not run keepalive on regular clients // Do not run keepalive on regular clients
@@ -62,10 +61,8 @@ void osd_messenger_t::init()
if (!cl->ping_time_remaining) if (!cl->ping_time_remaining)
{ {
// Ping timed out, stop the client // Ping timed out, stop the client
fprintf(stderr, "Ping timed out for OSD %ju (client %d), disconnecting peer\n", cl->osd_num, cl->peer_fd); fprintf(stderr, "Ping timed out for OSD %lu (client %d), disconnecting peer\n", cl->osd_num, cl->peer_fd);
stop_client(peer_fd, true); to_stop.push_back(cl->peer_fd);
// Restart iterator because it may be invalidated
cl_it = clients.upper_bound(peer_fd);
} }
} }
else if (cl->idle_time_remaining > 0) else if (cl->idle_time_remaining > 0)
@@ -99,15 +96,13 @@ void osd_messenger_t::init()
delete op; delete op;
if (fail_fd >= 0) if (fail_fd >= 0)
{ {
fprintf(stderr, "Ping failed for OSD %ju (client %d), disconnecting peer\n", fail_osd_num, fail_fd); fprintf(stderr, "Ping failed for OSD %lu (client %d), disconnecting peer\n", fail_osd_num, fail_fd);
stop_client(fail_fd, true); stop_client(fail_fd, true);
} }
}; };
to_ping.push_back(op);
cl->ping_time_remaining = osd_ping_timeout; cl->ping_time_remaining = osd_ping_timeout;
cl->idle_time_remaining = osd_idle_timeout; cl->idle_time_remaining = osd_idle_timeout;
outbox_push(op);
// Restart iterator because it may be invalidated
cl_it = clients.upper_bound(peer_fd);
} }
} }
else else
@@ -115,6 +110,15 @@ void osd_messenger_t::init()
cl->idle_time_remaining = osd_idle_timeout; cl->idle_time_remaining = osd_idle_timeout;
} }
} }
// Don't stop clients while a 'clients' iterator is still active
for (int peer_fd: to_stop)
{
stop_client(peer_fd, true);
}
for (auto op: to_ping)
{
outbox_push(op);
}
}); });
} }
@@ -253,7 +257,7 @@ void osd_messenger_t::try_connect_peer_addr(osd_num_t peer_osd, const char *peer
clients[peer_fd] = new osd_client_t(); clients[peer_fd] = new osd_client_t();
if (log_level > 0) if (log_level > 0)
{ {
fprintf(stderr, "Connecting to OSD %ju at %s:%d (client %d)\n", peer_osd, peer_host, peer_port, peer_fd); fprintf(stderr, "Connecting to OSD %lu at %s:%d (client %d)\n", peer_osd, peer_host, peer_port, peer_fd);
} }
clients[peer_fd]->peer_addr = addr; clients[peer_fd]->peer_addr = addr;
clients[peer_fd]->peer_port = peer_port; clients[peer_fd]->peer_port = peer_port;
@@ -319,7 +323,7 @@ void osd_messenger_t::handle_peer_epoll(int peer_fd, int epoll_events)
// Stop client // Stop client
if (log_level > 0) if (log_level > 0)
{ {
fprintf(stderr, "[OSD %ju] client %d disconnected\n", this->osd_num, peer_fd); fprintf(stderr, "[OSD %lu] client %d disconnected\n", this->osd_num, peer_fd);
} }
stop_client(peer_fd, true); stop_client(peer_fd, true);
} }
@@ -345,7 +349,7 @@ void osd_messenger_t::on_connect_peer(osd_num_t peer_osd, int peer_fd)
wp.connecting = false; wp.connecting = false;
if (peer_fd < 0) if (peer_fd < 0)
{ {
fprintf(stderr, "Failed to connect to peer OSD %ju address %s port %d: %s\n", peer_osd, wp.cur_addr.c_str(), wp.cur_port, strerror(-peer_fd)); fprintf(stderr, "Failed to connect to peer OSD %lu address %s port %d: %s\n", peer_osd, wp.cur_addr.c_str(), wp.cur_port, strerror(-peer_fd));
if (wp.address_changed) if (wp.address_changed)
{ {
wp.address_changed = false; wp.address_changed = false;
@@ -372,7 +376,7 @@ void osd_messenger_t::on_connect_peer(osd_num_t peer_osd, int peer_fd)
} }
if (log_level > 0) if (log_level > 0)
{ {
fprintf(stderr, "[OSD %ju] Connected with peer OSD %ju (client %d)\n", osd_num, peer_osd, peer_fd); fprintf(stderr, "[OSD %lu] Connected with peer OSD %lu (client %d)\n", osd_num, peer_osd, peer_fd);
} }
wanted_peers.erase(peer_osd); wanted_peers.erase(peer_osd);
repeer_pgs(peer_osd); repeer_pgs(peer_osd);
@@ -418,7 +422,7 @@ void osd_messenger_t::check_peer_config(osd_client_t *cl)
if (op->reply.hdr.retval < 0) if (op->reply.hdr.retval < 0)
{ {
err = true; err = true;
fprintf(stderr, "Failed to get config from OSD %ju (retval=%jd), disconnecting peer\n", cl->osd_num, op->reply.hdr.retval); fprintf(stderr, "Failed to get config from OSD %lu (retval=%ld), disconnecting peer\n", cl->osd_num, op->reply.hdr.retval);
} }
else else
{ {
@@ -426,18 +430,18 @@ void osd_messenger_t::check_peer_config(osd_client_t *cl)
if (json_err != "") if (json_err != "")
{ {
err = true; err = true;
fprintf(stderr, "Failed to get config from OSD %ju: bad JSON: %s, disconnecting peer\n", cl->osd_num, json_err.c_str()); fprintf(stderr, "Failed to get config from OSD %lu: bad JSON: %s, disconnecting peer\n", cl->osd_num, json_err.c_str());
} }
else if (config["osd_num"].uint64_value() != cl->osd_num) else if (config["osd_num"].uint64_value() != cl->osd_num)
{ {
err = true; err = true;
fprintf(stderr, "Connected to OSD %ju instead of OSD %ju, peer state is outdated, disconnecting peer\n", config["osd_num"].uint64_value(), cl->osd_num); fprintf(stderr, "Connected to OSD %lu instead of OSD %lu, peer state is outdated, disconnecting peer\n", config["osd_num"].uint64_value(), cl->osd_num);
} }
else if (config["protocol_version"].uint64_value() != OSD_PROTOCOL_VERSION) else if (config["protocol_version"].uint64_value() != OSD_PROTOCOL_VERSION)
{ {
err = true; err = true;
fprintf( fprintf(
stderr, "OSD %ju protocol version is %ju, but only version %u is supported.\n" stderr, "OSD %lu protocol version is %lu, but only version %u is supported.\n"
" If you need to upgrade from 0.5.x please request it via the issue tracker.\n", " If you need to upgrade from 0.5.x please request it via the issue tracker.\n",
cl->osd_num, config["protocol_version"].uint64_value(), OSD_PROTOCOL_VERSION cl->osd_num, config["protocol_version"].uint64_value(), OSD_PROTOCOL_VERSION
); );
@@ -463,7 +467,7 @@ void osd_messenger_t::check_peer_config(osd_client_t *cl)
cl->rdma_conn->connect(&addr) != 0) cl->rdma_conn->connect(&addr) != 0)
{ {
fprintf( fprintf(
stderr, "Failed to connect to OSD %ju (address %s) using RDMA\n", stderr, "Failed to connect to OSD %lu (address %s) using RDMA\n",
cl->osd_num, config["rdma_address"].string_value().c_str() cl->osd_num, config["rdma_address"].string_value().c_str()
); );
delete cl->rdma_conn; delete cl->rdma_conn;
@@ -484,7 +488,7 @@ void osd_messenger_t::check_peer_config(osd_client_t *cl)
} }
if (log_level > 0) if (log_level > 0)
{ {
fprintf(stderr, "Connected to OSD %ju using RDMA\n", cl->osd_num); fprintf(stderr, "Connected to OSD %lu using RDMA\n", cl->osd_num);
} }
cl->peer_state = PEER_RDMA; cl->peer_state = PEER_RDMA;
tfd->set_fd_handler(cl->peer_fd, false, [this](int peer_fd, int epoll_events) tfd->set_fd_handler(cl->peer_fd, false, [this](int peer_fd, int epoll_events)
@@ -516,7 +520,7 @@ void osd_messenger_t::accept_connections(int listen_fd)
while ((peer_fd = accept(listen_fd, (sockaddr*)&addr, &peer_addr_size)) >= 0) while ((peer_fd = accept(listen_fd, (sockaddr*)&addr, &peer_addr_size)) >= 0)
{ {
assert(peer_fd != 0); assert(peer_fd != 0);
fprintf(stderr, "[OSD %ju] new client %d: connection from %s\n", this->osd_num, peer_fd, fprintf(stderr, "[OSD %lu] new client %d: connection from %s\n", this->osd_num, peer_fd,
addr_to_string(addr).c_str()); addr_to_string(addr).c_str());
fcntl(peer_fd, F_SETFL, fcntl(peer_fd, F_GETFL, 0) | O_NONBLOCK); fcntl(peer_fd, F_SETFL, fcntl(peer_fd, F_GETFL, 0) | O_NONBLOCK);
int one = 1; int one = 1;
+4 -4
View File
@@ -76,7 +76,7 @@ struct osd_op_buf_list_t
buf = (iovec*)malloc(sizeof(iovec) * alloc); buf = (iovec*)malloc(sizeof(iovec) * alloc);
if (!buf) if (!buf)
{ {
fprintf(stderr, "Failed to allocate %u bytes\n", (int)sizeof(iovec) * alloc); fprintf(stderr, "Failed to allocate %lu bytes\n", sizeof(iovec) * alloc);
exit(1); exit(1);
} }
memcpy(buf, inline_buf, sizeof(iovec) * old); memcpy(buf, inline_buf, sizeof(iovec) * old);
@@ -87,7 +87,7 @@ struct osd_op_buf_list_t
buf = (iovec*)realloc(buf, sizeof(iovec) * alloc); buf = (iovec*)realloc(buf, sizeof(iovec) * alloc);
if (!buf) if (!buf)
{ {
fprintf(stderr, "Failed to allocate %u bytes\n", (int)sizeof(iovec) * alloc); fprintf(stderr, "Failed to allocate %lu bytes\n", sizeof(iovec) * alloc);
exit(1); exit(1);
} }
} }
@@ -109,7 +109,7 @@ struct osd_op_buf_list_t
buf = (iovec*)malloc(sizeof(iovec) * alloc); buf = (iovec*)malloc(sizeof(iovec) * alloc);
if (!buf) if (!buf)
{ {
fprintf(stderr, "Failed to allocate %u bytes\n", (int)sizeof(iovec) * alloc); fprintf(stderr, "Failed to allocate %lu bytes\n", sizeof(iovec) * alloc);
exit(1); exit(1);
} }
memcpy(buf, inline_buf, sizeof(iovec)*old); memcpy(buf, inline_buf, sizeof(iovec)*old);
@@ -120,7 +120,7 @@ struct osd_op_buf_list_t
buf = (iovec*)realloc(buf, sizeof(iovec) * alloc); buf = (iovec*)realloc(buf, sizeof(iovec) * alloc);
if (!buf) if (!buf)
{ {
fprintf(stderr, "Failed to allocate %u bytes\n", (int)sizeof(iovec) * alloc); fprintf(stderr, "Failed to allocate %lu bytes\n", sizeof(iovec) * alloc);
exit(1); exit(1);
} }
} }
+3 -3
View File
@@ -10,7 +10,7 @@ std::string msgr_rdma_address_t::to_string()
{ {
char msg[sizeof "0000:00000000:00000000:00000000000000000000000000000000"]; char msg[sizeof "0000:00000000:00000000:00000000000000000000000000000000"];
sprintf( sprintf(
msg, "%04x:%06x:%06x:%016jx%016jx", lid, qpn, psn, msg, "%04x:%06x:%06x:%016lx%016lx", lid, qpn, psn,
htobe64(((uint64_t*)&gid)[0]), htobe64(((uint64_t*)&gid)[1]) htobe64(((uint64_t*)&gid)[0]), htobe64(((uint64_t*)&gid)[1])
); );
return std::string(msg); return std::string(msg);
@@ -20,7 +20,7 @@ bool msgr_rdma_address_t::from_string(const char *str, msgr_rdma_address_t *dest
{ {
uint64_t* gid = (uint64_t*)&dest->gid; uint64_t* gid = (uint64_t*)&dest->gid;
int scanned = sscanf( int scanned = sscanf(
str, "%hx:%x:%x:%16jx%16jx", &dest->lid, &dest->qpn, &dest->psn, gid, gid+1 str, "%hx:%x:%x:%16lx%16lx", &dest->lid, &dest->qpn, &dest->psn, gid, gid+1
); );
gid[0] = be64toh(gid[0]); gid[0] = be64toh(gid[0]);
gid[1] = be64toh(gid[1]); gid[1] = be64toh(gid[1]);
@@ -594,7 +594,7 @@ void osd_messenger_t::handle_rdma_events()
fprintf(stderr, "RDMA work request failed for client %d", client_id); fprintf(stderr, "RDMA work request failed for client %d", client_id);
if (cl->osd_num) if (cl->osd_num)
{ {
fprintf(stderr, " (OSD %ju)", cl->osd_num); fprintf(stderr, " (OSD %lu)", cl->osd_num);
} }
fprintf(stderr, " with status: %s, stopping client\n", ibv_wc_status_str(wc[i].status)); fprintf(stderr, " with status: %s, stopping client\n", ibv_wc_status_str(wc[i].status));
stop_client(client_id); stop_client(client_id);
+3 -3
View File
@@ -180,7 +180,7 @@ bool osd_messenger_t::handle_finished_read(osd_client_t *cl)
handle_op_hdr(cl); handle_op_hdr(cl);
else else
{ {
fprintf(stderr, "Received garbage: magic=%jx id=%ju opcode=%jx from %d\n", cl->read_op->req.hdr.magic, cl->read_op->req.hdr.id, cl->read_op->req.hdr.opcode, cl->peer_fd); fprintf(stderr, "Received garbage: magic=%lx id=%lu opcode=%lx from %d\n", cl->read_op->req.hdr.magic, cl->read_op->req.hdr.id, cl->read_op->req.hdr.opcode, cl->peer_fd);
stop_client(cl->peer_fd); stop_client(cl->peer_fd);
return false; return false;
} }
@@ -297,7 +297,7 @@ bool osd_messenger_t::handle_reply_hdr(osd_client_t *cl)
if (req_it == cl->sent_ops.end()) if (req_it == cl->sent_ops.end())
{ {
// Command out of sync. Drop connection // Command out of sync. Drop connection
fprintf(stderr, "Client %d command out of sync: id %ju\n", cl->peer_fd, cl->read_op->req.hdr.id); fprintf(stderr, "Client %d command out of sync: id %lu\n", cl->peer_fd, cl->read_op->req.hdr.id);
stop_client(cl->peer_fd); stop_client(cl->peer_fd);
return false; return false;
} }
@@ -312,7 +312,7 @@ bool osd_messenger_t::handle_reply_hdr(osd_client_t *cl)
if (op->reply.hdr.retval >= 0 && (op->reply.hdr.retval != expected_size || bmp_len > op->bitmap_len)) if (op->reply.hdr.retval >= 0 && (op->reply.hdr.retval != expected_size || bmp_len > op->bitmap_len))
{ {
// Check reply length to not overflow the buffer // Check reply length to not overflow the buffer
fprintf(stderr, "Client %d read reply of different length: expected %u+%u, got %jd+%u\n", fprintf(stderr, "Client %d read reply of different length: expected %u+%u, got %ld+%u\n",
cl->peer_fd, expected_size, op->bitmap_len, op->reply.hdr.retval, bmp_len); cl->peer_fd, expected_size, op->bitmap_len, op->reply.hdr.retval, bmp_len);
cl->sent_ops[op->req.hdr.id] = op; cl->sent_ops[op->req.hdr.id] = op;
stop_client(cl->peer_fd); stop_client(cl->peer_fd);
+2 -2
View File
@@ -61,11 +61,11 @@ void osd_messenger_t::stop_client(int peer_fd, bool force, bool force_delete)
{ {
if (cl->osd_num) if (cl->osd_num)
{ {
fprintf(stderr, "[OSD %ju] Stopping client %d (OSD peer %ju)\n", osd_num, peer_fd, cl->osd_num); fprintf(stderr, "[OSD %lu] Stopping client %d (OSD peer %lu)\n", osd_num, peer_fd, cl->osd_num);
} }
else else
{ {
fprintf(stderr, "[OSD %ju] Stopping client %d (regular client)\n", osd_num, peer_fd); fprintf(stderr, "[OSD %lu] Stopping client %d (regular client)\n", osd_num, peer_fd);
} }
} }
// First set state to STOPPED so another stop_client() call doesn't try to free it again // First set state to STOPPED so another stop_client() call doesn't try to free it again
+3 -3
View File
@@ -738,7 +738,7 @@ protected:
} }
uint64_t handle = *((uint64_t*)cur_req.handle); uint64_t handle = *((uint64_t*)cur_req.handle);
#ifdef DEBUG #ifdef DEBUG
printf("request %jx +%x %jx\n", be64toh(cur_req.from), be32toh(cur_req.len), handle); printf("request %lx +%x %lx\n", be64toh(cur_req.from), be32toh(cur_req.len), handle);
#endif #endif
void *buf = NULL; void *buf = NULL;
cluster_op_t *op = new cluster_op_t; cluster_op_t *op = new cluster_op_t;
@@ -759,7 +759,7 @@ protected:
op->callback = [this, buf, handle](cluster_op_t *op) op->callback = [this, buf, handle](cluster_op_t *op)
{ {
#ifdef DEBUG #ifdef DEBUG
printf("reply %jx e=%d\n", handle, op->retval); printf("reply %lx e=%d\n", handle, op->retval);
#endif #endif
nbd_reply *reply = (nbd_reply*)buf; nbd_reply *reply = (nbd_reply*)buf;
reply->magic = htobe32(NBD_REPLY_MAGIC); reply->magic = htobe32(NBD_REPLY_MAGIC);
@@ -769,7 +769,7 @@ protected:
if (op->retval < 0 || op->opcode != OSD_OP_READ) if (op->retval < 0 || op->opcode != OSD_OP_READ)
to_list.push_back({ .iov_base = buf, .iov_len = sizeof(nbd_reply) }); to_list.push_back({ .iov_base = buf, .iov_len = sizeof(nbd_reply) });
else else
to_list.push_back({ .iov_base = buf, .iov_len = sizeof(nbd_reply) + (size_t)op->len }); to_list.push_back({ .iov_base = buf, .iov_len = sizeof(nbd_reply) + op->len });
to_free.push_back(buf); to_free.push_back(buf);
delete op; delete op;
ringloop->wakeup(); ringloop->wakeup();
+1 -1
View File
@@ -517,7 +517,7 @@ static void extend_inode(nfs_client_t *self, uint64_t inode, uint64_t new_size)
auto & ext = self->extends[inode]; auto & ext = self->extends[inode];
if (r.err) if (r.err)
{ {
fprintf(stderr, "Error extending inode %ju to %ju bytes: %s\n", inode, new_size, r.text.c_str()); fprintf(stderr, "Error extending inode %lu to %lu bytes: %s\n", inode, new_size, r.text.c_str());
} }
if (r.err == EAGAIN || ext.next_extend > ext.cur_extend) if (r.err == EAGAIN || ext.next_extend > ext.cur_extend)
{ {
+2 -2
View File
@@ -350,7 +350,7 @@ void nfs_proxy_t::parse_stats(etcd_kv_t & kv)
pool_id_t pool_id = 0; pool_id_t pool_id = 0;
inode_t inode_num = 0; inode_t inode_num = 0;
char null_byte = 0; char null_byte = 0;
int scanned = sscanf(key.c_str() + cli->st_cli.etcd_prefix.length()+13, "%u/%ju%c", &pool_id, &inode_num, &null_byte); int scanned = sscanf(key.c_str() + cli->st_cli.etcd_prefix.length()+13, "%u/%lu%c", &pool_id, &inode_num, &null_byte);
if (scanned != 2 || !pool_id || pool_id >= POOL_ID_MAX || !inode_num) if (scanned != 2 || !pool_id || pool_id >= POOL_ID_MAX || !inode_num)
{ {
fprintf(stderr, "Bad etcd key %s, ignoring\n", key.c_str()); fprintf(stderr, "Bad etcd key %s, ignoring\n", key.c_str());
@@ -387,7 +387,7 @@ void nfs_proxy_t::check_default_pool()
} }
else else
{ {
fprintf(stderr, "There are %zu pools. Please select default pool with --pool option\n", cli->st_cli.pool_config.size()); fprintf(stderr, "There are %lu pools. Please select default pool with --pool option\n", cli->st_cli.pool_config.size());
exit(1); exit(1);
} }
} }
+20 -23
View File
@@ -22,7 +22,7 @@ static blockstore_config_t json_to_bs(const json11::Json::object & config)
{ {
if (kv.second.is_string()) if (kv.second.is_string())
bs[kv.first] = kv.second.string_value(); bs[kv.first] = kv.second.string_value();
else if (!kv.second.is_null()) else
bs[kv.first] = kv.second.dump(); bs[kv.first] = kv.second.dump();
} }
return bs; return bs;
@@ -194,8 +194,7 @@ void osd_t::parse_config(bool init)
if (autosync_interval > MAX_AUTOSYNC_INTERVAL) if (autosync_interval > MAX_AUTOSYNC_INTERVAL)
autosync_interval = DEFAULT_AUTOSYNC_INTERVAL; autosync_interval = DEFAULT_AUTOSYNC_INTERVAL;
} }
if (config["autosync_writes"].is_number() || if (!config["autosync_writes"].is_null())
config["autosync_writes"].string_value() != "")
{ {
// Allow to set it to 0 // Allow to set it to 0
autosync_writes = config["autosync_writes"].uint64_value(); autosync_writes = config["autosync_writes"].uint64_value();
@@ -233,8 +232,6 @@ void osd_t::parse_config(bool init)
? 10 : config["recovery_tune_agg_interval"].uint64_value(); ? 10 : config["recovery_tune_agg_interval"].uint64_value();
recovery_tune_sleep_min_us = config["recovery_tune_sleep_min_us"].is_null() recovery_tune_sleep_min_us = config["recovery_tune_sleep_min_us"].is_null()
? 10 : config["recovery_tune_sleep_min_us"].uint64_value(); ? 10 : config["recovery_tune_sleep_min_us"].uint64_value();
recovery_tune_sleep_cutoff_us = config["recovery_tune_sleep_cutoff_us"].is_null()
? 10000000 : config["recovery_tune_sleep_cutoff_us"].uint64_value();
recovery_pg_switch = config["recovery_pg_switch"].uint64_value(); recovery_pg_switch = config["recovery_pg_switch"].uint64_value();
if (recovery_pg_switch < 1) if (recovery_pg_switch < 1)
recovery_pg_switch = DEFAULT_RECOVERY_PG_SWITCH; recovery_pg_switch = DEFAULT_RECOVERY_PG_SWITCH;
@@ -475,14 +472,14 @@ void osd_t::print_stats()
if (msgr.stats.op_stat_bytes[i] != 0) if (msgr.stats.op_stat_bytes[i] != 0)
{ {
printf( printf(
"[OSD %ju] avg latency for op %d (%s): %ju us, B/W: %.2f %s\n", osd_num, i, osd_op_names[i], avg, "[OSD %lu] avg latency for op %d (%s): %lu us, B/W: %.2f %s\n", osd_num, i, osd_op_names[i], avg,
(bw > 1024*1024*1024 ? bw/1024.0/1024/1024 : (bw > 1024*1024 ? bw/1024.0/1024 : bw/1024.0)), (bw > 1024*1024*1024 ? bw/1024.0/1024/1024 : (bw > 1024*1024 ? bw/1024.0/1024 : bw/1024.0)),
(bw > 1024*1024*1024 ? "GB/s" : (bw > 1024*1024 ? "MB/s" : "KB/s")) (bw > 1024*1024*1024 ? "GB/s" : (bw > 1024*1024 ? "MB/s" : "KB/s"))
); );
} }
else else
{ {
printf("[OSD %ju] avg latency for op %d (%s): %ju us\n", osd_num, i, osd_op_names[i], avg); printf("[OSD %lu] avg latency for op %d (%s): %lu us\n", osd_num, i, osd_op_names[i], avg);
} }
prev_stats.op_stat_count[i] = msgr.stats.op_stat_count[i]; prev_stats.op_stat_count[i] = msgr.stats.op_stat_count[i];
prev_stats.op_stat_sum[i] = msgr.stats.op_stat_sum[i]; prev_stats.op_stat_sum[i] = msgr.stats.op_stat_sum[i];
@@ -494,7 +491,7 @@ void osd_t::print_stats()
if (msgr.stats.subop_stat_count[i] != prev_stats.subop_stat_count[i]) if (msgr.stats.subop_stat_count[i] != prev_stats.subop_stat_count[i])
{ {
uint64_t avg = (msgr.stats.subop_stat_sum[i] - prev_stats.subop_stat_sum[i])/(msgr.stats.subop_stat_count[i] - prev_stats.subop_stat_count[i]); uint64_t avg = (msgr.stats.subop_stat_sum[i] - prev_stats.subop_stat_sum[i])/(msgr.stats.subop_stat_count[i] - prev_stats.subop_stat_count[i]);
printf("[OSD %ju] avg latency for subop %d (%s): %jd us\n", osd_num, i, osd_op_names[i], avg); printf("[OSD %lu] avg latency for subop %d (%s): %ld us\n", osd_num, i, osd_op_names[i], avg);
prev_stats.subop_stat_count[i] = msgr.stats.subop_stat_count[i]; prev_stats.subop_stat_count[i] = msgr.stats.subop_stat_count[i];
prev_stats.subop_stat_sum[i] = msgr.stats.subop_stat_sum[i]; prev_stats.subop_stat_sum[i] = msgr.stats.subop_stat_sum[i];
} }
@@ -505,7 +502,7 @@ void osd_t::print_stats()
{ {
uint64_t bw = (recovery_stat[i].bytes - recovery_print_prev[i].bytes) / print_stats_interval; uint64_t bw = (recovery_stat[i].bytes - recovery_print_prev[i].bytes) / print_stats_interval;
printf( printf(
"[OSD %ju] %s recovery: %.1f op/s, B/W: %.2f %s, avg latency %jd us, delay %jd us\n", osd_num, recovery_stat_names[i], "[OSD %lu] %s recovery: %.1f op/s, B/W: %.2f %s, avg latency %ld us, delay %ld us\n", osd_num, recovery_stat_names[i],
(recovery_stat[i].count - recovery_print_prev[i].count) * 1.0 / print_stats_interval, (recovery_stat[i].count - recovery_print_prev[i].count) * 1.0 / print_stats_interval,
(bw > 1024*1024*1024 ? bw/1024.0/1024/1024 : (bw > 1024*1024 ? bw/1024.0/1024 : bw/1024.0)), (bw > 1024*1024*1024 ? bw/1024.0/1024/1024 : (bw > 1024*1024 ? bw/1024.0/1024 : bw/1024.0)),
(bw > 1024*1024*1024 ? "GB/s" : (bw > 1024*1024 ? "MB/s" : "KB/s")), (bw > 1024*1024*1024 ? "GB/s" : (bw > 1024*1024 ? "MB/s" : "KB/s")),
@@ -517,19 +514,19 @@ void osd_t::print_stats()
memcpy(recovery_print_prev, recovery_stat, sizeof(recovery_stat)); memcpy(recovery_print_prev, recovery_stat, sizeof(recovery_stat));
if (corrupted_objects > 0) if (corrupted_objects > 0)
{ {
printf("[OSD %ju] %ju object(s) corrupted\n", osd_num, corrupted_objects); printf("[OSD %lu] %lu object(s) corrupted\n", osd_num, corrupted_objects);
} }
if (incomplete_objects > 0) if (incomplete_objects > 0)
{ {
printf("[OSD %ju] %ju object(s) incomplete\n", osd_num, incomplete_objects); printf("[OSD %lu] %lu object(s) incomplete\n", osd_num, incomplete_objects);
} }
if (degraded_objects > 0) if (degraded_objects > 0)
{ {
printf("[OSD %ju] %ju object(s) degraded\n", osd_num, degraded_objects); printf("[OSD %lu] %lu object(s) degraded\n", osd_num, degraded_objects);
} }
if (misplaced_objects > 0) if (misplaced_objects > 0)
{ {
printf("[OSD %ju] %ju object(s) misplaced\n", osd_num, misplaced_objects); printf("[OSD %lu] %lu object(s) misplaced\n", osd_num, misplaced_objects);
} }
} }
@@ -548,27 +545,27 @@ void osd_t::print_slow()
int l = sizeof(alloc), n; int l = sizeof(alloc), n;
char *buf = alloc; char *buf = alloc;
#define bufprintf(s, ...) { n = snprintf(buf, l, s, __VA_ARGS__); n = n < 0 ? 0 : n; buf += n; l -= n; } #define bufprintf(s, ...) { n = snprintf(buf, l, s, __VA_ARGS__); n = n < 0 ? 0 : n; buf += n; l -= n; }
bufprintf("[OSD %ju] Slow op %jx", osd_num, (uint64_t)op); bufprintf("[OSD %lu] Slow op %lx", osd_num, (unsigned long)op);
if (kv.second->osd_num) if (kv.second->osd_num)
{ {
bufprintf(" from peer OSD %ju (client %d)", kv.second->osd_num, kv.second->peer_fd); bufprintf(" from peer OSD %lu (client %d)", kv.second->osd_num, kv.second->peer_fd);
} }
else else
{ {
bufprintf(" from client %d", kv.second->peer_fd); bufprintf(" from client %d", kv.second->peer_fd);
} }
bufprintf(": %s id=%ju", osd_op_names[op->req.hdr.opcode], op->req.hdr.id); bufprintf(": %s id=%lu", osd_op_names[op->req.hdr.opcode], op->req.hdr.id);
if (op->req.hdr.opcode == OSD_OP_SEC_READ || op->req.hdr.opcode == OSD_OP_SEC_WRITE || if (op->req.hdr.opcode == OSD_OP_SEC_READ || op->req.hdr.opcode == OSD_OP_SEC_WRITE ||
op->req.hdr.opcode == OSD_OP_SEC_WRITE_STABLE || op->req.hdr.opcode == OSD_OP_SEC_DELETE) op->req.hdr.opcode == OSD_OP_SEC_WRITE_STABLE || op->req.hdr.opcode == OSD_OP_SEC_DELETE)
{ {
bufprintf(" %jx:%jx v", op->req.sec_rw.oid.inode, op->req.sec_rw.oid.stripe); bufprintf(" %lx:%lx v", op->req.sec_rw.oid.inode, op->req.sec_rw.oid.stripe);
if (op->req.sec_rw.version == UINT64_MAX) if (op->req.sec_rw.version == UINT64_MAX)
{ {
bufprintf("%s", "max"); bufprintf("%s", "max");
} }
else else
{ {
bufprintf("%ju", op->req.sec_rw.version); bufprintf("%lu", op->req.sec_rw.version);
} }
if (op->req.hdr.opcode != OSD_OP_SEC_DELETE) if (op->req.hdr.opcode != OSD_OP_SEC_DELETE)
{ {
@@ -580,17 +577,17 @@ void osd_t::print_slow()
for (uint64_t i = 0; i < op->req.sec_stab.len && i < sizeof(obj_ver_id)*12; i += sizeof(obj_ver_id)) for (uint64_t i = 0; i < op->req.sec_stab.len && i < sizeof(obj_ver_id)*12; i += sizeof(obj_ver_id))
{ {
obj_ver_id *ov = (obj_ver_id*)((uint8_t*)op->buf + i); obj_ver_id *ov = (obj_ver_id*)((uint8_t*)op->buf + i);
bufprintf(i == 0 ? " %jx:%jx v%ju" : ", %jx:%jx v%ju", ov->oid.inode, ov->oid.stripe, ov->version); bufprintf(i == 0 ? " %lx:%lx v%lu" : ", %lx:%lx v%lu", ov->oid.inode, ov->oid.stripe, ov->version);
} }
if (op->req.sec_stab.len > sizeof(obj_ver_id)*12) if (op->req.sec_stab.len > sizeof(obj_ver_id)*12)
{ {
bufprintf(", ... (%ju items)", op->req.sec_stab.len/sizeof(obj_ver_id)); bufprintf(", ... (%lu items)", op->req.sec_stab.len/sizeof(obj_ver_id));
} }
} }
else if (op->req.hdr.opcode == OSD_OP_SEC_LIST) else if (op->req.hdr.opcode == OSD_OP_SEC_LIST)
{ {
bufprintf( bufprintf(
" oid=%jx/%jx-%jx/%jx pg=%u/%u, stripe=%ju, limit=%u", " oid=%lx/%lx-%lx/%lx pg=%u/%u, stripe=%lu, limit=%u",
op->req.sec_list.min_inode, op->req.sec_list.min_stripe, op->req.sec_list.min_inode, op->req.sec_list.min_stripe,
op->req.sec_list.max_inode, op->req.sec_list.max_stripe, op->req.sec_list.max_inode, op->req.sec_list.max_stripe,
op->req.sec_list.list_pg, op->req.sec_list.pg_count, op->req.sec_list.list_pg, op->req.sec_list.pg_count,
@@ -600,7 +597,7 @@ void osd_t::print_slow()
else if (op->req.hdr.opcode == OSD_OP_READ || op->req.hdr.opcode == OSD_OP_WRITE || else if (op->req.hdr.opcode == OSD_OP_READ || op->req.hdr.opcode == OSD_OP_WRITE ||
op->req.hdr.opcode == OSD_OP_DELETE) op->req.hdr.opcode == OSD_OP_DELETE)
{ {
bufprintf(" inode=%jx offset=%jx len=%x", op->req.rw.inode, op->req.rw.offset, op->req.rw.len); bufprintf(" inode=%lx offset=%lx len=%x", op->req.rw.inode, op->req.rw.offset, op->req.rw.len);
} }
if (op->req.hdr.opcode == OSD_OP_SEC_READ || op->req.hdr.opcode == OSD_OP_SEC_WRITE || if (op->req.hdr.opcode == OSD_OP_SEC_READ || op->req.hdr.opcode == OSD_OP_SEC_WRITE ||
op->req.hdr.opcode == OSD_OP_SEC_WRITE_STABLE || op->req.hdr.opcode == OSD_OP_SEC_DELETE || op->req.hdr.opcode == OSD_OP_SEC_WRITE_STABLE || op->req.hdr.opcode == OSD_OP_SEC_DELETE ||
@@ -612,7 +609,7 @@ void osd_t::print_slow()
int wait_for = op->bs_op ? PRIV(op->bs_op)->wait_for : 0; int wait_for = op->bs_op ? PRIV(op->bs_op)->wait_for : 0;
if (wait_for) if (wait_for)
{ {
bufprintf(" wait=%d (detail=%ju)", wait_for, PRIV(op->bs_op)->wait_detail); bufprintf(" wait=%d (detail=%lu)", wait_for, PRIV(op->bs_op)->wait_detail);
} }
} }
else if (op->req.hdr.opcode == OSD_OP_READ || op->req.hdr.opcode == OSD_OP_WRITE || else if (op->req.hdr.opcode == OSD_OP_READ || op->req.hdr.opcode == OSD_OP_WRITE ||
-2
View File
@@ -125,7 +125,6 @@ class osd_t
int recovery_tune_interval = 1; int recovery_tune_interval = 1;
int recovery_tune_agg_interval = 10; int recovery_tune_agg_interval = 10;
int recovery_tune_sleep_min_us = 10; int recovery_tune_sleep_min_us = 10;
int recovery_tune_sleep_cutoff_us = 10000000;
int recovery_pg_switch = DEFAULT_RECOVERY_PG_SWITCH; int recovery_pg_switch = DEFAULT_RECOVERY_PG_SWITCH;
int recovery_sync_batch = DEFAULT_RECOVERY_BATCH; int recovery_sync_batch = DEFAULT_RECOVERY_BATCH;
int inode_vanish_time = 60; int inode_vanish_time = 60;
@@ -283,7 +282,6 @@ class osd_t
void exec_sync_stab_all(osd_op_t *cur_op); void exec_sync_stab_all(osd_op_t *cur_op);
void exec_show_config(osd_op_t *cur_op); void exec_show_config(osd_op_t *cur_op);
void exec_secondary(osd_op_t *cur_op); void exec_secondary(osd_op_t *cur_op);
void exec_secondary_real(osd_op_t *cur_op);
void secondary_op_callback(osd_op_t *cur_op); void secondary_op_callback(osd_op_t *cur_op);
// primary ops // primary ops
+22 -24
View File
@@ -117,7 +117,7 @@ bool osd_t::check_peer_config(osd_client_t *cl, json11::Json conf)
conf["immediate_commit"].is_null()) conf["immediate_commit"].is_null())
{ {
printf( printf(
"[OSD %ju] Warning: peer OSD %ju does not report block_size/bitmap_granularity/immediate_commit." "[OSD %lu] Warning: peer OSD %lu does not report block_size/bitmap_granularity/immediate_commit."
" Is it older than 0.6.3?\n", this->osd_num, cl->osd_num " Is it older than 0.6.3?\n", this->osd_num, cl->osd_num
); );
} }
@@ -129,7 +129,7 @@ bool osd_t::check_peer_config(osd_client_t *cl, json11::Json conf)
immediate_commit == IMMEDIATE_SMALL && peer_immediate_commit == IMMEDIATE_NONE) immediate_commit == IMMEDIATE_SMALL && peer_immediate_commit == IMMEDIATE_NONE)
{ {
printf( printf(
"[OSD %ju] My immediate_commit is \"%s\", but peer OSD %ju has \"%s\". We can't work together\n", "[OSD %lu] My immediate_commit is \"%s\", but peer OSD %lu has \"%s\". We can't work together\n",
this->osd_num, immediate_commit == IMMEDIATE_ALL ? "all" : "small", this->osd_num, immediate_commit == IMMEDIATE_ALL ? "all" : "small",
cl->osd_num, conf["immediate_commit"].string_value().c_str() cl->osd_num, conf["immediate_commit"].string_value().c_str()
); );
@@ -138,7 +138,7 @@ bool osd_t::check_peer_config(osd_client_t *cl, json11::Json conf)
else if (conf["block_size"].uint64_value() != (uint64_t)this->bs_block_size) else if (conf["block_size"].uint64_value() != (uint64_t)this->bs_block_size)
{ {
printf( printf(
"[OSD %ju] My block_size is %u, but peer OSD %ju has %ju. We can't work together\n", "[OSD %lu] My block_size is %u, but peer OSD %lu has %lu. We can't work together\n",
this->osd_num, this->bs_block_size, cl->osd_num, conf["block_size"].uint64_value() this->osd_num, this->bs_block_size, cl->osd_num, conf["block_size"].uint64_value()
); );
return false; return false;
@@ -146,7 +146,7 @@ bool osd_t::check_peer_config(osd_client_t *cl, json11::Json conf)
else if (conf["bitmap_granularity"].uint64_value() != (uint64_t)this->bs_bitmap_granularity) else if (conf["bitmap_granularity"].uint64_value() != (uint64_t)this->bs_bitmap_granularity)
{ {
printf( printf(
"[OSD %ju] My bitmap_granularity is %u, but peer OSD %ju has %ju. We can't work together\n", "[OSD %lu] My bitmap_granularity is %u, but peer OSD %lu has %lu. We can't work together\n",
this->osd_num, this->bs_bitmap_granularity, cl->osd_num, conf["bitmap_granularity"].uint64_value() this->osd_num, this->bs_bitmap_granularity, cl->osd_num, conf["bitmap_granularity"].uint64_value()
); );
return false; return false;
@@ -181,7 +181,7 @@ json11::Json osd_t::get_statistics()
timespec ts; timespec ts;
clock_gettime(CLOCK_REALTIME, &ts); clock_gettime(CLOCK_REALTIME, &ts);
char time_str[50] = { 0 }; char time_str[50] = { 0 };
sprintf(time_str, "%jd.%03ld", (uint64_t)ts.tv_sec, ts.tv_nsec/1000000); sprintf(time_str, "%ld.%03ld", ts.tv_sec, ts.tv_nsec/1000000);
st["time"] = time_str; st["time"] = time_str;
if (bs) if (bs)
{ {
@@ -262,8 +262,7 @@ void osd_t::report_statistics()
for (auto st_it = inode_stats.begin(); st_it != inode_stats.end(); ) for (auto st_it = inode_stats.begin(); st_it != inode_stats.end(); )
{ {
auto & kv = *st_it; auto & kv = *st_it;
auto spc_it = bs_inode_space.find(kv.first); if (!bs_inode_space[kv.first])
if (spc_it == bs_inode_space.end() || !spc_it->second) // prevent autovivification
{ {
// Is it an empty inode? // Is it an empty inode?
if (!tv_now.tv_sec) if (!tv_now.tv_sec)
@@ -358,7 +357,7 @@ void osd_t::report_statistics()
etcd_reporting_stats = false; etcd_reporting_stats = false;
if (err != "") if (err != "")
{ {
printf("[OSD %ju] Error reporting state to etcd: %s\n", this->osd_num, err.c_str()); printf("[OSD %lu] Error reporting state to etcd: %s\n", this->osd_num, err.c_str());
// Retry indefinitely // Retry indefinitely
tfd->set_timer(st_cli.etcd_slow_timeout, false, [this](int timer_id) tfd->set_timer(st_cli.etcd_slow_timeout, false, [this](int timer_id)
{ {
@@ -367,7 +366,7 @@ void osd_t::report_statistics()
} }
else if (res["error"].string_value() != "") else if (res["error"].string_value() != "")
{ {
printf("[OSD %ju] Error reporting state to etcd: %s\n", this->osd_num, res["error"].string_value().c_str()); printf("[OSD %lu] Error reporting state to etcd: %s\n", this->osd_num, res["error"].string_value().c_str());
force_stop(1); force_stop(1);
} }
}); });
@@ -432,7 +431,7 @@ void osd_t::acquire_lease()
create_osd_state(); create_osd_state();
}); });
printf( printf(
"[OSD %ju] reporting to etcd at %s every %d seconds (statistics every %d seconds)\n", this->osd_num, "[OSD %lu] reporting to etcd at %s every %d seconds (statistics every %d seconds)\n", this->osd_num,
(config["etcd_address"].is_string() ? config["etcd_address"].string_value() : config["etcd_address"].dump()).c_str(), (config["etcd_address"].is_string() ? config["etcd_address"].string_value() : config["etcd_address"].dump()).c_str(),
etcd_report_interval, etcd_stats_interval etcd_report_interval, etcd_stats_interval
); );
@@ -499,11 +498,11 @@ void osd_t::create_osd_state()
{ {
// OSD is already up // OSD is already up
auto kv = st_cli.parse_etcd_kv(data["responses"][0]["response_range"]["kvs"][0]); auto kv = st_cli.parse_etcd_kv(data["responses"][0]["response_range"]["kvs"][0]);
printf("Key %s already exists in etcd, OSD %ju is still up\n", kv.key.c_str(), this->osd_num); printf("Key %s already exists in etcd, OSD %lu is still up\n", kv.key.c_str(), this->osd_num);
int64_t port = kv.value["port"].int64_value(); int64_t port = kv.value["port"].int64_value();
for (auto & addr: kv.value["addresses"].array_items()) for (auto & addr: kv.value["addresses"].array_items())
{ {
printf(" listening at: %s:%jd\n", addr.string_value().c_str(), port); printf(" listening at: %s:%ld\n", addr.string_value().c_str(), port);
} }
force_stop(0); force_stop(0);
return; return;
@@ -569,13 +568,13 @@ void osd_t::force_stop(int exitcode)
{ {
printf("Error revoking etcd lease: %s\n", err.c_str()); printf("Error revoking etcd lease: %s\n", err.c_str());
} }
printf("[OSD %ju] Force stopping\n", this->osd_num); printf("[OSD %lu] Force stopping\n", this->osd_num);
exit(exitcode); exit(exitcode);
}); });
} }
else else
{ {
printf("[OSD %ju] Force stopping\n", this->osd_num); printf("[OSD %lu] Force stopping\n", this->osd_num);
exit(exitcode); exit(exitcode);
} }
} }
@@ -629,7 +628,7 @@ void osd_t::apply_pg_count()
if (still_active > 0) if (still_active > 0)
{ {
printf( printf(
"[OSD %ju] PG count change detected for pool %u (new is %ju, old is %u)," "[OSD %lu] PG count change detected for pool %u (new is %lu, old is %u),"
" but %u PG(s) are still active. This is not allowed. Exiting\n", " but %u PG(s) are still active. This is not allowed. Exiting\n",
this->osd_num, pool_item.first, pool_item.second.real_pg_count, pg_counts[pool_item.first], still_active this->osd_num, pool_item.first, pool_item.second.real_pg_count, pg_counts[pool_item.first], still_active
); );
@@ -663,7 +662,7 @@ void osd_t::apply_pg_config()
if (!warned_block_size) if (!warned_block_size)
{ {
printf( printf(
"[OSD %ju] My block_size and bitmap_granularity are %u/%u" "[OSD %lu] My block_size and bitmap_granularity are %u/%u"
", but pool %u has %u/%u. Refusing to start PGs of this pool\n", ", but pool %u has %u/%u. Refusing to start PGs of this pool\n",
this->osd_num, bs_block_size, bs_bitmap_granularity, this->osd_num, bs_block_size, bs_bitmap_granularity,
pool_id, pool_item.second.data_block_size, pool_item.second.bitmap_granularity pool_id, pool_item.second.data_block_size, pool_item.second.bitmap_granularity
@@ -843,13 +842,7 @@ void osd_t::report_pg_states()
pg_state_exists = true; pg_state_exists = true;
if (pg.state == PG_OFFLINE && pg_it->second.cur_primary != this->osd_num) if (pg.state == PG_OFFLINE && pg_it->second.cur_primary != this->osd_num)
{ {
// Nothing to report, PG is already taken over by another OSD // Nothing to check or report, PG is already taken over by another OSD
checks.push_back(json11::Json::object {
{ "target", "MOD" },
{ "key", state_key_base64 },
{ "result", "LESS" },
{ "mod_revision", st_cli.etcd_watch_revision+1 },
});
continue; continue;
} }
} }
@@ -857,6 +850,11 @@ void osd_t::report_pg_states()
} }
if (!pg_state_exists) if (!pg_state_exists)
{ {
if (pg.state == PG_OFFLINE)
{
// Nothing to check or report, PG is already stopped
continue;
}
// Check that the PG key does not exist // Check that the PG key does not exist
// Failed check indicates an unsuccessful PG lock attempt in this case // Failed check indicates an unsuccessful PG lock attempt in this case
checks.push_back(json11::Json::object { checks.push_back(json11::Json::object {
@@ -985,7 +983,7 @@ void osd_t::report_pg_states()
kv.value["primary"].uint64_value() != this->osd_num) kv.value["primary"].uint64_value() != this->osd_num)
{ {
// PG is somehow captured by another OSD // PG is somehow captured by another OSD
printf("BUG: OSD %ju captured our PG %u/%u. Race condition detected, exiting\n", printf("BUG: OSD %lu captured our PG %u/%u. Race condition detected, exiting\n",
kv.value["primary"].uint64_value(), pool_id, pg_num); kv.value["primary"].uint64_value(), pool_id, pg_num);
force_stop(1); force_stop(1);
return; return;
+10 -14
View File
@@ -66,7 +66,7 @@ void osd_t::handle_flush_op(bool rollback, pool_id_t pool_id, pg_num_t pg_num, p
{ {
if (log_level > 2) if (log_level > 2)
{ {
printf("[PG %u/%u] flush batch %jx completed on OSD %ju with result %d\n", printf("[PG %u/%u] flush batch %lx completed on OSD %lu with result %d\n",
pool_id, pg_num, (uint64_t)fb, peer_osd, retval); pool_id, pg_num, (uint64_t)fb, peer_osd, retval);
} }
pool_pg_num_t pg_id = { .pool_id = pool_id, .pg_num = pg_num }; pool_pg_num_t pg_id = { .pool_id = pool_id, .pg_num = pg_num };
@@ -88,7 +88,7 @@ void osd_t::handle_flush_op(bool rollback, pool_id_t pool_id, pg_num_t pg_num, p
} }
else else
{ {
printf("Error while doing flush on OSD %ju: %d (%s)\n", osd_num, retval, strerror(-retval)); printf("Error while doing flush on OSD %lu: %d (%s)\n", osd_num, retval, strerror(-retval));
auto fd_it = msgr.osd_peer_fds.find(peer_osd); auto fd_it = msgr.osd_peer_fds.find(peer_osd);
if (fd_it != msgr.osd_peer_fds.end()) if (fd_it != msgr.osd_peer_fds.end())
{ {
@@ -122,7 +122,7 @@ void osd_t::handle_flush_op(bool rollback, pool_id_t pool_id, pg_num_t pg_num, p
{ {
if (log_level > 2) if (log_level > 2)
{ {
printf("[PG %u/%u] continuing write %jx to object %jx:%jx after flush\n", printf("[PG %u/%u] continuing write %lx to object %lx:%lx after flush\n",
pool_id, pg_num, (uint64_t)wr_it->second, wr_it->first.inode, wr_it->first.stripe); pool_id, pg_num, (uint64_t)wr_it->second, wr_it->first.inode, wr_it->first.stripe);
} }
continue_ops.push_back(wr_it->second); continue_ops.push_back(wr_it->second);
@@ -169,12 +169,12 @@ bool osd_t::submit_flush_op(pool_id_t pool_id, pg_num_t pg_num, pg_flush_batch_t
if (log_level > 2) if (log_level > 2)
{ {
printf( printf(
"[PG %u/%u] flush batch %jx on OSD %ju: %s objects: ", "[PG %u/%u] flush batch %lx on OSD %lu: %s objects: ",
pool_id, pg_num, (uint64_t)fb, peer_osd, rollback ? "rollback" : "stabilize" pool_id, pg_num, (uint64_t)fb, peer_osd, rollback ? "rollback" : "stabilize"
); );
for (int i = 0; i < count; i++) for (int i = 0; i < count; i++)
{ {
printf(i > 0 ? ", %jx:%jx v%ju" : "%jx:%jx v%ju", data[i].oid.inode, data[i].oid.stripe, data[i].version); printf(i > 0 ? ", %lx:%lx v%lu" : "%lx:%lx v%lu", data[i].oid.inode, data[i].oid.stripe, data[i].version);
} }
printf("\n"); printf("\n");
} }
@@ -305,7 +305,7 @@ void osd_t::submit_recovery_op(osd_recovery_op_t *op)
}; };
if (log_level > 2) if (log_level > 2)
{ {
printf("Submitting recovery operation for %jx:%jx (%s)\n", op->oid.inode, op->oid.stripe, op->degraded ? "degraded" : "misplaced"); printf("Submitting recovery operation for %lx:%lx (%s)\n", op->oid.inode, op->oid.stripe, op->degraded ? "degraded" : "misplaced");
} }
op->osd_op->peer_fd = -1; op->osd_op->peer_fd = -1;
op->osd_op->callback = [this, op](osd_op_t *osd_op) op->osd_op->callback = [this, op](osd_op_t *osd_op)
@@ -315,7 +315,7 @@ void osd_t::submit_recovery_op(osd_recovery_op_t *op)
// Error recovering object // Error recovering object
// EPIPE is totally harmless (peer is gone), others like EIO/EDOM may be not // EPIPE is totally harmless (peer is gone), others like EIO/EDOM may be not
printf( printf(
"[PG %u/%u] Recovery operation failed with object %jx:%jx: error %jd\n", "[PG %u/%u] Recovery operation failed with object %lx:%lx: error %ld\n",
INODE_POOL(op->oid.inode), INODE_POOL(op->oid.inode),
map_to_pg(op->oid, st_cli.pool_config.at(INODE_POOL(op->oid.inode)).pg_stripe_size), map_to_pg(op->oid, st_cli.pool_config.at(INODE_POOL(op->oid.inode)).pg_stripe_size),
op->oid.inode, op->oid.stripe, osd_op->reply.hdr.retval op->oid.inode, op->oid.stripe, osd_op->reply.hdr.retval
@@ -323,7 +323,7 @@ void osd_t::submit_recovery_op(osd_recovery_op_t *op)
} }
else if (log_level > 2) else if (log_level > 2)
{ {
printf("Recovery operation done for %jx:%jx\n", op->oid.inode, op->oid.stripe); printf("Recovery operation done for %lx:%lx\n", op->oid.inode, op->oid.stripe);
} }
finish_recovery_op(op); finish_recovery_op(op);
}; };
@@ -422,10 +422,6 @@ void osd_t::tune_recovery()
rtune_avg_lat = total_recovery_usec/recovery_count; rtune_avg_lat = total_recovery_usec/recovery_count;
uint64_t target_lat = rtune_avg_lat * rtune_avg_lat/1000000.0 * recovery_count/recovery_tune_interval / rtune_target_util; uint64_t target_lat = rtune_avg_lat * rtune_avg_lat/1000000.0 * recovery_count/recovery_tune_interval / rtune_target_util;
auto sleep_us = target_lat > rtune_avg_lat+recovery_tune_sleep_min_us ? target_lat-rtune_avg_lat : 0; auto sleep_us = target_lat > rtune_avg_lat+recovery_tune_sleep_min_us ? target_lat-rtune_avg_lat : 0;
if (sleep_us > recovery_tune_sleep_cutoff_us)
{
return;
}
if (recovery_target_sleep_items.size() != recovery_tune_agg_interval) if (recovery_target_sleep_items.size() != recovery_tune_agg_interval)
{ {
recovery_target_sleep_items.resize(recovery_tune_agg_interval); recovery_target_sleep_items.resize(recovery_tune_agg_interval);
@@ -442,10 +438,10 @@ void osd_t::tune_recovery()
if (recovery_target_sleep_count < recovery_tune_agg_interval) if (recovery_target_sleep_count < recovery_tune_agg_interval)
recovery_target_sleep_count++; recovery_target_sleep_count++;
recovery_target_sleep_us = recovery_target_sleep_total / recovery_target_sleep_count; recovery_target_sleep_us = recovery_target_sleep_total / recovery_target_sleep_count;
if (log_level > 1) if (log_level > 4)
{ {
printf( printf(
"[OSD %ju] auto-tune: client util: %.2f, recovery util: %.2f, lat: %ju us -> target util %.2f, delay %ju us\n", "[OSD %lu] auto-tune: client util: %.2f, recovery util: %.2f, lat: %lu us -> target util %.2f, delay %lu us\n",
osd_num, rtune_client_util, total_recovery_usec/1000000.0/recovery_tune_interval, osd_num, rtune_client_util, total_recovery_usec/1000000.0/recovery_tune_interval,
rtune_avg_lat, rtune_target_util, recovery_target_sleep_us rtune_avg_lat, rtune_target_util, recovery_target_sleep_us
); );
+4 -7
View File
@@ -113,7 +113,7 @@ void osd_t::repeer_pgs(osd_num_t peer_osd)
if (repeer) if (repeer)
{ {
// Repeer this pg // Repeer this pg
printf("[PG %u/%u] Repeer because of OSD %ju\n", pg.pool_id, pg.pg_num, peer_osd); printf("[PG %u/%u] Repeer because of OSD %lu\n", pg.pool_id, pg.pg_num, peer_osd);
if (!(pg.state & (PG_ACTIVE | PG_REPEERING)) || pg.inflight == 0 && !pg.flush_batch) if (!(pg.state & (PG_ACTIVE | PG_REPEERING)) || pg.inflight == 0 && !pg.flush_batch)
{ {
start_pg_peering(pg); start_pg_peering(pg);
@@ -222,9 +222,6 @@ void osd_t::start_pg_peering(pg_t & pg)
} }
if (pg.pg_cursize < pg.pg_minsize) if (pg.pg_cursize < pg.pg_minsize)
{ {
// FIXME: Incomplete EC PGs may currently easily lead to write hangs ("slow ops" in OSD logs)
// because such PGs don't flush unstable entries on secondary OSDs so they can't remove these
// entries from their journals...
pg.state = PG_INCOMPLETE; pg.state = PG_INCOMPLETE;
report_pg_state(pg); report_pg_state(pg);
return; return;
@@ -347,7 +344,7 @@ void osd_t::submit_list_subop(osd_num_t role_osd, pg_peering_state_t *ps)
} }
add_bs_subop_stats(op); add_bs_subop_stats(op);
printf( printf(
"[PG %u/%u] Got object list from OSD %ju (local): %d object versions (%ju of them stable)\n", "[PG %u/%u] Got object list from OSD %lu (local): %d object versions (%lu of them stable)\n",
ps->pool_id, ps->pg_num, role_osd, bs_op->retval, bs_op->version ps->pool_id, ps->pg_num, role_osd, bs_op->retval, bs_op->version
); );
ps->list_results[role_osd] = { ps->list_results[role_osd] = {
@@ -387,7 +384,7 @@ void osd_t::submit_list_subop(osd_num_t role_osd, pg_peering_state_t *ps)
{ {
if (op->reply.hdr.retval < 0) if (op->reply.hdr.retval < 0)
{ {
printf("Failed to get object list from OSD %ju (retval=%jd), disconnecting peer\n", role_osd, op->reply.hdr.retval); printf("Failed to get object list from OSD %lu (retval=%ld), disconnecting peer\n", role_osd, op->reply.hdr.retval);
int fail_fd = op->peer_fd; int fail_fd = op->peer_fd;
ps->list_ops.erase(role_osd); ps->list_ops.erase(role_osd);
delete op; delete op;
@@ -395,7 +392,7 @@ void osd_t::submit_list_subop(osd_num_t role_osd, pg_peering_state_t *ps)
return; return;
} }
printf( printf(
"[PG %u/%u] Got object list from OSD %ju: %jd object versions (%ju of them stable)\n", "[PG %u/%u] Got object list from OSD %lu: %ld object versions (%lu of them stable)\n",
ps->pool_id, ps->pg_num, role_osd, op->reply.hdr.retval, op->reply.sec_list.stable_count ps->pool_id, ps->pg_num, role_osd, op->reply.hdr.retval, op->reply.sec_list.stable_count
); );
ps->list_results[role_osd] = { ps->list_results[role_osd] = {

Some files were not shown because too many files have changed in this diff Show More