Compare commits
261 Commits
v0.7.0
...
hier-failu
Author | SHA1 | Date | |
---|---|---|---|
72f0cff79d | |||
c1d470522c | |||
57feb7f390 | |||
431f780347 | |||
98077a1712 | |||
1c7d53996d | |||
2ca07b1ea7 | |||
022176aa98 | |||
120e3fa7bc | |||
629999f789 | |||
93eca11ba2 | |||
5a9e1ede52 | |||
1c9a188600 | |||
de3e609166 | |||
11481170f5 | |||
e69d459d43 | |||
da82754baa | |||
d356aca030 | |||
04a273d213 | |||
6442010f93 | |||
6f4dc16c59 | |||
ce4a8067b5 | |||
e431ecb715 | |||
8cac795445 | |||
a409598b16 | |||
f4c6765522 | |||
ad2916068a | |||
321cb435a6 | |||
cfcf4f4355 | |||
e0fb17bfee | |||
5b9031fecc | |||
5da1d8e1b5 | |||
44f86f1999 | |||
2d9a80c6f6 | |||
5e295e346e | |||
d9c0898b7c | |||
04cfb48361 | |||
ab615849d6 | |||
38be9a49c0 | |||
7d6bf84a3e | |||
41a40a4123 | |||
b94587ef0e | |||
2a2f4f6738 | |||
c768a9015f | |||
0d9e10cf96 | |||
b74ccb613c | |||
5052174918 | |||
eec9cf5575 | |||
a04dab0840 | |||
160863f707 | |||
2f16c32eb4 | |||
2877cd0adb | |||
480509f5b9 | |||
46462da45e | |||
024c8658f6 | |||
7e958afeda | |||
2f5e769a29 | |||
28d5e53c6c | |||
d9f55f11d8 | |||
3237014608 | |||
baaf8f6f44 | |||
1d83fdcd17 | |||
0ddd787c38 | |||
6eff3a60a5 | |||
888a6975ab | |||
cd1e890bd4 | |||
0fbf4c6a08 | |||
d06ed2b0e7 | |||
3bbc46543d | |||
2fb0c85618 | |||
d81a6c04fc | |||
7b35801647 | |||
f3228d5c07 | |||
18366f5055 | |||
851507c147 | |||
9aaad28488 | |||
dd57d086fe | |||
8810eae8fb | |||
c1365f46c9 | |||
14d6acbcba | |||
1e307069bc | |||
c3e80abad7 | |||
138ffe4032 | |||
8139a34e97 | |||
4ab630b44d | |||
2c8241b7db | |||
36a7dd3671 | |||
936122bbcf | |||
1a1ba0d1e7 | |||
3d09c9cec7 | |||
3d08a1ad6c | |||
499881d81c | |||
aba93b951b | |||
d125fb1f30 | |||
9d3fd72298 | |||
8b552a01f9 | |||
0385b2f9e8 | |||
749c837045 | |||
98001d845b | |||
c96bcae74b | |||
9f4e34a8cc | |||
81fc8bb94c | |||
bc465c16de | |||
8763e9211c | |||
9e1a80bd17 | |||
3e280f2f08 | |||
fe87b4076b | |||
a38957c1a7 | |||
137309cf29 | |||
373f9d0387 | |||
c4516ea971 | |||
91065c80fc | |||
0f6b946add | |||
465cbf0b2f | |||
41add50e4e | |||
02e7be7dc9 | |||
73940adf07 | |||
e950c024d3 | |||
71d6d9f868 | |||
a4dfa519af | |||
37a6aff2fa | |||
67019f5b02 | |||
0593e5c21c | |||
998e24adf8 | |||
d7bd36dc32 | |||
cf5c562800 | |||
629200b0cc | |||
3589ccec22 | |||
8d55a1e780 | |||
65f6b3a4eb | |||
fd216eac77 | |||
61fca7c426 | |||
1c29ed80b9 | |||
68f3fb795e | |||
fa90f287da | |||
795020674d | |||
8e12285629 | |||
b9b50ab4cc | |||
0d8625f92d | |||
2f3c2c5140 | |||
4ebdd02b0f | |||
bf6fdc4141 | |||
c2244331e6 | |||
3de57e87b1 | |||
2d4cc688b2 | |||
31bd1ec145 | |||
c08d1f2dfe | |||
1d80bcc8d0 | |||
5ef8bed75f | |||
8669998e5e | |||
b457327e77 | |||
f7fa9d5e34 | |||
49b88b01f9 | |||
71688bcb59 | |||
552e207d2b | |||
5464821fa5 | |||
6917a32ca8 | |||
f8722a8bd5 | |||
9c2f69c9fa | |||
1a93e3f33a | |||
3f35744052 | |||
66f14ac019 | |||
1364009931 | |||
d7e30b8353 | |||
cb437913d3 | |||
472bce58ab | |||
7a71e7ef01 | |||
c71e5e7bbd | |||
8fdf30b21f | |||
238037ae31 | |||
09a8864686 | |||
6e6f6ecbb0 | |||
9491f81419 | |||
44c2b30167 | |||
bf8a0581cd | |||
5953942042 | |||
a276a1f737 | |||
cc24e5796e | |||
6e26732e6a | |||
b4edc79449 | |||
5f26887d32 | |||
11ec9ad874 | |||
83bb6598dc | |||
150f369346 | |||
8d9a5fde15 | |||
9ccc607ab9 | |||
8972878c77 | |||
2a1da88253 | |||
2f13f347b0 | |||
9453db0e99 | |||
a828a1233d | |||
9481456dfe | |||
bd11db5d0a | |||
68ebe5993a | |||
eecbfb66ce | |||
a537db8909 | |||
54ef2c389f | |||
153c73574a | |||
d83580bd68 | |||
29b40aba93 | |||
a52f2b0e8f | |||
1407db9c08 | |||
c0d5e83fb8 | |||
40d8d65188 | |||
a16263e88c | |||
e62bab1b39 | |||
cb4e3a118d | |||
b1e39b5dea | |||
1170319431 | |||
2e0a2221eb | |||
5a10d135f3 | |||
4c9aaa8a86 | |||
ae99ee6266 | |||
5af75f7d78 | |||
7dc6f10ea1 | |||
6fde9950d6 | |||
76dd0fdcea | |||
5acc19bbd5 | |||
d5ca4e1f90 | |||
67e04f789f | |||
837407a84c | |||
1fe5908899 | |||
dcc6d546be | |||
85fa389557 | |||
dfa433c63b | |||
cf487c95aa | |||
b10656ca09 | |||
ea632367e9 | |||
4d777c6729 | |||
0c404c5074 | |||
dfd80626bd | |||
30907852c2 | |||
078ed5b116 | |||
73a363bf92 | |||
b0e86ca643 | |||
8800afb649 | |||
c10c90f620 | |||
e20cdd13b6 | |||
d29b5d2d04 | |||
65b0e8e940 | |||
bce357e2a5 | |||
0876ca09cd | |||
dac12d8a4c | |||
1eec4407ab | |||
![]() |
3b7c6dcac2 | ||
342517d126 | |||
675bc12a13 | |||
101592bbff | |||
be4087d9d2 | |||
404e43dd2d | |||
87613ed590 | |||
2a2e914ef9 | |||
0cdc9292c8 | |||
3e1b03bb5c | |||
36e851505a | |||
1efbbb0c36 | |||
088dd15449 | |||
4a531d7b8b | |||
a0cae4c180 | |||
c4eb46600d | |||
21b306e25f |
36
.gitea/workflows/buildenv.Dockerfile
Normal file
36
.gitea/workflows/buildenv.Dockerfile
Normal file
@@ -0,0 +1,36 @@
|
|||||||
|
FROM node:16-bullseye
|
||||||
|
|
||||||
|
WORKDIR /root
|
||||||
|
|
||||||
|
ADD ./docker/vitastor.gpg /etc/apt/trusted.gpg.d
|
||||||
|
|
||||||
|
RUN echo 'deb http://deb.debian.org/debian bullseye-backports main' >> /etc/apt/sources.list; \
|
||||||
|
echo 'deb http://vitastor.io/debian bullseye main' >> /etc/apt/sources.list; \
|
||||||
|
echo >> /etc/apt/preferences; \
|
||||||
|
echo 'Package: *' >> /etc/apt/preferences; \
|
||||||
|
echo 'Pin: release a=bullseye-backports' >> /etc/apt/preferences; \
|
||||||
|
echo 'Pin-Priority: 500' >> /etc/apt/preferences; \
|
||||||
|
echo >> /etc/apt/preferences; \
|
||||||
|
echo 'Package: *' >> /etc/apt/preferences; \
|
||||||
|
echo 'Pin: origin "vitastor.io"' >> /etc/apt/preferences; \
|
||||||
|
echo 'Pin-Priority: 1000' >> /etc/apt/preferences; \
|
||||||
|
grep '^deb ' /etc/apt/sources.list | perl -pe 's/^deb/deb-src/' >> /etc/apt/sources.list; \
|
||||||
|
echo 'APT::Install-Recommends false;' >> /etc/apt/apt.conf; \
|
||||||
|
echo 'APT::Install-Suggests false;' >> /etc/apt/apt.conf
|
||||||
|
|
||||||
|
RUN apt-get update
|
||||||
|
RUN apt-get -y install etcd qemu-system-x86 qemu-block-extra qemu-utils fio libasan5 \
|
||||||
|
liburing1 liburing-dev libgoogle-perftools-dev devscripts libjerasure-dev cmake libibverbs-dev libisal-dev
|
||||||
|
RUN apt-get -y build-dep fio qemu=`dpkg -s qemu-system-x86|grep ^Version:|awk '{print $2}'`
|
||||||
|
RUN apt-get -y install jq lp-solve sudo
|
||||||
|
RUN apt-get --download-only source fio qemu=`dpkg -s qemu-system-x86|grep ^Version:|awk '{print $2}'`
|
||||||
|
|
||||||
|
RUN set -ex; \
|
||||||
|
mkdir qemu-build; \
|
||||||
|
cd qemu-build; \
|
||||||
|
dpkg-source -x /root/qemu*.dsc; \
|
||||||
|
cd qemu*/; \
|
||||||
|
debian/rules configure-qemu || debian/rules b/configure-stamp; \
|
||||||
|
cd b/qemu; \
|
||||||
|
make -j8 config-poison.h || true; \
|
||||||
|
make -j8 qapi/qapi-builtin-types.h
|
16
.gitea/workflows/test.Dockerfile
Normal file
16
.gitea/workflows/test.Dockerfile
Normal file
@@ -0,0 +1,16 @@
|
|||||||
|
FROM git.yourcmc.ru/vitalif/vitastor/buildenv
|
||||||
|
|
||||||
|
ADD . /root/vitastor
|
||||||
|
|
||||||
|
RUN set -e -x; \
|
||||||
|
mkdir -p /root/fio-build/; \
|
||||||
|
cd /root/fio-build/; \
|
||||||
|
dpkg-source -x /root/fio*.dsc; \
|
||||||
|
cd /root/vitastor; \
|
||||||
|
ln -s /root/fio-build/fio-*/ ./fio; \
|
||||||
|
ln -s /root/qemu-build/qemu-*/ ./qemu; \
|
||||||
|
ls /usr/include/linux/raw.h || cp ./debian/raw.h /usr/include/linux/raw.h; \
|
||||||
|
mkdir build; \
|
||||||
|
cd build; \
|
||||||
|
cmake .. -DWITH_ASAN=yes -DWITH_QEMU=yes; \
|
||||||
|
make -j16
|
552
.gitea/workflows/test.yml
Normal file
552
.gitea/workflows/test.yml
Normal file
@@ -0,0 +1,552 @@
|
|||||||
|
name: Test
|
||||||
|
|
||||||
|
on:
|
||||||
|
push:
|
||||||
|
branches:
|
||||||
|
- '*'
|
||||||
|
paths:
|
||||||
|
- '.gitea/**'
|
||||||
|
- 'src/**'
|
||||||
|
- 'mon/**'
|
||||||
|
- 'json11'
|
||||||
|
- 'cpp-btree'
|
||||||
|
- 'tests/**'
|
||||||
|
|
||||||
|
env:
|
||||||
|
BUILDENV_IMAGE: git.yourcmc.ru/vitalif/vitastor/buildenv
|
||||||
|
TEST_IMAGE: git.yourcmc.ru/vitalif/vitastor/test
|
||||||
|
OSD_ARGS: '--etcd_quick_timeout 2000'
|
||||||
|
|
||||||
|
concurrency:
|
||||||
|
group: ci-${{ github.ref }}
|
||||||
|
cancel-in-progress: true
|
||||||
|
|
||||||
|
jobs:
|
||||||
|
|
||||||
|
buildenv:
|
||||||
|
runs-on: ubuntu-latest
|
||||||
|
container: git.yourcmc.ru/vitalif/gitea-ci-dind
|
||||||
|
steps:
|
||||||
|
- uses: actions/checkout@v3
|
||||||
|
|
||||||
|
- name: Build and push
|
||||||
|
run: |
|
||||||
|
set -ex
|
||||||
|
if ! docker manifest inspect $BUILDENV_IMAGE >/dev/null; then
|
||||||
|
docker build -t $BUILDENV_IMAGE -f .gitea/workflows/buildenv.Dockerfile .
|
||||||
|
docker login git.yourcmc.ru -u vitalif -p "${{secrets.TOKEN}}"
|
||||||
|
docker push $BUILDENV_IMAGE
|
||||||
|
fi
|
||||||
|
|
||||||
|
build:
|
||||||
|
runs-on: ubuntu-latest
|
||||||
|
needs: buildenv
|
||||||
|
container: git.yourcmc.ru/vitalif/gitea-ci-dind
|
||||||
|
steps:
|
||||||
|
- uses: actions/checkout@v3
|
||||||
|
with:
|
||||||
|
submodules: true
|
||||||
|
|
||||||
|
- name: Build and push
|
||||||
|
run: |
|
||||||
|
set -ex
|
||||||
|
if ! docker manifest inspect $TEST_IMAGE:$GITHUB_SHA >/dev/null; then
|
||||||
|
docker build -t $TEST_IMAGE:$GITHUB_SHA -f .gitea/workflows/test.Dockerfile .
|
||||||
|
docker login git.yourcmc.ru -u vitalif -p "${{secrets.TOKEN}}"
|
||||||
|
docker push $TEST_IMAGE:$GITHUB_SHA
|
||||||
|
fi
|
||||||
|
|
||||||
|
make_test:
|
||||||
|
runs-on: ubuntu-latest
|
||||||
|
needs: build
|
||||||
|
container: ${{env.TEST_IMAGE}}:${{github.sha}}
|
||||||
|
steps:
|
||||||
|
# leak sanitizer sometimes crashes
|
||||||
|
- run: cd /root/vitastor/build && ASAN_OPTIONS=detect_leaks=0 make -j16 test
|
||||||
|
|
||||||
|
test_add_osd:
|
||||||
|
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_add_osd.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_cas:
|
||||||
|
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_cas.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_change_pg_count:
|
||||||
|
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_change_pg_count.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_change_pg_count_ec:
|
||||||
|
runs-on: ubuntu-latest
|
||||||
|
needs: build
|
||||||
|
container: ${{env.TEST_IMAGE}}:${{github.sha}}
|
||||||
|
steps:
|
||||||
|
- name: Run test
|
||||||
|
id: test
|
||||||
|
timeout-minutes: 3
|
||||||
|
run: SCHEME=ec /root/vitastor/tests/test_change_pg_count.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_change_pg_size:
|
||||||
|
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_change_pg_size.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_create_nomaxid:
|
||||||
|
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_create_nomaxid.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_etcd_fail:
|
||||||
|
runs-on: ubuntu-latest
|
||||||
|
needs: build
|
||||||
|
container: ${{env.TEST_IMAGE}}:${{github.sha}}
|
||||||
|
steps:
|
||||||
|
- name: Run test
|
||||||
|
id: test
|
||||||
|
timeout-minutes: 10
|
||||||
|
run: /root/vitastor/tests/test_etcd_fail.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_failure_domain:
|
||||||
|
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_failure_domain.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_interrupted_rebalance:
|
||||||
|
runs-on: ubuntu-latest
|
||||||
|
needs: build
|
||||||
|
container: ${{env.TEST_IMAGE}}:${{github.sha}}
|
||||||
|
steps:
|
||||||
|
- name: Run test
|
||||||
|
id: test
|
||||||
|
timeout-minutes: 10
|
||||||
|
run: /root/vitastor/tests/test_interrupted_rebalance.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_interrupted_rebalance_imm:
|
||||||
|
runs-on: ubuntu-latest
|
||||||
|
needs: build
|
||||||
|
container: ${{env.TEST_IMAGE}}:${{github.sha}}
|
||||||
|
steps:
|
||||||
|
- name: Run test
|
||||||
|
id: test
|
||||||
|
timeout-minutes: 10
|
||||||
|
run: IMMEDIATE_COMMIT=1 /root/vitastor/tests/test_interrupted_rebalance.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_interrupted_rebalance_ec:
|
||||||
|
runs-on: ubuntu-latest
|
||||||
|
needs: build
|
||||||
|
container: ${{env.TEST_IMAGE}}:${{github.sha}}
|
||||||
|
steps:
|
||||||
|
- name: Run test
|
||||||
|
id: test
|
||||||
|
timeout-minutes: 10
|
||||||
|
run: SCHEME=ec /root/vitastor/tests/test_interrupted_rebalance.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_interrupted_rebalance_ec_imm:
|
||||||
|
runs-on: ubuntu-latest
|
||||||
|
needs: build
|
||||||
|
container: ${{env.TEST_IMAGE}}:${{github.sha}}
|
||||||
|
steps:
|
||||||
|
- name: Run test
|
||||||
|
id: test
|
||||||
|
timeout-minutes: 10
|
||||||
|
run: SCHEME=ec IMMEDIATE_COMMIT=1 /root/vitastor/tests/test_interrupted_rebalance.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_minsize_1:
|
||||||
|
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_minsize_1.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_move_reappear:
|
||||||
|
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_move_reappear.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_rebalance_verify:
|
||||||
|
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_rebalance_verify.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_rebalance_verify_imm:
|
||||||
|
runs-on: ubuntu-latest
|
||||||
|
needs: build
|
||||||
|
container: ${{env.TEST_IMAGE}}:${{github.sha}}
|
||||||
|
steps:
|
||||||
|
- name: Run test
|
||||||
|
id: test
|
||||||
|
timeout-minutes: 3
|
||||||
|
run: IMMEDIATE_COMMIT=1 /root/vitastor/tests/test_rebalance_verify.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_rebalance_verify_ec:
|
||||||
|
runs-on: ubuntu-latest
|
||||||
|
needs: build
|
||||||
|
container: ${{env.TEST_IMAGE}}:${{github.sha}}
|
||||||
|
steps:
|
||||||
|
- name: Run test
|
||||||
|
id: test
|
||||||
|
timeout-minutes: 3
|
||||||
|
run: SCHEME=ec /root/vitastor/tests/test_rebalance_verify.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_rebalance_verify_ec_imm:
|
||||||
|
runs-on: ubuntu-latest
|
||||||
|
needs: build
|
||||||
|
container: ${{env.TEST_IMAGE}}:${{github.sha}}
|
||||||
|
steps:
|
||||||
|
- name: Run test
|
||||||
|
id: test
|
||||||
|
timeout-minutes: 3
|
||||||
|
run: SCHEME=ec IMMEDIATE_COMMIT=1 /root/vitastor/tests/test_rebalance_verify.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_rm:
|
||||||
|
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_rm.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_snapshot:
|
||||||
|
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_snapshot.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_snapshot_ec:
|
||||||
|
runs-on: ubuntu-latest
|
||||||
|
needs: build
|
||||||
|
container: ${{env.TEST_IMAGE}}:${{github.sha}}
|
||||||
|
steps:
|
||||||
|
- name: Run test
|
||||||
|
id: test
|
||||||
|
timeout-minutes: 3
|
||||||
|
run: SCHEME=ec /root/vitastor/tests/test_snapshot.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_splitbrain:
|
||||||
|
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_splitbrain.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:
|
||||||
|
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_write.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_xor:
|
||||||
|
runs-on: ubuntu-latest
|
||||||
|
needs: build
|
||||||
|
container: ${{env.TEST_IMAGE}}:${{github.sha}}
|
||||||
|
steps:
|
||||||
|
- name: Run test
|
||||||
|
id: test
|
||||||
|
timeout-minutes: 3
|
||||||
|
run: SCHEME=xor /root/vitastor/tests/test_write.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_no_same:
|
||||||
|
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_write_no_same.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_heal_pg_size_2:
|
||||||
|
runs-on: ubuntu-latest
|
||||||
|
needs: build
|
||||||
|
container: ${{env.TEST_IMAGE}}:${{github.sha}}
|
||||||
|
steps:
|
||||||
|
- name: Run test
|
||||||
|
id: test
|
||||||
|
timeout-minutes: 10
|
||||||
|
run: PG_SIZE=2 /root/vitastor/tests/test_heal.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_heal_ec:
|
||||||
|
runs-on: ubuntu-latest
|
||||||
|
needs: build
|
||||||
|
container: ${{env.TEST_IMAGE}}:${{github.sha}}
|
||||||
|
steps:
|
||||||
|
- name: Run test
|
||||||
|
id: test
|
||||||
|
timeout-minutes: 10
|
||||||
|
run: SCHEME=ec /root/vitastor/tests/test_heal.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
|
||||||
|
|
68
.gitea/workflows/tests-to-yaml.pl
Executable file
68
.gitea/workflows/tests-to-yaml.pl
Executable file
@@ -0,0 +1,68 @@
|
|||||||
|
#!/usr/bin/perl
|
||||||
|
|
||||||
|
use strict;
|
||||||
|
|
||||||
|
for my $line (<>)
|
||||||
|
{
|
||||||
|
if ($line =~ /\.\/(test_[^\.]+)/s)
|
||||||
|
{
|
||||||
|
chomp $line;
|
||||||
|
my $test_name = $1;
|
||||||
|
my $timeout = 3;
|
||||||
|
if ($test_name eq 'test_etcd_fail' || $test_name eq 'test_heal' || $test_name eq 'test_interrupted_rebalance')
|
||||||
|
{
|
||||||
|
$timeout = 10;
|
||||||
|
}
|
||||||
|
while ($line =~ /([^\s=]+)=(\S+)/gs)
|
||||||
|
{
|
||||||
|
if ($1 eq 'SCHEME' && $2 eq 'ec')
|
||||||
|
{
|
||||||
|
$test_name .= '_ec';
|
||||||
|
}
|
||||||
|
elsif ($1 eq 'SCHEME' && $2 eq 'xor')
|
||||||
|
{
|
||||||
|
$test_name .= '_xor';
|
||||||
|
}
|
||||||
|
elsif ($1 eq 'IMMEDIATE_COMMIT')
|
||||||
|
{
|
||||||
|
$test_name .= '_imm';
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
$test_name .= '_'.lc($1).'_'.$2;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
$line =~ s!\./test_!/root/vitastor/tests/test_!;
|
||||||
|
# Gitea CI doesn't support artifacts yet, lol
|
||||||
|
#- name: Upload results
|
||||||
|
# uses: actions/upload-artifact\@v3
|
||||||
|
# if: always()
|
||||||
|
# with:
|
||||||
|
# name: ${test_name}_result
|
||||||
|
# path: |
|
||||||
|
# /root/vitastor/testdata
|
||||||
|
# !/root/vitastor/testdata/*.bin
|
||||||
|
# retention-days: 5
|
||||||
|
print <<"EOF"
|
||||||
|
$test_name:
|
||||||
|
runs-on: ubuntu-latest
|
||||||
|
needs: build
|
||||||
|
container: \${{env.TEST_IMAGE}}:\${{github.sha}}
|
||||||
|
steps:
|
||||||
|
- name: Run test
|
||||||
|
id: test
|
||||||
|
timeout-minutes: $timeout
|
||||||
|
run: $line
|
||||||
|
- 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
|
||||||
|
|
||||||
|
EOF
|
||||||
|
;
|
||||||
|
}
|
||||||
|
}
|
@@ -1,7 +1,7 @@
|
|||||||
cmake_minimum_required(VERSION 2.8)
|
cmake_minimum_required(VERSION 2.8.12)
|
||||||
|
|
||||||
project(vitastor)
|
project(vitastor)
|
||||||
|
|
||||||
set(VERSION "0.7.0")
|
set(VERSION "0.8.9")
|
||||||
|
|
||||||
add_subdirectory(src)
|
add_subdirectory(src)
|
||||||
|
@@ -58,6 +58,7 @@ Vitastor поддерживает QEMU-драйвер, протоколы NBD и
|
|||||||
- [Метаданные образов в etcd](docs/config/inode.ru.md)
|
- [Метаданные образов в etcd](docs/config/inode.ru.md)
|
||||||
- Использование
|
- Использование
|
||||||
- [vitastor-cli](docs/usage/cli.ru.md) (консольный интерфейс)
|
- [vitastor-cli](docs/usage/cli.ru.md) (консольный интерфейс)
|
||||||
|
- [vitastor-disk](docs/usage/disk.ru.md) (управление дисками)
|
||||||
- [fio](docs/usage/fio.ru.md) для тестов производительности
|
- [fio](docs/usage/fio.ru.md) для тестов производительности
|
||||||
- [NBD](docs/usage/nbd.ru.md) для монтирования ядром
|
- [NBD](docs/usage/nbd.ru.md) для монтирования ядром
|
||||||
- [QEMU и qemu-img](docs/usage/qemu.ru.md)
|
- [QEMU и qemu-img](docs/usage/qemu.ru.md)
|
||||||
@@ -96,5 +97,5 @@ Vitastor Network Public License 1.1, основанная на GNU GPL 3.0 с д
|
|||||||
и также на условиях GNU GPL 2.0 или более поздней версии. Так сделано в целях
|
и также на условиях GNU GPL 2.0 или более поздней версии. Так сделано в целях
|
||||||
совместимости с таким ПО, как QEMU и fio.
|
совместимости с таким ПО, как QEMU и fio.
|
||||||
|
|
||||||
Вы можете найти полный текст VNPL 1.1 в файле [VNPL-1.1.txt](VNPL-1.1.txt),
|
Вы можете найти полный текст VNPL 1.1 на английском языке в файле [VNPL-1.1.txt](VNPL-1.1.txt),
|
||||||
а GPL 2.0 в файле [GPL-2.0.txt](GPL-2.0.txt).
|
VNPL 1.1 на русском языке в файле [VNPL-1.1-RU.txt](VNPL-1.1-RU.txt), а GPL 2.0 в файле [GPL-2.0.txt](GPL-2.0.txt).
|
||||||
|
@@ -58,6 +58,7 @@ Read more details below in the documentation.
|
|||||||
- [Image metadata in etcd](docs/config/inode.en.md)
|
- [Image metadata in etcd](docs/config/inode.en.md)
|
||||||
- Usage
|
- Usage
|
||||||
- [vitastor-cli](docs/usage/cli.en.md) (command-line interface)
|
- [vitastor-cli](docs/usage/cli.en.md) (command-line interface)
|
||||||
|
- [vitastor-disk](docs/usage/disk.en.md) (disk management tool)
|
||||||
- [fio](docs/usage/fio.en.md) for benchmarks
|
- [fio](docs/usage/fio.en.md) for benchmarks
|
||||||
- [NBD](docs/usage/nbd.en.md) for kernel mounts
|
- [NBD](docs/usage/nbd.en.md) for kernel mounts
|
||||||
- [QEMU and qemu-img](docs/usage/qemu.en.md)
|
- [QEMU and qemu-img](docs/usage/qemu.en.md)
|
||||||
|
680
VNPL-1.1-RU.txt
Normal file
680
VNPL-1.1-RU.txt
Normal file
@@ -0,0 +1,680 @@
|
|||||||
|
СЕТЕВАЯ ПУБЛИЧНАЯ ЛИЦЕНЗИЯ VITASTOR
|
||||||
|
VITASTOR NETWORK PUBLIC LICENSE
|
||||||
|
Версия 1.1, от 6 февраля 2021
|
||||||
|
|
||||||
|
Автор лицензии: Виталий Филиппов <vitalif@yourcmc.ru>, 2021 год
|
||||||
|
Каждый имеет право копировать и распространять точные копии этой
|
||||||
|
лицензии, но без внесения изменений.
|
||||||
|
|
||||||
|
ПРЕАМБУЛА
|
||||||
|
|
||||||
|
Сетевая Публичная Лицензия Vitastor - это свободная "копилефт" лицензия для
|
||||||
|
для программного обеспечения (ПО) и других видов произведений, специально
|
||||||
|
разработанная, чтобы гарантировать кооперацию с сообществом при разработке
|
||||||
|
сетевых приложений.
|
||||||
|
|
||||||
|
Большинство лицензий на программное обеспечение и другие произведения
|
||||||
|
спроектированы так, чтобы лишить Вас свободы делиться ими и изменять их.
|
||||||
|
Сетевая Публичная Лицензия Vitastor, напротив, разработана с целью
|
||||||
|
гарантировать Ваше право распространять и вносить изменения во все версии
|
||||||
|
программного обеспечения -- для уверенности, что ПО останется свободным для
|
||||||
|
всех пользователей.
|
||||||
|
|
||||||
|
Когда мы говорим о свободном ПО, мы имеем в виду свободу использования, а не
|
||||||
|
бесплатность. Свободные лицензии, такие, как Сетевая Публичная Лицензия
|
||||||
|
Vitastor, составлены для того, чтобы убедиться, что у Вас есть право
|
||||||
|
распространять копии свободного ПО (и взимать плату за них, если Вы хотите),
|
||||||
|
что Вы получаете исходные тексты или можете получить их, если захотите, что Вы
|
||||||
|
можете изменять программное обеспечение или использовать его части в новых
|
||||||
|
свободных программах, и что Вы знаете о своем праве делать всё это.
|
||||||
|
|
||||||
|
Разработчики, использующие Сетевую Публичную Лицензию Vitastor, гарантируют
|
||||||
|
Ваши права при помощи следующих мер: (1) закрепляют авторское право на
|
||||||
|
программное обеспечение, и (2) предлагают Вам принять условия настоящей
|
||||||
|
Лицензии, закрепляющей Ваше право на создание копий, распространение и (или)
|
||||||
|
модификацию программного обеспечения.
|
||||||
|
|
||||||
|
Еще одно преимущество защиты свободы всех пользователей заключается в том,
|
||||||
|
что улучшения, сделанные в разных версиях программы, при их широком
|
||||||
|
распространении становятся доступными для использования другими разработчиками.
|
||||||
|
Многие разработчики программного обеспечения воодушевляются этим
|
||||||
|
сотрудничеством и пользуются его преимуществами. Однако, если программное
|
||||||
|
обеспечение используется на сетевых серверах, данный результат не всегда
|
||||||
|
достигается. Генеральная публичная лицензия GNU разрешает создание измененных
|
||||||
|
версий и предоставление неограниченного доступа к ним, не делая общедоступным
|
||||||
|
их исходный текст. Даже генеральная публичная лицензия GNU Affero разрешает
|
||||||
|
использование модифицированной версии свободной программы в закрытой среде, где
|
||||||
|
внешние пользователи взаимодействуют с ней только через закрытый промежуточный
|
||||||
|
интерфейс (прокси), опять же, без открытия в свободный публичный доступ как
|
||||||
|
самой программы, так и прокси.
|
||||||
|
|
||||||
|
Сетевая Публичная Лицензия Vitastor разработана специально, чтобы
|
||||||
|
гарантировать, что в таких случаях и модифицированная версия программы, и
|
||||||
|
прокси останутся доступными сообществу. Для этого лицензия требует от
|
||||||
|
операторов сетевых серверов предоставлять исходный код оригинальной программы,
|
||||||
|
а также всех других программ, взаимодействующих с ней на их серверах,
|
||||||
|
пользователям этих серверов, на условиях свободных лицензий. Таким образом,
|
||||||
|
публичное использование изменённой версии ПО на сервере, прямо или косвенно
|
||||||
|
доступном пользователям, даёт пользователям доступ к исходным кодам изменённой
|
||||||
|
версии.
|
||||||
|
|
||||||
|
Детальные определения используемых терминов и описание условий копирования,
|
||||||
|
распространения и внесения изменений приведены ниже.
|
||||||
|
|
||||||
|
ТЕРМИНЫ И УСЛОВИЯ
|
||||||
|
|
||||||
|
0. Определения.
|
||||||
|
|
||||||
|
"Настоящая Лицензия" -- версия 1.1 Сетевой Публичной Лицензии Vitastor.
|
||||||
|
|
||||||
|
Под "Авторским правом" понимаются все законы, сходные с авторско-правовыми,
|
||||||
|
которые применяются к любым видам работ, например, к топологиям микросхем.
|
||||||
|
|
||||||
|
Термином "Программа" обозначается любое охраноспособное произведение,
|
||||||
|
используемое в соответствии с настоящей Лицензией. Лицензиат именуется "Вы".
|
||||||
|
"Лицензиаты" и "получатели" могут быть как физическими лицами, так и
|
||||||
|
организациями.
|
||||||
|
|
||||||
|
"Внесение изменений" в произведение означает копирование или адаптацию
|
||||||
|
произведения целиком или в части, способом, требующим разрешения
|
||||||
|
правообладателя, за исключением изготовления его точной копии. Получившееся
|
||||||
|
произведение называется "измененной версией" предыдущего произведения или
|
||||||
|
произведением, "основанным на" более ранней работе.
|
||||||
|
|
||||||
|
Термином "Лицензионное произведение" обозначается неизмененная Программа или
|
||||||
|
произведение, основанное на Программе.
|
||||||
|
|
||||||
|
"Распространение" произведения означает совершение с ним действий, которые
|
||||||
|
при отсутствии разрешения сделают Вас прямо или косвенно ответственным за
|
||||||
|
нарушение действующего закона об авторском праве, за исключением запуска на
|
||||||
|
компьютере или изменения копии, созданной в личных целях. Распространение
|
||||||
|
включает в себя копирование, раздачу копий (с изменениями или без них),
|
||||||
|
доведение до всеобщего сведения, а в некоторых странах -- и другие действия.
|
||||||
|
|
||||||
|
"Передача" произведения означает любой вид распространения, который позволяет
|
||||||
|
другим лицам создавать или получать копии произведения. Обычное взаимодействие
|
||||||
|
с пользователем через компьютерную сеть без создания копии передачей не
|
||||||
|
является.
|
||||||
|
|
||||||
|
Интерактивный интерфейс пользователя должен отображать "Информация об
|
||||||
|
авторском праве", достаточную для того, чтобы (1) обеспечить отображение
|
||||||
|
соответствующего уведомления об авторских правах и (2) сообщить пользователю
|
||||||
|
о том, что ему не предоставляются никакие гарантии на произведение (за
|
||||||
|
исключением явным образом предоставленных гарантий), о том, что лицензиаты
|
||||||
|
могут передавать произведение на условиях, описанных в настоящей Лицензии,
|
||||||
|
а также о том, как ознакомиться с текстом настоящей Лицензии. Если интерфейс
|
||||||
|
предоставляет собой список пользовательских команд или настроек, наподобие
|
||||||
|
меню, это требование считается выполненным при наличии явно выделенного
|
||||||
|
пункта в таком меню.
|
||||||
|
|
||||||
|
1. Исходный текст.
|
||||||
|
|
||||||
|
Под "Исходным текстом" понимается произведение в форме, которая более всего
|
||||||
|
подходит для внесения в него изменений. "Объектным кодом" называется
|
||||||
|
произведение в любой иной форме.
|
||||||
|
|
||||||
|
"Стандартный интерфейс" -- интерфейс, который либо является общепринятым
|
||||||
|
стандартом, введенным общепризнанным органом по стандартизации, либо, в случае
|
||||||
|
интерфейсов, характерных для конкретного языка программирования -- тот,
|
||||||
|
который широко используется разработчиками, пишущими программы на этом языке.
|
||||||
|
|
||||||
|
"Системные библиотеки" исполняемого произведения включают в себя то, что не
|
||||||
|
относится к произведению в целом и при этом (a) входит в обычный комплект
|
||||||
|
Основного компонента, но при этом не является его частью и (b) служит только
|
||||||
|
для обеспечения работы с этим Основным компонентом или для реализации
|
||||||
|
Стандартного интерфейса, для которого существует общедоступная реализация,
|
||||||
|
опубликованная в виде исходного текста. "Основным компонентом" в данном
|
||||||
|
контексте назван главный существенный компонент (ядро, оконная система и т.д.)
|
||||||
|
определенной операционной системы (если она используется), под управлением
|
||||||
|
которой функционирует исполняемое произведение, либо компилятор, используемый
|
||||||
|
для создания произведения или интерпретатор объектного кода, используемый для
|
||||||
|
его запуска.
|
||||||
|
|
||||||
|
"Полный исходный текст" для произведения в форме объектного кода -- весь
|
||||||
|
исходный текст, необходимый для создания, установки и (для исполняемого
|
||||||
|
произведения) функционирования объектного кода, а также модификации
|
||||||
|
произведения, включая сценарии, контролирующие эти действия. Однако он не
|
||||||
|
включает в себя Системные библиотеки, необходимые для функционирования
|
||||||
|
произведения, инструменты общего назначения или общедоступные свободные
|
||||||
|
программы, которые используются в неизменном виде для выполнения этих
|
||||||
|
действий, но не являются частью произведения. Полный исходный текст включает
|
||||||
|
в себя, например, файлы описания интерфейса, прилагаемые к файлам исходного
|
||||||
|
текста произведения, а также исходные тексты общих библиотек и динамически
|
||||||
|
связанных подпрограмм, которые требуются для функционирования произведения
|
||||||
|
и разработаны специально для этого, например, для прямой передачи данных
|
||||||
|
или управления потоками между этими подпрограммами и другими частями
|
||||||
|
произведения. Полный исходный текст не включает в себя то, что пользователи
|
||||||
|
могут сгенерировать автоматически из других частей Полного исходного текста.
|
||||||
|
Полным исходным текстом для произведения в форме исходных текстов является
|
||||||
|
само это произведение.
|
||||||
|
|
||||||
|
2. Основные права.
|
||||||
|
|
||||||
|
Все права, предоставленные на основании настоящей Лицензии, действуют в
|
||||||
|
течение срока действия авторских прав на Программу и не могут быть отозваны
|
||||||
|
при условии, что сформулированные в ней условия соблюдены. Настоящая Лицензия
|
||||||
|
однозначно подтверждает Ваши неограниченные права на запуск неизмененной
|
||||||
|
Программы. Настоящая Лицензия распространяется на результаты функционирования
|
||||||
|
Лицензионного произведения только в том случае, если они, учитывая их
|
||||||
|
содержание, сами являются частью Лицензионного произведения. Настоящая
|
||||||
|
Лицензия подтверждает Ваши права на свободное использование произведения
|
||||||
|
или другие аналогичные полномочия, предусмотренные действующим
|
||||||
|
законодательством об авторском праве.
|
||||||
|
|
||||||
|
Если Вы не осуществляете обычную передачу Лицензионного произведения, то
|
||||||
|
можете как угодно создавать, запускать и распространять его копии до тех пор,
|
||||||
|
пока ваша Лицензия сохраняет силу. Вы можете передавать Лицензионные
|
||||||
|
произведения третьим лицам исключительно для того, чтобы они внесли в них
|
||||||
|
изменения для Вас или предоставили Вам возможность их запуска, при условии,
|
||||||
|
что Вы соглашаетесь с условиями настоящей Лицензии при передаче всех
|
||||||
|
материалов, авторскими правами на которые Вы не обладаете. Лица, создающие
|
||||||
|
или запускающие Лицензионные произведения для Вас, должны делать это
|
||||||
|
исключительно от Вашего имени, под Вашим руководством и контролем, на
|
||||||
|
условиях, которые запрещают им создание без Вашей санкции каких-либо копий
|
||||||
|
материалов, на которые Вы обладаете авторским правом.
|
||||||
|
|
||||||
|
Любая другая передача разрешается исключительно при соблюдении описанных
|
||||||
|
ниже условий. Сублицензирование не допускается; раздел 10 делает его не нужным.
|
||||||
|
|
||||||
|
3. Защита прав пользователей от законов, запрещающих обход технических средств.
|
||||||
|
|
||||||
|
Ни одно Лицензионное произведение не должно считаться содержащим эффективные
|
||||||
|
технические средства, удовлетворяющие требованиям любого действующего закона,
|
||||||
|
принятого для исполнения обязательств, предусмотренных статьей 11 Договора ВОИС
|
||||||
|
по авторскому праву от 20 декабря 1996 года или аналогичных законов,
|
||||||
|
запрещающих или ограничивающих обход таких технических средств.
|
||||||
|
|
||||||
|
При передаче Лицензионного произведения Вы отказываетесь от всех
|
||||||
|
предоставляемых законом полномочий по запрету обхода технических средств,
|
||||||
|
используемых авторами в связи с осуществлением их прав, признавая, что такой
|
||||||
|
обход находится в рамках осуществления прав на использование Лицензионного
|
||||||
|
произведения, предоставленных настоящей Лицензией; также Вы отказываетесь
|
||||||
|
от любых попыток ограничить функционирование произведения или внесение в него
|
||||||
|
изменений, направленных на реализацию предоставленных Вам законом прав на
|
||||||
|
запрет пользователю обхода технических средств.
|
||||||
|
|
||||||
|
4. Передача неизмененных копий.
|
||||||
|
|
||||||
|
Вы можете передавать точные копии исходных текстов Программы в том виде,
|
||||||
|
в котором Вы их получили, на любом носителе, при условии, что Вы прилагаете
|
||||||
|
к каждой копии соответствующее уведомление об авторских правах способом,
|
||||||
|
обеспечивающим ознакомление с ним пользователя; сохраняете все уведомления
|
||||||
|
о том, что к тексту применима настоящая Лицензия и любые ограничения,
|
||||||
|
добавленные в соответствии с разделом 7; сохраняете все уведомления об
|
||||||
|
отсутствии каких-либо гарантий; предоставляете всем получателям вместе с
|
||||||
|
Программой копию настоящей Лицензии.
|
||||||
|
|
||||||
|
Вы можете установить любую цену за каждую копию, которую Вы передаете,
|
||||||
|
или распространять копии бесплатно; также Вы можете предложить поддержку
|
||||||
|
или гарантию за отдельную плату.
|
||||||
|
|
||||||
|
5. Передача измененных исходных текстов.
|
||||||
|
|
||||||
|
Вы можете передавать исходный текст произведения, основанного на Программе,
|
||||||
|
или изменений, необходимых для того, чтобы получить его из Программы, на
|
||||||
|
условиях, описанных в разделе 4, при соблюдении следующих условий:
|
||||||
|
|
||||||
|
а) Произведение должно содержать уведомления о произведенных Вами
|
||||||
|
изменениях с указанием их даты, сделанные способом, обеспечивающим
|
||||||
|
ознакомление с ними пользователя.
|
||||||
|
|
||||||
|
b) Произведение должно содержать уведомление о том, что оно
|
||||||
|
распространяется на условиях настоящей Лицензии, а также об условиях,
|
||||||
|
добавленных в соответствии с разделом 7, сделанное способом,
|
||||||
|
обеспечивающим ознакомление с ним пользователя. Данное требование имеет
|
||||||
|
приоритет над требованиями раздела 4 "оставлять нетронутыми все
|
||||||
|
уведомления".
|
||||||
|
|
||||||
|
c) Вы должны передать на условиях настоящей Лицензии всю работу целиком
|
||||||
|
любому лицу, которое приобретает копию. Таким образом, настоящая Лицензия
|
||||||
|
вместе с любыми применимыми условиями раздела 7 будет применяться к
|
||||||
|
произведению в целом и всем его частям, независимо от их комплектности.
|
||||||
|
Настоящая Лицензия не дает права на лицензирование произведения на любых
|
||||||
|
других условиях, но это не лишает законной силы такое разрешение, если Вы
|
||||||
|
получили его отдельно.
|
||||||
|
|
||||||
|
d) Если произведение имеет интерактивные пользовательские интерфейсы,
|
||||||
|
каждый из них должен отображать Информацию об авторском праве; однако,
|
||||||
|
если Программа имеет пользовательские интерфейсы, которые не отображают
|
||||||
|
информацию об авторском праве, от Вашего произведения этого также не
|
||||||
|
требуется.
|
||||||
|
|
||||||
|
Включение Лицензионного произведения в подборку на разделе хранения данных
|
||||||
|
или на носителе, на котором распространяется произведение, вместе с другими
|
||||||
|
отдельными самостоятельными произведениями, которые по своей природе не
|
||||||
|
являются переработкой Лицензионного произведения и не объединены с ним,
|
||||||
|
например, в программный комплекс, называется "набором", если авторские права
|
||||||
|
на подборку не используются для ограничения доступа к ней или законных прав
|
||||||
|
её пользователей сверх того, что предусматривают лицензии на отдельные
|
||||||
|
произведения. Включение Лицензионного произведения в набор не влечет применения
|
||||||
|
положений настоящей Лицензии к остальным его частям.
|
||||||
|
|
||||||
|
6. Передача произведения в формах, не относящихся к исходному тексту.
|
||||||
|
|
||||||
|
Вы можете передавать Лицензионное произведение в виде объектного кода в
|
||||||
|
соответствии с положениями разделов 4 и 5, при условии, что Вы также передаете
|
||||||
|
машиночитаемый Полный исходный текст в соответствии с условиями настоящей
|
||||||
|
Лицензии, одним из следующих способов:
|
||||||
|
|
||||||
|
а) Передавая объектный код или содержащий его материальный продукт (включая
|
||||||
|
распределенный материальный носитель), с приложением Полного исходного
|
||||||
|
текста наматериальном носителе, обычно используемом для обмена программным
|
||||||
|
обеспечением.
|
||||||
|
|
||||||
|
b) Передавая объектный код или содержащий его материальный продукт (включая
|
||||||
|
носитель, на котором распространяется произведение), с письменным
|
||||||
|
предложением, действительным в течение не менее трех лет либо до тех пор,
|
||||||
|
пока Вы предоставляете запасные части или поддержку для данного продукта,
|
||||||
|
о передаче любому обладателю объектного кода (1) копии Полного исходного
|
||||||
|
текста для всего программного обеспечения, содержащегося в продукте, на
|
||||||
|
которое распространяется действие настоящей Лицензии, на физическом
|
||||||
|
носителе, обычно используемом для обмена программным обеспечением, по цене,
|
||||||
|
не превышающей разумных затрат на передачу копии, или (2) доступа к Полному
|
||||||
|
исходному тексту с возможностью его копирования с сетевого сервера без
|
||||||
|
взимания платы.
|
||||||
|
|
||||||
|
с) Передавая отдельные копии объектного кода с письменной копией предложения
|
||||||
|
о предоставлении Полного исходного текста. Этот вариант допускается только
|
||||||
|
в отдельных случаях при распространении без извлечения прибыли, и только
|
||||||
|
если Вы получили объектный код с таким предложением в соответствии
|
||||||
|
с пунктом 6b.
|
||||||
|
|
||||||
|
d) Передавая объектный код посредством предоставления доступа к нему по
|
||||||
|
определенному адресу (бесплатно или за дополнительную плату), и предлагая
|
||||||
|
эквивалентный доступ к Полному исходному тексту таким же способом по тому же
|
||||||
|
адресу без какой-либо дополнительной оплаты. От Вас не требуется принуждать
|
||||||
|
получателей копировать Полный исходный текст вместе с объектным кодом. Если
|
||||||
|
объектный код размещен на сетевом сервере, Полный исходный текст может
|
||||||
|
находиться на другом сервере (управляемом Вами или третьим лицом), который
|
||||||
|
предоставляет аналогичную возможность копирования; при этом Вы должны четко
|
||||||
|
указать рядом с объектным кодом способ получения Полного исходного текста.
|
||||||
|
Независимо от того, на каком сервере расположен Полный исходный текст, Вы
|
||||||
|
обязаны убедиться в том, что он будет распространяться в течение времени,
|
||||||
|
необходимого для соблюдения этих требований.
|
||||||
|
|
||||||
|
e) Передавая объектный код с использованием одноранговой (пиринговой) сети,
|
||||||
|
при условии информирования других пользователей сети о том, где можно
|
||||||
|
бесплатно получить объектный код и Полный исходный текст произведения
|
||||||
|
способом, описанным в пункте 6d.
|
||||||
|
|
||||||
|
Не нужно включать в передаваемый объектный код его отделимые части, исходные
|
||||||
|
тексты которых не входят в состав Полного исходного текста, такие как Системные
|
||||||
|
библиотеки.
|
||||||
|
|
||||||
|
"Потребительский товар" это либо (1) "товар, предназначенный для личных нужд",
|
||||||
|
под которым понимается любое материальное личное имущество, которое обычно
|
||||||
|
используется для личных, семейных или домашних целей, или (2) что-либо
|
||||||
|
спроектированное или продающееся для использования в жилище. При определении
|
||||||
|
того, предназначен ли товар для личных нужд, сомнения должны толковаться в
|
||||||
|
пользу положительного ответа на этот вопрос. Применительно к конкретному
|
||||||
|
товару, используемому конкретным пользователем, под выражением "обычно
|
||||||
|
используется" имеется в виду способ, которым данный вид товаров преимущественно
|
||||||
|
или как правило используется, независимо от статуса конкретного пользователя
|
||||||
|
или способа, которым конкретный пользователь использует, предполагает или
|
||||||
|
будет использовать товар. Товар относится к предназначенным для личных нужд
|
||||||
|
независимо от того, насколько часто он используется в коммерческой
|
||||||
|
деятельности, промышленности или иной сфере, не относящейся к личным нуждам,
|
||||||
|
за исключением случая, когда использование в этой сфере представляет собой
|
||||||
|
единственный основной способ использования такого товара.
|
||||||
|
|
||||||
|
"Информация, необходимая для установки" Потребительского товара -- любые
|
||||||
|
методы, процедуры, сведения, необходимые для авторизации, или другая
|
||||||
|
информация, необходимая для установки и запуска в Потребительском товаре
|
||||||
|
измененных версий Лицензионного произведения, полученных при изменении
|
||||||
|
Полного исходного текста. Данная информация должна быть достаточной для
|
||||||
|
того, чтобы обеспечить возможность внесения в исходный текст изменений,
|
||||||
|
не приводящих к ограничению или нарушению его дальнейшей работоспособности.
|
||||||
|
|
||||||
|
Если вместе с Потребительским товаром или специально для использования
|
||||||
|
в нём Вы передаете произведение в виде объектного кода на условиях, описанных
|
||||||
|
в данном разделе, и такая передача является частью сделки, по которой право
|
||||||
|
владения и пользования Потребительским товаром переходит к получателю
|
||||||
|
пожизненно или на определенный срок (независимо от признаков сделки), Полный
|
||||||
|
исходный текст, передаваемый согласно данному разделу, должен сопровождаться
|
||||||
|
Информацией, необходимой для установки. Но это требование не применяется,
|
||||||
|
если ни Вы, ни какое-либо третье лицо не сохраняет за собой возможности
|
||||||
|
установки измененного объектного кода на Потребительский товар (например,
|
||||||
|
произведение было установлено в постоянную память).
|
||||||
|
|
||||||
|
Требование о предоставлении Информации, необходимой для установки, не
|
||||||
|
включает в себя требование продолжения оказания услуг по поддержке,
|
||||||
|
предоставления гарантии или обновлений для произведения, которое было изменено
|
||||||
|
или установлено получателем, либо для Потребительского товара, в котором оно
|
||||||
|
было изменено или на который оно было установлено. В доступе к сети может быть
|
||||||
|
отказано, если само внесение изменений существенно и негативно влияет на
|
||||||
|
работу сети, нарушает правила обмена данными или не поддерживает протоколы для
|
||||||
|
обмена данными по сети.
|
||||||
|
|
||||||
|
Передаваемый в соответствии с данным разделом Полный исходный текст и
|
||||||
|
предоставленная Информация, необходимая для установки, должны быть записаны в
|
||||||
|
формате, который имеет общедоступное описание (и общедоступную реализацию,
|
||||||
|
опубликованную в форме исходного текста) и не должны требовать никаких
|
||||||
|
специальных паролей или ключей для распаковки, чтения или копирования.
|
||||||
|
|
||||||
|
7. Дополнительные условия.
|
||||||
|
|
||||||
|
"Дополнительными разрешениями" называются условия, которые дополняют условия
|
||||||
|
настоящей Лицензии, делая исключения из одного или нескольких её положений.
|
||||||
|
Дополнительные разрешения, которые применимы ко всей Программе, должны
|
||||||
|
рассматриваться как часть настоящей Лицензии, в той степени, в которой они
|
||||||
|
соответствуют действующему законодательству. Если дополнительные разрешения
|
||||||
|
применяются только к части Программы, эта часть может быть использована отдельно
|
||||||
|
на измененных условиях, но вся Программа продолжает использоваться на условиях
|
||||||
|
настоящей Лицензии без учета дополнительных разрешений.
|
||||||
|
|
||||||
|
Когда Вы передаете копию Лицензионного произведения, Вы можете по своему
|
||||||
|
усмотрению исключить любые дополнительные разрешения, примененные к этой копии
|
||||||
|
или к любой её части. (Для дополнительных разрешений может быть заявлено
|
||||||
|
требование об их удалении в определенных случаях, когда Вы вносите изменения в
|
||||||
|
произведение.) Вы можете добавлять дополнительные разрешения к добавленным Вами
|
||||||
|
в Лицензионное произведение материалам, на которые Вы обладаете авторскими
|
||||||
|
правами или правом выдачи соответствующего разрешения.
|
||||||
|
|
||||||
|
Независимо от любых других положений настоящей Лицензии, Вы можете дополнить
|
||||||
|
следующими условиями положения настоящей Лицензии в отношении материала,
|
||||||
|
добавленного к Лицензионному произведению (если это разрешено обладателями
|
||||||
|
авторских прав на материал):
|
||||||
|
|
||||||
|
a) отказом от гарантий или ограничением ответственности, отличающимися от
|
||||||
|
тех, что описаны в разделах 15 и 16 настоящей Лицензии; либо
|
||||||
|
|
||||||
|
b) требованием сохранения соответствующей информации о правах или об
|
||||||
|
авторстве материала, или включения её в Информацию об авторском праве,
|
||||||
|
отображаемую содержащим его произведением; либо
|
||||||
|
|
||||||
|
c) запретом на искажение информации об источнике происхождения материала
|
||||||
|
или требованием того, чтобы измененные версии такого материала содержали
|
||||||
|
корректную отметку об отличиях от исходной версии; либо
|
||||||
|
|
||||||
|
d) ограничением использования в целях рекламы имен лицензиаров или авторов
|
||||||
|
материала; либо
|
||||||
|
|
||||||
|
e) отказом от предоставления прав на использование в качестве товарных
|
||||||
|
знаков некоторых торговых наименований, товарных знаков или знаков
|
||||||
|
обслуживания; либо
|
||||||
|
|
||||||
|
f) требованием от каждого, кто по договору передает материал (или его
|
||||||
|
измененные версии), предоставления компенсации лицензиарам и авторам
|
||||||
|
материала в виде принятия на себя любой ответственности, которую этот
|
||||||
|
договор налагает на лицензиаров и авторов.
|
||||||
|
|
||||||
|
Все остальные ограничительные дополнительные условия считаются "дополнительными
|
||||||
|
запретами" по смыслу раздела 10. Если программа, которую Вы получили, или любая
|
||||||
|
её часть содержит уведомление о том, что наряду с настоящей Лицензией её
|
||||||
|
использование регулируется условием, относящимся к дополнительным запретам, Вы
|
||||||
|
можете удалить такое условие. Если лицензия содержит дополнительный запрет, но
|
||||||
|
допускает лицензирование на измененных условиях или передачу в соответствии с
|
||||||
|
настоящей Лицензией, Вы можете добавить к Лицензионному произведению материал,
|
||||||
|
используемый на условиях такой лицензии, в том случае, если дополнительный
|
||||||
|
запрет не сохраняется при таком изменении условий лицензии или передаче.
|
||||||
|
|
||||||
|
Если Вы добавляете условия для использования Лицензионного произведения в
|
||||||
|
соответствии с настоящим разделом, Вы должны поместить в соответствующих файлах
|
||||||
|
исходного текста уведомление о том, что к этим файлам применяются дополнительные
|
||||||
|
условия, или указание на то, как ознакомиться с соответствующими условиями.
|
||||||
|
|
||||||
|
Дополнительные разрешающие или ограничивающие условия могут быть сформулированы
|
||||||
|
в виде отдельной лицензии или зафиксированы как исключения; вышеуказанные
|
||||||
|
требования применяются в любом случае.
|
||||||
|
|
||||||
|
8. Прекращение действия.
|
||||||
|
|
||||||
|
Вы не можете распространять Лицензионное произведение или вносить в него
|
||||||
|
изменения на условиях, отличающихся от явно оговоренных в настоящей Лицензии.
|
||||||
|
Любая попытка распространения или внесения изменений на иных условиях является
|
||||||
|
ничтожной и автоматически прекращает Ваши права, полученные по настоящей
|
||||||
|
Лицензии (включая лицензию на любые патенты, предоставленные согласно третьему
|
||||||
|
пункту раздела 11).
|
||||||
|
|
||||||
|
Тем не менее если Вы прекращаете нарушение настоящей Лицензии, Ваши права,
|
||||||
|
полученные от конкретного правообладателя, восстанавливаются (а) временно, до
|
||||||
|
тех пор пока правообладатель явно и окончательно не прекратит действие Ваших
|
||||||
|
прав, и (б) навсегда, если правообладатель не уведомит Вас о нарушении с помощью
|
||||||
|
надлежащих средств в течение 60 дней после прекращения нарушений.
|
||||||
|
|
||||||
|
Кроме того, Ваши права, полученные от конкретного правообладателя,
|
||||||
|
восстанавливаются навсегда, если правообладатель впервые любым подходящим
|
||||||
|
способом уведомляет Вас о нарушении настоящей Лицензии на свое произведение (для
|
||||||
|
любого произведения) и Вы устраняете нарушение в течение 30 дней после получения
|
||||||
|
уведомления.
|
||||||
|
|
||||||
|
Прекращение Ваших прав, описанное в настоящем разделе, не прекращает действие
|
||||||
|
лицензий лиц, которые получили от Вас копии произведения или права,
|
||||||
|
предоставляемые настоящей Лицензией. Если Ваши права были прекращены навсегда и
|
||||||
|
не восстановлены, Вы не можете вновь получить право на тот же материал на
|
||||||
|
условиях, описанных в разделе 10.
|
||||||
|
|
||||||
|
9. Акцепт не требуется для получения копий.
|
||||||
|
|
||||||
|
Вы не обязаны принимать условия настоящей Лицензии для того, чтобы получить или
|
||||||
|
запустить копию Программы. Случайное распространение Лицензионного произведения,
|
||||||
|
происходящее вследствие использования одноранговой (пиринговой) сети для
|
||||||
|
получения его копии, также не требует принятия этих условий. Тем не менее только
|
||||||
|
настоящая Лицензия дает Вам право распространять или изменять любое Лицензионное
|
||||||
|
произведение. Если Вы не приняли условия настоящей Лицензии, такие действия
|
||||||
|
будут нарушением авторского права. Поэтому изменяя или распространяя
|
||||||
|
Лицензионное произведение, Вы выражаете согласие с условиями настоящей Лицензии.
|
||||||
|
|
||||||
|
10. Автоматическое получение прав последующими получателями.
|
||||||
|
|
||||||
|
Каждый раз, когда Вы передаете Лицензионное произведение, получатель
|
||||||
|
автоматически получает от его лицензиара право запускать, изменять и
|
||||||
|
распространять это произведение при условии соблюдения настоящей Лицензии. Вы не
|
||||||
|
несете ответственности за соблюдение третьими лицами условий настоящей Лицензии.
|
||||||
|
|
||||||
|
"Реорганизацией" называются действия, в результате которых передается управление
|
||||||
|
организацией или значительная часть её активов, а также происходит разделение
|
||||||
|
или слияние организаций. Если распространение Лицензионного произведения
|
||||||
|
является результатом реорганизации, каждая из сторон сделки, получающая копию
|
||||||
|
произведения, также получает все права на произведение, которые предшествующее
|
||||||
|
юридическое лицо имело или могло предоставить согласно предыдущему абзацу, а
|
||||||
|
также право на владение Полным исходным текстом произведения от предшественника,
|
||||||
|
осуществляемое в его интересах, если предшественник владеет им или может
|
||||||
|
получить его при разумных усилиях.
|
||||||
|
|
||||||
|
Вы не можете налагать каких-либо дополнительных ограничений на осуществление
|
||||||
|
прав, предоставленных или подтвержденных в соответствии с настоящей Лицензией.
|
||||||
|
Например, Вы не можете ставить осуществление прав, предоставленных по настоящей
|
||||||
|
Лицензии, в зависимость от оплаты отчислений, роялти или других сборов; также Вы
|
||||||
|
не можете инициировать судебный процесс (включая встречный иск или заявление
|
||||||
|
встречного требования в судебном процессе) о нарушении любых патентных прав при
|
||||||
|
создании, использовании, продаже, предложении продажи, импорте Программы или
|
||||||
|
любой её части.
|
||||||
|
|
||||||
|
11. Патенты.
|
||||||
|
|
||||||
|
"Инвестором" называется правообладатель, разрешающий использование Программы
|
||||||
|
либо произведения, на котором основана Программа, на условиях настоящей
|
||||||
|
Лицензии. Произведение, лицензированное таким образом, называется "версией со
|
||||||
|
вкладом" инвестора.
|
||||||
|
|
||||||
|
"Неотъемлемые патентные претензии" инвестора -- все патентные права,
|
||||||
|
принадлежащие инвестору или контролируемые им в настоящее время либо
|
||||||
|
приобретенные в будущем, которые могут быть нарушены созданием, использованием
|
||||||
|
или продажей версии со вкладом, допускаемыми настоящей Лицензией; они не
|
||||||
|
включают в себя права, которые будут нарушены исключительно вследствие будущих
|
||||||
|
изменений версии со вкладом. Для целей данного определения под "контролем"
|
||||||
|
понимается право выдавать патентные сублицензии способами, не нарушающими
|
||||||
|
требований настоящей Лицензии.
|
||||||
|
|
||||||
|
Каждый инвестор предоставляет Вам неисключительную безвозмездную лицензию на
|
||||||
|
патент, действующую во всем мире, соответствующую неотъемлемым патентным
|
||||||
|
претензиям инвестора, на создание, использование, продажу, предложение для
|
||||||
|
продажи, импорт, а также запуск, внесение изменений и распространение всего, что
|
||||||
|
входит в состав версии со вкладом.
|
||||||
|
|
||||||
|
В следующих трех абзацах "лицензией на патент" называется любое явно выраженное
|
||||||
|
вовне согласие или обязательство не применять патент (например, выдача
|
||||||
|
разрешения на использование запатентованного объекта или обещание не подавать в
|
||||||
|
суд за нарушение патента). "Выдать" кому-то такую лицензию на патент означает
|
||||||
|
заключить такое соглашение или обязаться не применять патент против него.
|
||||||
|
|
||||||
|
Если Вы передаете Лицензионное произведение, сознательно основываясь на лицензии
|
||||||
|
на патент, в то время как Полный исходный текст произведения невозможно
|
||||||
|
бесплатно скопировать с общедоступного сервера или другим не вызывающим
|
||||||
|
затруднений способом, Вы должны либо (1) обеспечить возможность такого доступа к
|
||||||
|
Полному исходному тексту, либо (2) отказаться от прав, предоставленных по
|
||||||
|
лицензии на патент для данного произведения, либо (3) принять меры по передаче
|
||||||
|
лицензии на патент последующим получателям произведения, в соответствии с
|
||||||
|
требованиями настоящей Лицензии. "Сознательно основываясь" означает, что Вы
|
||||||
|
знаете, что при отсутствии лицензии на патент передача Вами Лицензионного
|
||||||
|
произведения в определенной стране или использование получателем переданного ему
|
||||||
|
Вами Лицензионного произведения в этой стране нарушит один или несколько
|
||||||
|
определенных патентов этой страны, срок действия которых не истек.
|
||||||
|
|
||||||
|
Если в соответствии или в связи с единичной сделкой либо соглашением Вы
|
||||||
|
передаете или делаете заказ на распространение Лицензионного произведения, и
|
||||||
|
предоставляете определенным лицам, получающим Лицензионное произведение,
|
||||||
|
лицензию на патент, разрешающую им использовать, распространять, вносить
|
||||||
|
изменения или передавать конкретные экземпляры Лицензионного произведения,
|
||||||
|
права, которые Вы предоставляете по лицензии на патент, автоматически переходят
|
||||||
|
ко всем получателям Лицензионного произведения и произведений, созданных на его
|
||||||
|
основе.
|
||||||
|
|
||||||
|
Патентная лицензия называется "дискриминирующей", если она не покрывает,
|
||||||
|
запрещает осуществление или содержит в качестве условия отказ от применения
|
||||||
|
одного или нескольких прав, предоставленных настоящей Лицензией. Вы не можете
|
||||||
|
передавать Лицензионное произведение, если Вы являетесь участником договора с
|
||||||
|
третьим лицом, осуществляющим распространение программного обеспечения, в
|
||||||
|
соответствии с которым Вы делаете в пользу третьего лица выплаты, размер которых
|
||||||
|
зависит от масштабов Вашей деятельности по передаче произведения, и в
|
||||||
|
соответствии с которым любое третье лицо, получающее от Вас Лицензионное
|
||||||
|
произведение, делает это на условиях дискриминирующей патентной лицензии (а)
|
||||||
|
которая зависит от количества копий Лицензионного произведения, переданных Вами
|
||||||
|
(или копий, сделанных с этих копий), или (b) которая используется
|
||||||
|
преимущественно в конкретных товарах или подборках, содержащих Лицензионное
|
||||||
|
произведение, или в связи с ними, в том случае, если Вы заключили данный договор
|
||||||
|
или получили лицензию на патент после 28 марта 2007 года.
|
||||||
|
|
||||||
|
Ничто в настоящей Лицензии не должно толковаться как исключение или ограничение
|
||||||
|
любого предполагаемого права или других способов противодействия нарушениям,
|
||||||
|
которые во всем остальном могут быть доступны для Вас в соответствии с
|
||||||
|
применимым патентным правом.
|
||||||
|
|
||||||
|
12. Запрет отказывать в свободе другим.
|
||||||
|
|
||||||
|
Если на Вас наложены обязанности (будь то по решению суда, договору или иным
|
||||||
|
способом), которые противоречат условиям настоящей Лицензии, это не освобождает
|
||||||
|
Вас от соблюдения её условий. Если Вы не можете передать Лицензионное
|
||||||
|
произведение так, чтобы одновременно выполнять Ваши обязательства по настоящей
|
||||||
|
Лицензии и любые другие относящиеся к делу обязательства, то Вы не можете
|
||||||
|
передавать его вообще. Например, если Вы согласны с условием, обязывающими Вас
|
||||||
|
производить сбор отчислений за дальнейшую передачу от тех, кому Вы передаете
|
||||||
|
Программу, то для того, чтобы соблюсти это условие и выполнить требования
|
||||||
|
настоящей Лицензии, Вы должны полностью воздержаться от передачи Программы.
|
||||||
|
|
||||||
|
13. Удаленное сетевое взаимодействие.
|
||||||
|
|
||||||
|
Под "Прокси-программой" понимается отдельная программа, специально
|
||||||
|
разработанная для использования совместно с Лицензионным произведением,
|
||||||
|
и взаимодействующая с ним прямо или косвенно через любой вид программного
|
||||||
|
интерфейса, компьютерную сеть, имитацию такой сети, или, в свою очередь,
|
||||||
|
через другую Прокси-программу.
|
||||||
|
|
||||||
|
Независимо от любых других положений настоящей Лицензии, если вы
|
||||||
|
предоставляете любому пользователю возможность взаимодействовать с Лицензионным
|
||||||
|
произведением через компьютерную сеть, имитацию такой сети, или через любое
|
||||||
|
количество "Прокси-программ", вы должны в явной форме предложить этому
|
||||||
|
пользователю возможность получить Полный исходный текст Лицензионного
|
||||||
|
произведения и всех Прокси-программ путём предоставления доступа к нему
|
||||||
|
с сетевого сервера без взимания платы, посредством стандартных или
|
||||||
|
традиционных способов, используемых для копирования программного обеспечения.
|
||||||
|
Полный исходный текст Лицензионного произведения должен предоставляться
|
||||||
|
пользователю на условиях настоящей Лицензии, а Полный исходный текст
|
||||||
|
Прокси-программ должен предоставляться пользователю либо на условиях настоящей
|
||||||
|
Лицензии, либо на условиях одной из свободных лицензий, совместимых с
|
||||||
|
Генеральной публичной Лицензией GNU, перечисленных Фондом Свободного
|
||||||
|
Программного Обеспечения в списке под названием "Лицензии свободных программ,
|
||||||
|
совместимые с GPL".
|
||||||
|
|
||||||
|
14. Пересмотренные редакции настоящей Лицензии.
|
||||||
|
|
||||||
|
Автор настоящей Лицензии время от времени может публиковать пересмотренные
|
||||||
|
и (или) новые редакции Сетевой Публичной Лицензии Vitastor. Они будут аналогичны
|
||||||
|
по смыслу настоящей редакции, но могут отличаться от нее в деталях, направленных
|
||||||
|
на решение новых проблем или регулирование новых отношений.
|
||||||
|
|
||||||
|
Каждой редакции присваивается собственный номер. Если для Программы указано,
|
||||||
|
что к ней применима определенная редакция Сетевой Публичной Лицензии Vitastor
|
||||||
|
"или любая более поздняя редакция", у Вас есть возможность использовать термины
|
||||||
|
и условия, содержащиеся в редакции с указанным номером или любой более поздней
|
||||||
|
редакции, опубликованной автором настоящей Лицензии. Если для Программы не
|
||||||
|
указан номер редакции Сетевой Публичной Лицензии Vitastor, Вы можете выбрать
|
||||||
|
любую редакцию, опубликованную автором настоящей Лицензии.
|
||||||
|
|
||||||
|
Более поздние редакции Лицензии могут дать Вам дополнительные или принципиально
|
||||||
|
иные права. Тем не менее в результате Вашего выбора более поздней редакции на
|
||||||
|
автора или правообладателя не возлагается никаких дополнительных обязанностей.
|
||||||
|
|
||||||
|
15. Отказ от гарантий.
|
||||||
|
|
||||||
|
НА ПРОГРАММУ НЕ ПРЕДОСТАВЛЯЕТСЯ НИКАКИХ ГАРАНТИЙ ЗА ИСКЛЮЧЕНИЕМ ПРЕДУСМОТРЕННЫХ
|
||||||
|
ДЕЙСТВУЮЩИМ ЗАКОНОДАТЕЛЬСТВОМ. ЕСЛИ ИНОЕ НЕ УКАЗАНО В ПИСЬМЕННОЙ ФОРМЕ,
|
||||||
|
ПРАВООБЛАДАТЕЛИ И (ИЛИ) ТРЕТЬИ ЛИЦА ПРЕДОСТАВЛЯЮТ ПРОГРАММУ "КАК ЕСТЬ", БЕЗ
|
||||||
|
КАКИХ-ЛИБО ЯВНЫХ ИЛИ ПОДРАЗУМЕВАЕМЫХ ГАРАНТИЙ, ВКЛЮЧАЯ ГАРАНТИИ ПРИГОДНОСТИ ДЛЯ
|
||||||
|
КОНКРЕТНЫХ ЦЕЛЕЙ, НО НЕ ОГРАНИЧИВАЯСЬ ИМИ. ВЕСЬ РИСК, СВЯЗАННЫЙ С КАЧЕСТВОМ И
|
||||||
|
ПРОИЗВОДИТЕЛЬНОСТЬЮ ПРОГРАММЫ, ВОЗЛАГАЕТСЯ НА ВАС. ЕСЛИ В ПРОГРАММЕ БУДУТ
|
||||||
|
ВЫЯВЛЕНЫ НЕДОСТАТКИ, ВЫ ПРИНИМАЕТЕ НА СЕБЯ СТОИМОСТЬ ВСЕГО НЕОБХОДИМОГО
|
||||||
|
ОБСЛУЖИВАНИЯ, РЕМОНТА ИЛИ ИСПРАВЛЕНИЯ.
|
||||||
|
|
||||||
|
16. Ограничение ответственности.
|
||||||
|
|
||||||
|
ЕСЛИ ИНОЕ НЕ ПРЕДУСМОТРЕНО ДЕЙСТВУЮЩИМ ЗАКОНОДАТЕЛЬСТВОМ ИЛИ СОГЛАШЕНИЕМ СТОРОН,
|
||||||
|
ЗАКЛЮЧЕННЫМ В ПИСЬМЕННОЙ ФОРМЕ, ПРАВООБЛАДАТЕЛЬ ИЛИ ИНОЕ ЛИЦО, КОТОРОЕ ВНОСИТ
|
||||||
|
ИЗМЕНЕНИЯ В ПРОГРАММУ И (ИЛИ) ПЕРЕДАЕТ ЕЁ НА УСЛОВИЯХ, СФОРМУЛИРОВАННЫХ ВЫШЕ, НЕ
|
||||||
|
МОЖЕТ НЕСТИ ОТВЕТСТВЕННОСТЬ ПЕРЕД ВАМИ ЗА ПРИЧИНЕННЫЙ УЩЕРБ, ВКЛЮЧАЯ УЩЕРБ
|
||||||
|
ОБЩЕГО ЛИБО КОНКРЕТНОГО ХАРАКТЕРА, ПРИЧИНЕННЫЙ СЛУЧАЙНО ИЛИ ЯВЛЯЮЩИЙСЯ
|
||||||
|
СЛЕДСТВИЕМ ИСПОЛЬЗОВАНИЯ ПРОГРАММЫ ЛИБО НЕВОЗМОЖНОСТИ ЕЁ ИСПОЛЬЗОВАНИЯ (В ТОМ
|
||||||
|
ЧИСЛЕ ЗА УНИЧТОЖЕНИЕ ИЛИ МОДИФИКАЦИЮ ИНФОРМАЦИИ, ЛИБО УБЫТКИ, ПОНЕСЕННЫЕ ВАМИ
|
||||||
|
ИЛИ ТРЕТЬИМИ ЛИЦАМИ, ЛИБО СБОИ ПРОГРАММЫ ПРИ ВЗАИМОДЕЙСТВИИ С ДРУГИМ ПРОГРАММНЫМ
|
||||||
|
ОБЕСПЕЧЕНИЕМ), В ТОМ ЧИСЛЕ И В СЛУЧАЯХ, КОГДА ПРАВООБЛАДАТЕЛЬ ИЛИ ТРЕТЬЕ ЛИЦО
|
||||||
|
ПРЕДУПРЕЖДЕНЫ О ВОЗМОЖНОСТИ ПРИЧИНЕНИЯ ТАКИХ УБЫТКОВ.
|
||||||
|
|
||||||
|
17. Толкование разделов 15 и 16.
|
||||||
|
|
||||||
|
Если отказ от гарантии и ограничение ответственности, представленные выше, по
|
||||||
|
закону не могут быть применены в соответствии с их условиями, суды,
|
||||||
|
рассматривающие спор, должны применить действующий закон, который в наибольшей
|
||||||
|
степени предусматривает абсолютный отказ от всей гражданской ответственности в
|
||||||
|
связи с Программой, за исключением случаев, когда гарантия или принятие на себя
|
||||||
|
ответственности за копию программы предоставляется за плату.
|
||||||
|
|
||||||
|
КОНЕЦ ОПРЕДЕЛЕНИЙ И УСЛОВИЙ
|
||||||
|
|
||||||
|
Порядок применения условий Лицензии к Вашим программам
|
||||||
|
|
||||||
|
Если Вы разрабатываете новую программу и хотите, чтобы её использование принесло
|
||||||
|
максимальную пользу обществу, наилучший способ достичь этого -- сделать её
|
||||||
|
свободной, чтобы все могли распространять и изменять её на условиях настоящей
|
||||||
|
Лицензии.
|
||||||
|
|
||||||
|
Для этого сделайте так, чтобы программа содержала в себе описанные ниже
|
||||||
|
уведомления. Самым надежным способом это сделать является включение их в начало
|
||||||
|
каждого файла исходного текста, чтобы наиболее эффективным образом сообщить об
|
||||||
|
отсутствии гарантий; каждый файл должен иметь по меньшей мере одну строку с
|
||||||
|
оповещением об авторских правах и указанием на то, где находится полный текст
|
||||||
|
уведомлений.
|
||||||
|
|
||||||
|
<Строка с названием Программы и информацией о её назначении.>
|
||||||
|
Copyright © <год выпуска программы в свет> <имя автора>
|
||||||
|
|
||||||
|
Эта программа является свободным программным обеспечением: Вы можете
|
||||||
|
распространять её и (или) изменять, соблюдая условия Сетевой Публичной
|
||||||
|
Лицензии Vitastor, опубликованной автором Vitastor, либо редакции 1.1
|
||||||
|
Лицензии, либо (на Ваше усмотрение) любой редакции, выпущенной позже.
|
||||||
|
|
||||||
|
Эта программа распространяется в расчете на то, что она окажется полезной,
|
||||||
|
но БЕЗ КАКИХ-ЛИБО ГАРАНТИЙ, включая подразумеваемую гарантию КАЧЕСТВА либо
|
||||||
|
ПРИГОДНОСТИ ДЛЯ ОПРЕДЕЛЕННЫХ ЦЕЛЕЙ. Ознакомьтесь с Сетевой Публичной
|
||||||
|
Лицензией Vitastor для получения более подробной информации.
|
||||||
|
|
||||||
|
Также добавьте информацию о том, как связаться с Вами посредством электронной
|
||||||
|
или обычной почты.
|
||||||
|
|
||||||
|
Если ваша программа взаимодействует с пользователями удаленно через
|
||||||
|
компьютерную сеть, Вы также должны убедиться, что обеспечили её пользователям
|
||||||
|
возможность получить её исходные тексты. Например, если Ваша программа является
|
||||||
|
веб-приложением, её интерфейс может отображать ссылку "Исходные коды", которая
|
||||||
|
указывает на архив с текстом. Существует много способов, которыми Вы можете
|
||||||
|
распространять исходные тексты, для разных программ подходят разные решения;
|
||||||
|
ознакомьтесь с разделом 13 для того, чтобы узнать конкретные требования.
|
@@ -61,7 +61,7 @@ modification follow.
|
|||||||
|
|
||||||
0. Definitions.
|
0. Definitions.
|
||||||
|
|
||||||
"This License" refers to version 1 of the Vitastor Network Public License.
|
"This License" refers to version 1.1 of the Vitastor Network Public License.
|
||||||
|
|
||||||
"Copyright" also means copyright-like laws that apply to other kinds of
|
"Copyright" also means copyright-like laws that apply to other kinds of
|
||||||
works, such as semiconductor masks.
|
works, such as semiconductor masks.
|
||||||
@@ -629,7 +629,7 @@ the "copyright" line and a pointer to where the full notice is found.
|
|||||||
|
|
||||||
This program is free software: you can redistribute it and/or modify
|
This program is free software: you can redistribute it and/or modify
|
||||||
it under the terms of the Vitastor Network Public License as published by
|
it under the terms of the Vitastor Network Public License as published by
|
||||||
the Vitastor Author, either version 1 of the License, or
|
the Vitastor Author, either version 1.1 of the License, or
|
||||||
(at your option) any later version.
|
(at your option) any later version.
|
||||||
|
|
||||||
This program is distributed in the hope that it will be useful,
|
This program is distributed in the hope that it will be useful,
|
||||||
|
@@ -18,15 +18,19 @@ ENV CSI_ENDPOINT=""
|
|||||||
|
|
||||||
RUN apt-get update && \
|
RUN apt-get update && \
|
||||||
apt-get install -y wget && \
|
apt-get install -y wget && \
|
||||||
wget -q -O /etc/apt/trusted.gpg.d/vitastor.gpg https://vitastor.io/debian/pubkey.gpg && \
|
|
||||||
(echo deb http://vitastor.io/debian buster main > /etc/apt/sources.list.d/vitastor.list) && \
|
|
||||||
(echo deb http://deb.debian.org/debian buster-backports main > /etc/apt/sources.list.d/backports.list) && \
|
(echo deb http://deb.debian.org/debian buster-backports main > /etc/apt/sources.list.d/backports.list) && \
|
||||||
(echo "APT::Install-Recommends false;" > /etc/apt/apt.conf) && \
|
(echo "APT::Install-Recommends false;" > /etc/apt/apt.conf) && \
|
||||||
apt-get update && \
|
apt-get update && \
|
||||||
apt-get install -y e2fsprogs xfsprogs vitastor kmod && \
|
apt-get install -y e2fsprogs xfsprogs kmod && \
|
||||||
apt-get clean && \
|
apt-get clean && \
|
||||||
(echo options nbd nbds_max=128 > /etc/modprobe.d/nbd.conf)
|
(echo options nbd nbds_max=128 > /etc/modprobe.d/nbd.conf)
|
||||||
|
|
||||||
COPY --from=build /app/vitastor-csi /bin/
|
COPY --from=build /app/vitastor-csi /bin/
|
||||||
|
|
||||||
|
RUN (echo deb http://vitastor.io/debian buster main > /etc/apt/sources.list.d/vitastor.list) && \
|
||||||
|
wget -q -O /etc/apt/trusted.gpg.d/vitastor.gpg https://vitastor.io/debian/pubkey.gpg && \
|
||||||
|
apt-get update && \
|
||||||
|
apt-get install -y vitastor-client && \
|
||||||
|
apt-get clean
|
||||||
|
|
||||||
ENTRYPOINT ["/bin/vitastor-csi"]
|
ENTRYPOINT ["/bin/vitastor-csi"]
|
||||||
|
@@ -1,4 +1,4 @@
|
|||||||
VERSION ?= v0.7.0
|
VERSION ?= v0.8.9
|
||||||
|
|
||||||
all: build push
|
all: build push
|
||||||
|
|
||||||
|
@@ -49,7 +49,7 @@ spec:
|
|||||||
capabilities:
|
capabilities:
|
||||||
add: ["SYS_ADMIN"]
|
add: ["SYS_ADMIN"]
|
||||||
allowPrivilegeEscalation: true
|
allowPrivilegeEscalation: true
|
||||||
image: vitalif/vitastor-csi:v0.7.0
|
image: vitalif/vitastor-csi:v0.8.9
|
||||||
args:
|
args:
|
||||||
- "--node=$(NODE_ID)"
|
- "--node=$(NODE_ID)"
|
||||||
- "--endpoint=$(CSI_ENDPOINT)"
|
- "--endpoint=$(CSI_ENDPOINT)"
|
||||||
@@ -102,7 +102,7 @@ spec:
|
|||||||
- "--health-port=9898"
|
- "--health-port=9898"
|
||||||
env:
|
env:
|
||||||
- name: CSI_ENDPOINT
|
- name: CSI_ENDPOINT
|
||||||
value: unix://csi/csi.sock
|
value: unix:///csi/csi.sock
|
||||||
volumeMounts:
|
volumeMounts:
|
||||||
- mountPath: /csi
|
- mountPath: /csi
|
||||||
name: socket-dir
|
name: socket-dir
|
||||||
|
@@ -116,7 +116,7 @@ spec:
|
|||||||
privileged: true
|
privileged: true
|
||||||
capabilities:
|
capabilities:
|
||||||
add: ["SYS_ADMIN"]
|
add: ["SYS_ADMIN"]
|
||||||
image: vitalif/vitastor-csi:v0.7.0
|
image: vitalif/vitastor-csi:v0.8.9
|
||||||
args:
|
args:
|
||||||
- "--node=$(NODE_ID)"
|
- "--node=$(NODE_ID)"
|
||||||
- "--endpoint=$(CSI_ENDPOINT)"
|
- "--endpoint=$(CSI_ENDPOINT)"
|
||||||
|
17
csi/go.mod
17
csi/go.mod
@@ -4,25 +4,10 @@ go 1.15
|
|||||||
|
|
||||||
require (
|
require (
|
||||||
github.com/container-storage-interface/spec v1.4.0
|
github.com/container-storage-interface/spec v1.4.0
|
||||||
github.com/coreos/bbolt v0.0.0-00010101000000-000000000000 // indirect
|
|
||||||
github.com/coreos/etcd v3.3.25+incompatible // indirect
|
|
||||||
github.com/coreos/go-semver v0.3.0 // indirect
|
|
||||||
github.com/coreos/go-systemd v0.0.0-20191104093116-d3cd4ed1dbcf // indirect
|
|
||||||
github.com/coreos/pkg v0.0.0-20180928190104-399ea9e2e55f // indirect
|
|
||||||
github.com/dustin/go-humanize v1.0.0 // indirect
|
|
||||||
github.com/golang/glog v0.0.0-20160126235308-23def4e6c14b
|
github.com/golang/glog v0.0.0-20160126235308-23def4e6c14b
|
||||||
github.com/gorilla/websocket v1.4.2 // indirect
|
|
||||||
github.com/grpc-ecosystem/go-grpc-middleware v1.3.0 // indirect
|
|
||||||
github.com/grpc-ecosystem/go-grpc-prometheus v1.2.0 // indirect
|
|
||||||
github.com/grpc-ecosystem/grpc-gateway v1.16.0 // indirect
|
|
||||||
github.com/jonboulle/clockwork v0.2.2 // indirect
|
|
||||||
github.com/kubernetes-csi/csi-lib-utils v0.9.1
|
github.com/kubernetes-csi/csi-lib-utils v0.9.1
|
||||||
github.com/soheilhy/cmux v0.1.5 // indirect
|
|
||||||
github.com/tmc/grpc-websocket-proxy v0.0.0-20201229170055-e5319fda7802 // indirect
|
|
||||||
github.com/xiang90/probing v0.0.0-20190116061207-43a291ad63a2 // indirect
|
|
||||||
go.etcd.io/bbolt v0.0.0-00010101000000-000000000000 // indirect
|
|
||||||
go.etcd.io/etcd v3.3.25+incompatible
|
|
||||||
golang.org/x/net v0.0.0-20201202161906-c7110b5ffcbb
|
golang.org/x/net v0.0.0-20201202161906-c7110b5ffcbb
|
||||||
|
golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1 // indirect
|
||||||
google.golang.org/grpc v1.33.1
|
google.golang.org/grpc v1.33.1
|
||||||
k8s.io/klog v1.0.0
|
k8s.io/klog v1.0.0
|
||||||
k8s.io/utils v0.0.0-20210305010621-2afb4311ab10
|
k8s.io/utils v0.0.0-20210305010621-2afb4311ab10
|
||||||
|
82
csi/go.sum
82
csi/go.sum
@@ -31,14 +31,11 @@ github.com/alecthomas/template v0.0.0-20160405071501-a0175ee3bccc/go.mod h1:LOuy
|
|||||||
github.com/alecthomas/template v0.0.0-20190718012654-fb15b899a751/go.mod h1:LOuyumcjzFXgccqObfd/Ljyb9UuFJ6TxHnclSeseNhc=
|
github.com/alecthomas/template v0.0.0-20190718012654-fb15b899a751/go.mod h1:LOuyumcjzFXgccqObfd/Ljyb9UuFJ6TxHnclSeseNhc=
|
||||||
github.com/alecthomas/units v0.0.0-20151022065526-2efee857e7cf/go.mod h1:ybxpYRFXyAe+OPACYpWeL0wqObRcbAqCMya13uyzqw0=
|
github.com/alecthomas/units v0.0.0-20151022065526-2efee857e7cf/go.mod h1:ybxpYRFXyAe+OPACYpWeL0wqObRcbAqCMya13uyzqw0=
|
||||||
github.com/alecthomas/units v0.0.0-20190717042225-c3de453c63f4/go.mod h1:ybxpYRFXyAe+OPACYpWeL0wqObRcbAqCMya13uyzqw0=
|
github.com/alecthomas/units v0.0.0-20190717042225-c3de453c63f4/go.mod h1:ybxpYRFXyAe+OPACYpWeL0wqObRcbAqCMya13uyzqw0=
|
||||||
github.com/antihax/optional v1.0.0/go.mod h1:uupD/76wgC+ih3iEmQUL+0Ugr19nfwCT1kdvxnR2qWY=
|
|
||||||
github.com/beorn7/perks v0.0.0-20180321164747-3a771d992973/go.mod h1:Dwedo/Wpr24TaqPxmxbtue+5NUziq4I4S80YR8gNf3Q=
|
github.com/beorn7/perks v0.0.0-20180321164747-3a771d992973/go.mod h1:Dwedo/Wpr24TaqPxmxbtue+5NUziq4I4S80YR8gNf3Q=
|
||||||
github.com/beorn7/perks v1.0.0/go.mod h1:KWe93zE9D1o94FZ5RNwFwVgaQK1VOXiVxmqh+CedLV8=
|
github.com/beorn7/perks v1.0.0/go.mod h1:KWe93zE9D1o94FZ5RNwFwVgaQK1VOXiVxmqh+CedLV8=
|
||||||
github.com/beorn7/perks v1.0.1 h1:VlbKKnNfV8bJzeqoa4cOKqO6bYr3WgKZxO8Z16+hsOM=
|
|
||||||
github.com/beorn7/perks v1.0.1/go.mod h1:G2ZrVWU2WbWT9wwq4/hrbKbnv/1ERSJQ0ibhJ6rlkpw=
|
github.com/beorn7/perks v1.0.1/go.mod h1:G2ZrVWU2WbWT9wwq4/hrbKbnv/1ERSJQ0ibhJ6rlkpw=
|
||||||
github.com/blang/semver v3.5.0+incompatible/go.mod h1:kRBLl5iJ+tD4TcOOxsy/0fnwebNt5EWlYSAyrTnjyyk=
|
github.com/blang/semver v3.5.0+incompatible/go.mod h1:kRBLl5iJ+tD4TcOOxsy/0fnwebNt5EWlYSAyrTnjyyk=
|
||||||
github.com/census-instrumentation/opencensus-proto v0.2.1/go.mod h1:f6KPmirojxKA12rnyqOA5BBL4O983OfeGPqjHWSTneU=
|
github.com/census-instrumentation/opencensus-proto v0.2.1/go.mod h1:f6KPmirojxKA12rnyqOA5BBL4O983OfeGPqjHWSTneU=
|
||||||
github.com/cespare/xxhash/v2 v2.1.1 h1:6MnRN8NT7+YBpUIWxHtefFZOKTAPgGjpQSxqLNn0+qY=
|
|
||||||
github.com/cespare/xxhash/v2 v2.1.1/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs=
|
github.com/cespare/xxhash/v2 v2.1.1/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs=
|
||||||
github.com/chzyer/logex v1.1.10/go.mod h1:+Ywpsq7O8HXn0nuIou7OrIPyXbp3wmkHB+jjWRnGsAI=
|
github.com/chzyer/logex v1.1.10/go.mod h1:+Ywpsq7O8HXn0nuIou7OrIPyXbp3wmkHB+jjWRnGsAI=
|
||||||
github.com/chzyer/readline v0.0.0-20180603132655-2972be24d48e/go.mod h1:nSuG5e5PlCu98SY8svDHJxuZscDgtXS6KTTbou5AhLI=
|
github.com/chzyer/readline v0.0.0-20180603132655-2972be24d48e/go.mod h1:nSuG5e5PlCu98SY8svDHJxuZscDgtXS6KTTbou5AhLI=
|
||||||
@@ -46,25 +43,12 @@ github.com/chzyer/test v0.0.0-20180213035817-a1ea475d72b1/go.mod h1:Q3SI9o4m/ZMn
|
|||||||
github.com/container-storage-interface/spec v1.2.0/go.mod h1:6URME8mwIBbpVyZV93Ce5St17xBiQJQY67NDsuohiy4=
|
github.com/container-storage-interface/spec v1.2.0/go.mod h1:6URME8mwIBbpVyZV93Ce5St17xBiQJQY67NDsuohiy4=
|
||||||
github.com/container-storage-interface/spec v1.4.0 h1:ozAshSKxpJnYUfmkpZCTYyF/4MYeYlhdXbAvPvfGmkg=
|
github.com/container-storage-interface/spec v1.4.0 h1:ozAshSKxpJnYUfmkpZCTYyF/4MYeYlhdXbAvPvfGmkg=
|
||||||
github.com/container-storage-interface/spec v1.4.0/go.mod h1:6URME8mwIBbpVyZV93Ce5St17xBiQJQY67NDsuohiy4=
|
github.com/container-storage-interface/spec v1.4.0/go.mod h1:6URME8mwIBbpVyZV93Ce5St17xBiQJQY67NDsuohiy4=
|
||||||
github.com/coreos/bbolt v1.3.5 h1:XFv7xaq7701j8ZSEzR28VohFYSlyakMyqNMU5FQH6Ac=
|
|
||||||
github.com/coreos/bbolt v1.3.5/go.mod h1:G5EMThwa9y8QZGBClrRx5EY+Yw9kAhnjy3bSjsnlVTQ=
|
|
||||||
github.com/coreos/etcd v3.3.25+incompatible h1:0GQEw6h3YnuOVdtwygkIfJ+Omx0tZ8/QkVyXI4LkbeY=
|
|
||||||
github.com/coreos/etcd v3.3.25+incompatible/go.mod h1:uF7uidLiAD3TWHmW31ZFd/JWoc32PjwdhPthX9715RE=
|
|
||||||
github.com/coreos/go-semver v0.3.0 h1:wkHLiw0WNATZnSG7epLsujiMCgPAc9xhjJ4tgnAxmfM=
|
|
||||||
github.com/coreos/go-semver v0.3.0/go.mod h1:nnelYz7RCh+5ahJtPPxZlU+153eP4D4r3EedlOD2RNk=
|
|
||||||
github.com/coreos/go-systemd v0.0.0-20191104093116-d3cd4ed1dbcf h1:iW4rZ826su+pqaw19uhpSCzhj44qo35pNgKFGqzDKkU=
|
|
||||||
github.com/coreos/go-systemd v0.0.0-20191104093116-d3cd4ed1dbcf/go.mod h1:F5haX7vjVVG0kc13fIWeqUViNPyEJxv/OmvnBo0Yme4=
|
|
||||||
github.com/coreos/pkg v0.0.0-20180928190104-399ea9e2e55f h1:lBNOc5arjvs8E5mO2tbpBpLoyyu8B6e44T7hJy6potg=
|
|
||||||
github.com/coreos/pkg v0.0.0-20180928190104-399ea9e2e55f/go.mod h1:E3G3o1h8I7cfcXa63jLwjI0eiQQMgzzUDFVpN/nH/eA=
|
|
||||||
github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
|
github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
|
||||||
github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c=
|
github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c=
|
||||||
github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
|
github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
|
||||||
github.com/dgrijalva/jwt-go v3.2.0+incompatible h1:7qlOGliEKZXTDg6OTjfoBKDXWrumCAMpl/TFQ4/5kLM=
|
|
||||||
github.com/dgrijalva/jwt-go v3.2.0+incompatible/go.mod h1:E3ru+11k8xSBh+hMPgOLZmtrrCbhqsmaPHjLKYnJCaQ=
|
github.com/dgrijalva/jwt-go v3.2.0+incompatible/go.mod h1:E3ru+11k8xSBh+hMPgOLZmtrrCbhqsmaPHjLKYnJCaQ=
|
||||||
github.com/docker/spdystream v0.0.0-20160310174837-449fdfce4d96/go.mod h1:Qh8CwZgvJUkLughtfhJv5dyTYa91l1fOUCrgjqmcifM=
|
github.com/docker/spdystream v0.0.0-20160310174837-449fdfce4d96/go.mod h1:Qh8CwZgvJUkLughtfhJv5dyTYa91l1fOUCrgjqmcifM=
|
||||||
github.com/docopt/docopt-go v0.0.0-20180111231733-ee0de3bc6815/go.mod h1:WwZ+bS3ebgob9U8Nd0kOddGdZWjyMGR8Wziv+TBNwSE=
|
github.com/docopt/docopt-go v0.0.0-20180111231733-ee0de3bc6815/go.mod h1:WwZ+bS3ebgob9U8Nd0kOddGdZWjyMGR8Wziv+TBNwSE=
|
||||||
github.com/dustin/go-humanize v1.0.0 h1:VSnTsYCnlFHaM2/igO1h6X3HA71jcobQuxemgkq4zYo=
|
|
||||||
github.com/dustin/go-humanize v1.0.0/go.mod h1:HtrtbFcZ19U5GC7JDqmcUSB87Iq5E25KnS6fMYU6eOk=
|
|
||||||
github.com/elazarl/goproxy v0.0.0-20180725130230-947c36da3153/go.mod h1:/Zj4wYkgs4iZTTu3o/KG3Itv/qCCa8VVMlb3i9OVuzc=
|
github.com/elazarl/goproxy v0.0.0-20180725130230-947c36da3153/go.mod h1:/Zj4wYkgs4iZTTu3o/KG3Itv/qCCa8VVMlb3i9OVuzc=
|
||||||
github.com/emicklei/go-restful v0.0.0-20170410110728-ff4f55a20633/go.mod h1:otzb+WCGbkyDHkqmQmT5YD2WR4BBwUdeQoFo8l/7tVs=
|
github.com/emicklei/go-restful v0.0.0-20170410110728-ff4f55a20633/go.mod h1:otzb+WCGbkyDHkqmQmT5YD2WR4BBwUdeQoFo8l/7tVs=
|
||||||
github.com/envoyproxy/go-control-plane v0.9.0/go.mod h1:YTl/9mNaCwkRvm6d1a2C3ymFceY/DCBVvsKhRF0iEA4=
|
github.com/envoyproxy/go-control-plane v0.9.0/go.mod h1:YTl/9mNaCwkRvm6d1a2C3ymFceY/DCBVvsKhRF0iEA4=
|
||||||
@@ -73,7 +57,6 @@ github.com/evanphx/json-patch v4.9.0+incompatible/go.mod h1:50XU6AFN0ol/bzJsmQLi
|
|||||||
github.com/fsnotify/fsnotify v1.4.7/go.mod h1:jwhsz4b93w/PPRr/qN1Yymfu8t87LnFCMoQvtojpjFo=
|
github.com/fsnotify/fsnotify v1.4.7/go.mod h1:jwhsz4b93w/PPRr/qN1Yymfu8t87LnFCMoQvtojpjFo=
|
||||||
github.com/fsnotify/fsnotify v1.4.9/go.mod h1:znqG4EE+3YCdAaPaxE2ZRY/06pZUdp0tY4IgpuI1SZQ=
|
github.com/fsnotify/fsnotify v1.4.9/go.mod h1:znqG4EE+3YCdAaPaxE2ZRY/06pZUdp0tY4IgpuI1SZQ=
|
||||||
github.com/ghodss/yaml v0.0.0-20150909031657-73d445a93680/go.mod h1:4dBDuWmgqj2HViK6kFavaiC9ZROes6MMH2rRYeMEF04=
|
github.com/ghodss/yaml v0.0.0-20150909031657-73d445a93680/go.mod h1:4dBDuWmgqj2HViK6kFavaiC9ZROes6MMH2rRYeMEF04=
|
||||||
github.com/ghodss/yaml v1.0.0/go.mod h1:4dBDuWmgqj2HViK6kFavaiC9ZROes6MMH2rRYeMEF04=
|
|
||||||
github.com/go-gl/glfw/v3.3/glfw v0.0.0-20191125211704-12ad95a8df72/go.mod h1:tQ2UAYgL5IevRw8kRxooKSPJfGvJ9fJQFa0TUsXzTg8=
|
github.com/go-gl/glfw/v3.3/glfw v0.0.0-20191125211704-12ad95a8df72/go.mod h1:tQ2UAYgL5IevRw8kRxooKSPJfGvJ9fJQFa0TUsXzTg8=
|
||||||
github.com/go-kit/kit v0.8.0/go.mod h1:xBxKIO96dXMWWy0MnWVtmwkA9/13aqxPnvrjFYMA2as=
|
github.com/go-kit/kit v0.8.0/go.mod h1:xBxKIO96dXMWWy0MnWVtmwkA9/13aqxPnvrjFYMA2as=
|
||||||
github.com/go-kit/kit v0.9.0/go.mod h1:xBxKIO96dXMWWy0MnWVtmwkA9/13aqxPnvrjFYMA2as=
|
github.com/go-kit/kit v0.9.0/go.mod h1:xBxKIO96dXMWWy0MnWVtmwkA9/13aqxPnvrjFYMA2as=
|
||||||
@@ -88,14 +71,10 @@ github.com/go-openapi/spec v0.0.0-20160808142527-6aced65f8501/go.mod h1:J8+jY1nA
|
|||||||
github.com/go-openapi/swag v0.0.0-20160704191624-1d0bd113de87/go.mod h1:DXUve3Dpr1UfpPtxFw+EFuQ41HhCWZfha5jSVRG7C7I=
|
github.com/go-openapi/swag v0.0.0-20160704191624-1d0bd113de87/go.mod h1:DXUve3Dpr1UfpPtxFw+EFuQ41HhCWZfha5jSVRG7C7I=
|
||||||
github.com/go-stack/stack v1.8.0/go.mod h1:v0f6uXyyMGvRgIKkXu+yp6POWl0qKG85gN/melR3HDY=
|
github.com/go-stack/stack v1.8.0/go.mod h1:v0f6uXyyMGvRgIKkXu+yp6POWl0qKG85gN/melR3HDY=
|
||||||
github.com/gogo/protobuf v1.1.1/go.mod h1:r8qH/GZQm5c6nD/R0oafs1akxWv10x8SbQlK7atdtwQ=
|
github.com/gogo/protobuf v1.1.1/go.mod h1:r8qH/GZQm5c6nD/R0oafs1akxWv10x8SbQlK7atdtwQ=
|
||||||
github.com/gogo/protobuf v1.3.1 h1:DqDEcV5aeaTmdFBePNpYsp3FlcVH/2ISVVM9Qf8PSls=
|
|
||||||
github.com/gogo/protobuf v1.3.1/go.mod h1:SlYgWuQ5SjCEi6WLHjHCa1yvBfUnHcTbrrZtXPKa29o=
|
github.com/gogo/protobuf v1.3.1/go.mod h1:SlYgWuQ5SjCEi6WLHjHCa1yvBfUnHcTbrrZtXPKa29o=
|
||||||
github.com/gogo/protobuf v1.3.2 h1:Ov1cvc58UF3b5XjBnZv7+opcTcQFZebYjWzi34vdm4Q=
|
|
||||||
github.com/gogo/protobuf v1.3.2/go.mod h1:P1XiOD3dCwIKUDQYPy72D8LYyHL2YPYrpS2s69NZV8Q=
|
|
||||||
github.com/golang/glog v0.0.0-20160126235308-23def4e6c14b h1:VKtxabqXZkF25pY9ekfRL6a582T4P37/31XEstQ5p58=
|
github.com/golang/glog v0.0.0-20160126235308-23def4e6c14b h1:VKtxabqXZkF25pY9ekfRL6a582T4P37/31XEstQ5p58=
|
||||||
github.com/golang/glog v0.0.0-20160126235308-23def4e6c14b/go.mod h1:SBH7ygxi8pfUlaOkMMuAQtPIUF8ecWP5IEl/CR7VP2Q=
|
github.com/golang/glog v0.0.0-20160126235308-23def4e6c14b/go.mod h1:SBH7ygxi8pfUlaOkMMuAQtPIUF8ecWP5IEl/CR7VP2Q=
|
||||||
github.com/golang/groupcache v0.0.0-20190702054246-869f871628b6/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc=
|
github.com/golang/groupcache v0.0.0-20190702054246-869f871628b6/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc=
|
||||||
github.com/golang/groupcache v0.0.0-20191227052852-215e87163ea7 h1:5ZkaAPbicIKTF2I64qf5Fh8Aa83Q/dnOafMYV0OMwjA=
|
|
||||||
github.com/golang/groupcache v0.0.0-20191227052852-215e87163ea7/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc=
|
github.com/golang/groupcache v0.0.0-20191227052852-215e87163ea7/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc=
|
||||||
github.com/golang/mock v1.1.1/go.mod h1:oTYuIxOrZwtPieC+H1uAHpcLFnEyAGVDL/k47Jfbm0A=
|
github.com/golang/mock v1.1.1/go.mod h1:oTYuIxOrZwtPieC+H1uAHpcLFnEyAGVDL/k47Jfbm0A=
|
||||||
github.com/golang/mock v1.2.0/go.mod h1:oTYuIxOrZwtPieC+H1uAHpcLFnEyAGVDL/k47Jfbm0A=
|
github.com/golang/mock v1.2.0/go.mod h1:oTYuIxOrZwtPieC+H1uAHpcLFnEyAGVDL/k47Jfbm0A=
|
||||||
@@ -113,7 +92,6 @@ github.com/golang/protobuf v1.4.1/go.mod h1:U8fpvMrcmy5pZrNK1lt4xCsGvpyWQ/VVv6QD
|
|||||||
github.com/golang/protobuf v1.4.2 h1:+Z5KGCizgyZCbGh1KZqA0fcLLkwbsjIzS4aV2v7wJX0=
|
github.com/golang/protobuf v1.4.2 h1:+Z5KGCizgyZCbGh1KZqA0fcLLkwbsjIzS4aV2v7wJX0=
|
||||||
github.com/golang/protobuf v1.4.2/go.mod h1:oDoupMAO8OvCJWAcko0GGGIgR6R6ocIYbsSw735rRwI=
|
github.com/golang/protobuf v1.4.2/go.mod h1:oDoupMAO8OvCJWAcko0GGGIgR6R6ocIYbsSw735rRwI=
|
||||||
github.com/google/btree v0.0.0-20180813153112-4030bb1f1f0c/go.mod h1:lNA+9X1NB3Zf8V7Ke586lFgjr2dZNuvo3lPJSGZ5JPQ=
|
github.com/google/btree v0.0.0-20180813153112-4030bb1f1f0c/go.mod h1:lNA+9X1NB3Zf8V7Ke586lFgjr2dZNuvo3lPJSGZ5JPQ=
|
||||||
github.com/google/btree v1.0.0 h1:0udJVsspx3VBr5FwtLhQQtuAsVc79tTq0ocGIPAU6qo=
|
|
||||||
github.com/google/btree v1.0.0/go.mod h1:lNA+9X1NB3Zf8V7Ke586lFgjr2dZNuvo3lPJSGZ5JPQ=
|
github.com/google/btree v1.0.0/go.mod h1:lNA+9X1NB3Zf8V7Ke586lFgjr2dZNuvo3lPJSGZ5JPQ=
|
||||||
github.com/google/go-cmp v0.2.0/go.mod h1:oXzfMopK8JAjlY9xF4vHSVASa0yLyX7SntLO5aqRK0M=
|
github.com/google/go-cmp v0.2.0/go.mod h1:oXzfMopK8JAjlY9xF4vHSVASa0yLyX7SntLO5aqRK0M=
|
||||||
github.com/google/go-cmp v0.3.0/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU=
|
github.com/google/go-cmp v0.3.0/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU=
|
||||||
@@ -127,38 +105,24 @@ github.com/google/pprof v0.0.0-20181206194817-3ea8567a2e57/go.mod h1:zfwlbNMJ+OI
|
|||||||
github.com/google/pprof v0.0.0-20190515194954-54271f7e092f/go.mod h1:zfwlbNMJ+OItoe0UupaVj+oy1omPYYDuagoSzA8v9mc=
|
github.com/google/pprof v0.0.0-20190515194954-54271f7e092f/go.mod h1:zfwlbNMJ+OItoe0UupaVj+oy1omPYYDuagoSzA8v9mc=
|
||||||
github.com/google/pprof v0.0.0-20191218002539-d4f498aebedc/go.mod h1:ZgVRPoUq/hfqzAqh7sHMqb3I9Rq5C59dIz2SbBwJ4eM=
|
github.com/google/pprof v0.0.0-20191218002539-d4f498aebedc/go.mod h1:ZgVRPoUq/hfqzAqh7sHMqb3I9Rq5C59dIz2SbBwJ4eM=
|
||||||
github.com/google/renameio v0.1.0/go.mod h1:KWCgfxg9yswjAJkECMjeO8J8rahYeXnNhOm40UhjYkI=
|
github.com/google/renameio v0.1.0/go.mod h1:KWCgfxg9yswjAJkECMjeO8J8rahYeXnNhOm40UhjYkI=
|
||||||
github.com/google/uuid v1.1.1 h1:Gkbcsh/GbpXz7lPftLA3P6TYMwjCLYm83jiFQZF/3gY=
|
|
||||||
github.com/google/uuid v1.1.1/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo=
|
github.com/google/uuid v1.1.1/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo=
|
||||||
github.com/googleapis/gax-go/v2 v2.0.4/go.mod h1:0Wqv26UfaUD9n4G6kQubkQ+KchISgw+vpHVxEJEs9eg=
|
github.com/googleapis/gax-go/v2 v2.0.4/go.mod h1:0Wqv26UfaUD9n4G6kQubkQ+KchISgw+vpHVxEJEs9eg=
|
||||||
github.com/googleapis/gax-go/v2 v2.0.5/go.mod h1:DWXyrwAJ9X0FpwwEdw+IPEYBICEFu5mhpdKc/us6bOk=
|
github.com/googleapis/gax-go/v2 v2.0.5/go.mod h1:DWXyrwAJ9X0FpwwEdw+IPEYBICEFu5mhpdKc/us6bOk=
|
||||||
github.com/googleapis/gnostic v0.4.1/go.mod h1:LRhVm6pbyptWbWbuZ38d1eyptfvIytN3ir6b65WBswg=
|
github.com/googleapis/gnostic v0.4.1/go.mod h1:LRhVm6pbyptWbWbuZ38d1eyptfvIytN3ir6b65WBswg=
|
||||||
github.com/gorilla/websocket v1.4.2 h1:+/TMaTYc4QFitKJxsQ7Yye35DkWvkdLcvGKqM+x0Ufc=
|
|
||||||
github.com/gorilla/websocket v1.4.2/go.mod h1:YR8l580nyteQvAITg2hZ9XVh4b55+EU/adAjf1fMHhE=
|
|
||||||
github.com/gregjones/httpcache v0.0.0-20180305231024-9cad4c3443a7/go.mod h1:FecbI9+v66THATjSRHfNgh1IVFe/9kFxbXtjV0ctIMA=
|
github.com/gregjones/httpcache v0.0.0-20180305231024-9cad4c3443a7/go.mod h1:FecbI9+v66THATjSRHfNgh1IVFe/9kFxbXtjV0ctIMA=
|
||||||
github.com/grpc-ecosystem/go-grpc-middleware v1.3.0 h1:+9834+KizmvFV7pXQGSXQTsaWhq2GjuNUt0aUU0YBYw=
|
|
||||||
github.com/grpc-ecosystem/go-grpc-middleware v1.3.0/go.mod h1:z0ButlSOZa5vEBq9m2m2hlwIgKw+rp3sdCBRoJY+30Y=
|
|
||||||
github.com/grpc-ecosystem/go-grpc-prometheus v1.2.0 h1:Ovs26xHkKqVztRpIrF/92BcuyuQ/YW4NSIpoGtfXNho=
|
|
||||||
github.com/grpc-ecosystem/go-grpc-prometheus v1.2.0/go.mod h1:8NvIoxWQoOIhqOTXgfV/d3M/q6VIi02HzZEHgUlZvzk=
|
|
||||||
github.com/grpc-ecosystem/grpc-gateway v1.16.0 h1:gmcG1KaJ57LophUzW0Hy8NmPhnMZb4M0+kPpLofRdBo=
|
|
||||||
github.com/grpc-ecosystem/grpc-gateway v1.16.0/go.mod h1:BDjrQk3hbvj6Nolgz8mAMFbcEtjT1g+wF4CSlocrBnw=
|
|
||||||
github.com/hashicorp/golang-lru v0.5.0/go.mod h1:/m3WP610KZHVQ1SGc6re/UDhFvYD7pJ4Ao+sR/qLZy8=
|
github.com/hashicorp/golang-lru v0.5.0/go.mod h1:/m3WP610KZHVQ1SGc6re/UDhFvYD7pJ4Ao+sR/qLZy8=
|
||||||
github.com/hashicorp/golang-lru v0.5.1/go.mod h1:/m3WP610KZHVQ1SGc6re/UDhFvYD7pJ4Ao+sR/qLZy8=
|
github.com/hashicorp/golang-lru v0.5.1/go.mod h1:/m3WP610KZHVQ1SGc6re/UDhFvYD7pJ4Ao+sR/qLZy8=
|
||||||
github.com/hpcloud/tail v1.0.0/go.mod h1:ab1qPbhIpdTxEkNHXyeSf5vhxWSCs/tWer42PpOxQnU=
|
github.com/hpcloud/tail v1.0.0/go.mod h1:ab1qPbhIpdTxEkNHXyeSf5vhxWSCs/tWer42PpOxQnU=
|
||||||
github.com/ianlancetaylor/demangle v0.0.0-20181102032728-5e5cf60278f6/go.mod h1:aSSvb/t6k1mPoxDqO4vJh6VOCGPwU4O0C2/Eqndh1Sc=
|
github.com/ianlancetaylor/demangle v0.0.0-20181102032728-5e5cf60278f6/go.mod h1:aSSvb/t6k1mPoxDqO4vJh6VOCGPwU4O0C2/Eqndh1Sc=
|
||||||
github.com/imdario/mergo v0.3.5/go.mod h1:2EnlNZ0deacrJVfApfmtdGgDfMuh/nq6Ok1EcJh5FfA=
|
github.com/imdario/mergo v0.3.5/go.mod h1:2EnlNZ0deacrJVfApfmtdGgDfMuh/nq6Ok1EcJh5FfA=
|
||||||
github.com/jonboulle/clockwork v0.2.2 h1:UOGuzwb1PwsrDAObMuhUnj0p5ULPj8V/xJ7Kx9qUBdQ=
|
|
||||||
github.com/jonboulle/clockwork v0.2.2/go.mod h1:Pkfl5aHPm1nk2H9h0bjmnJD/BcgbGXUBGnn1kMkgxc8=
|
|
||||||
github.com/json-iterator/go v1.1.6/go.mod h1:+SdeFBvtyEkXs7REEP0seUULqWtbJapLOCVDaaPEHmU=
|
github.com/json-iterator/go v1.1.6/go.mod h1:+SdeFBvtyEkXs7REEP0seUULqWtbJapLOCVDaaPEHmU=
|
||||||
github.com/json-iterator/go v1.1.10 h1:Kz6Cvnvv2wGdaG/V8yMvfkmNiXq9Ya2KUv4rouJJr68=
|
|
||||||
github.com/json-iterator/go v1.1.10/go.mod h1:KdQUCv79m/52Kvf8AW2vK1V8akMuk1QjK/uOdHXbAo4=
|
github.com/json-iterator/go v1.1.10/go.mod h1:KdQUCv79m/52Kvf8AW2vK1V8akMuk1QjK/uOdHXbAo4=
|
||||||
github.com/jstemmer/go-junit-report v0.0.0-20190106144839-af01ea7f8024/go.mod h1:6v2b51hI/fHJwM22ozAgKL4VKDeJcHhJFhtBdhmNjmU=
|
github.com/jstemmer/go-junit-report v0.0.0-20190106144839-af01ea7f8024/go.mod h1:6v2b51hI/fHJwM22ozAgKL4VKDeJcHhJFhtBdhmNjmU=
|
||||||
github.com/jstemmer/go-junit-report v0.9.1/go.mod h1:Brl9GWCQeLvo8nXZwPNNblvFj/XSXhF0NWZEnDohbsk=
|
github.com/jstemmer/go-junit-report v0.9.1/go.mod h1:Brl9GWCQeLvo8nXZwPNNblvFj/XSXhF0NWZEnDohbsk=
|
||||||
github.com/julienschmidt/httprouter v1.2.0/go.mod h1:SYymIcj16QtmaHHD7aYtjjsJG7VTCxuUUipMqKk8s4w=
|
github.com/julienschmidt/httprouter v1.2.0/go.mod h1:SYymIcj16QtmaHHD7aYtjjsJG7VTCxuUUipMqKk8s4w=
|
||||||
github.com/kisielk/errcheck v1.2.0/go.mod h1:/BMXB+zMLi60iA8Vv6Ksmxu/1UDYcXs4uQLJ+jE2L00=
|
github.com/kisielk/errcheck v1.2.0/go.mod h1:/BMXB+zMLi60iA8Vv6Ksmxu/1UDYcXs4uQLJ+jE2L00=
|
||||||
github.com/kisielk/errcheck v1.5.0/go.mod h1:pFxgyoBC7bSaBwPgfKdkLd5X25qrDl4LWUI2bnpBCr8=
|
|
||||||
github.com/kisielk/gotool v1.0.0/go.mod h1:XhKaO+MFFWcvkIS/tQcRk01m1F5IRFswLeQ+oQHNcck=
|
github.com/kisielk/gotool v1.0.0/go.mod h1:XhKaO+MFFWcvkIS/tQcRk01m1F5IRFswLeQ+oQHNcck=
|
||||||
github.com/konsorten/go-windows-terminal-sequences v1.0.1/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ=
|
github.com/konsorten/go-windows-terminal-sequences v1.0.1/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ=
|
||||||
github.com/konsorten/go-windows-terminal-sequences v1.0.3 h1:CE8S1cTafDpPvMhIxNJKvHsGVBgn1xWYf1NbHQhywc8=
|
|
||||||
github.com/konsorten/go-windows-terminal-sequences v1.0.3/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ=
|
github.com/konsorten/go-windows-terminal-sequences v1.0.3/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ=
|
||||||
github.com/kr/logfmt v0.0.0-20140226030751-b84e30acd515/go.mod h1:+0opPa2QZZtGFBFZlji/RkVcI2GknAs/DXo4wKdlNEc=
|
github.com/kr/logfmt v0.0.0-20140226030751-b84e30acd515/go.mod h1:+0opPa2QZZtGFBFZlji/RkVcI2GknAs/DXo4wKdlNEc=
|
||||||
github.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORNo=
|
github.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORNo=
|
||||||
@@ -171,14 +135,11 @@ github.com/kubernetes-csi/csi-lib-utils v0.9.1 h1:sGq6ifVujfMSkfTsMZip44Ttv8SDXv
|
|||||||
github.com/kubernetes-csi/csi-lib-utils v0.9.1/go.mod h1:8E2jVUX9j3QgspwHXa6LwyN7IHQDjW9jX3kwoWnSC+M=
|
github.com/kubernetes-csi/csi-lib-utils v0.9.1/go.mod h1:8E2jVUX9j3QgspwHXa6LwyN7IHQDjW9jX3kwoWnSC+M=
|
||||||
github.com/mailru/easyjson v0.0.0-20160728113105-d5b7844b561a/go.mod h1:C1wdFJiN94OJF2b5HbByQZoLdCWB1Yqtg26g4irojpc=
|
github.com/mailru/easyjson v0.0.0-20160728113105-d5b7844b561a/go.mod h1:C1wdFJiN94OJF2b5HbByQZoLdCWB1Yqtg26g4irojpc=
|
||||||
github.com/matttproud/golang_protobuf_extensions v1.0.1/go.mod h1:D8He9yQNgCq6Z5Ld7szi9bcBfOoFv/3dc6xSMkL2PC0=
|
github.com/matttproud/golang_protobuf_extensions v1.0.1/go.mod h1:D8He9yQNgCq6Z5Ld7szi9bcBfOoFv/3dc6xSMkL2PC0=
|
||||||
github.com/matttproud/golang_protobuf_extensions v1.0.2-0.20181231171920-c182affec369 h1:I0XW9+e1XWDxdcEniV4rQAIOPUGDq67JSCiRCgGCZLI=
|
|
||||||
github.com/matttproud/golang_protobuf_extensions v1.0.2-0.20181231171920-c182affec369/go.mod h1:BSXmuO+STAnVfrANrmjBb36TMTDstsz7MSK+HVaYKv4=
|
github.com/matttproud/golang_protobuf_extensions v1.0.2-0.20181231171920-c182affec369/go.mod h1:BSXmuO+STAnVfrANrmjBb36TMTDstsz7MSK+HVaYKv4=
|
||||||
github.com/moby/term v0.0.0-20200312100748-672ec06f55cd/go.mod h1:DdlQx2hp0Ss5/fLikoLlEeIYiATotOjgB//nb973jeo=
|
github.com/moby/term v0.0.0-20200312100748-672ec06f55cd/go.mod h1:DdlQx2hp0Ss5/fLikoLlEeIYiATotOjgB//nb973jeo=
|
||||||
github.com/modern-go/concurrent v0.0.0-20180228061459-e0a39a4cb421/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q=
|
github.com/modern-go/concurrent v0.0.0-20180228061459-e0a39a4cb421/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q=
|
||||||
github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd h1:TRLaZ9cD/w8PVh93nsPXa1VrQ6jlwL5oN8l14QlcNfg=
|
|
||||||
github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q=
|
github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q=
|
||||||
github.com/modern-go/reflect2 v0.0.0-20180701023420-4b7aa43c6742/go.mod h1:bx2lNnkwVCuqBIxFjflWJWanXIb3RllmbCylyMrvgv0=
|
github.com/modern-go/reflect2 v0.0.0-20180701023420-4b7aa43c6742/go.mod h1:bx2lNnkwVCuqBIxFjflWJWanXIb3RllmbCylyMrvgv0=
|
||||||
github.com/modern-go/reflect2 v1.0.1 h1:9f412s+6RmYXLWZSEzVVgPGK7C2PphHj5RJrvfx9AWI=
|
|
||||||
github.com/modern-go/reflect2 v1.0.1/go.mod h1:bx2lNnkwVCuqBIxFjflWJWanXIb3RllmbCylyMrvgv0=
|
github.com/modern-go/reflect2 v1.0.1/go.mod h1:bx2lNnkwVCuqBIxFjflWJWanXIb3RllmbCylyMrvgv0=
|
||||||
github.com/munnerz/goautoneg v0.0.0-20120707110453-a547fc61f48d/go.mod h1:+n7T8mK8HuQTcFwEeznm/DIxMOiR9yIdICNftLE1DvQ=
|
github.com/munnerz/goautoneg v0.0.0-20120707110453-a547fc61f48d/go.mod h1:+n7T8mK8HuQTcFwEeznm/DIxMOiR9yIdICNftLE1DvQ=
|
||||||
github.com/mwitkow/go-conntrack v0.0.0-20161129095857-cc309e4a2223/go.mod h1:qRWi+5nqEBWmkhHvq77mSJWrCKwh8bxhgT7d/eI7P4U=
|
github.com/mwitkow/go-conntrack v0.0.0-20161129095857-cc309e4a2223/go.mod h1:qRWi+5nqEBWmkhHvq77mSJWrCKwh8bxhgT7d/eI7P4U=
|
||||||
@@ -188,38 +149,28 @@ github.com/onsi/ginkgo v1.6.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+W
|
|||||||
github.com/onsi/ginkgo v1.11.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE=
|
github.com/onsi/ginkgo v1.11.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE=
|
||||||
github.com/onsi/gomega v0.0.0-20170829124025-dcabb60a477c/go.mod h1:C1qb7wdrVGGVU+Z6iS04AVkA3Q65CEZX59MT0QO5uiA=
|
github.com/onsi/gomega v0.0.0-20170829124025-dcabb60a477c/go.mod h1:C1qb7wdrVGGVU+Z6iS04AVkA3Q65CEZX59MT0QO5uiA=
|
||||||
github.com/onsi/gomega v1.7.0/go.mod h1:ex+gbHU/CVuBBDIJjb2X0qEXbFg53c61hWP/1CpauHY=
|
github.com/onsi/gomega v1.7.0/go.mod h1:ex+gbHU/CVuBBDIJjb2X0qEXbFg53c61hWP/1CpauHY=
|
||||||
github.com/opentracing/opentracing-go v1.1.0/go.mod h1:UkNAQd3GIcIGf0SeVgPpRdFStlNbqXla1AfSYxPUl2o=
|
|
||||||
github.com/peterbourgon/diskv v2.0.1+incompatible/go.mod h1:uqqh8zWWbv1HBMNONnaR/tNboyR3/BZd58JJSHlUSCU=
|
github.com/peterbourgon/diskv v2.0.1+incompatible/go.mod h1:uqqh8zWWbv1HBMNONnaR/tNboyR3/BZd58JJSHlUSCU=
|
||||||
github.com/pkg/errors v0.8.0/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
|
github.com/pkg/errors v0.8.0/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
|
||||||
github.com/pkg/errors v0.8.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
|
github.com/pkg/errors v0.8.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
|
||||||
github.com/pkg/errors v0.9.1 h1:FEBLx1zS214owpjy7qsBeixbURkuhQAwrK5UwLGTwt4=
|
|
||||||
github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
|
github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
|
||||||
github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM=
|
github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM=
|
||||||
github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
|
github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
|
||||||
github.com/prometheus/client_golang v0.9.1/go.mod h1:7SWBe2y4D6OKWSNQJUaRYU/AaXPKyh/dDVn+NZz0KFw=
|
github.com/prometheus/client_golang v0.9.1/go.mod h1:7SWBe2y4D6OKWSNQJUaRYU/AaXPKyh/dDVn+NZz0KFw=
|
||||||
github.com/prometheus/client_golang v1.0.0/go.mod h1:db9x61etRT2tGnBNRi70OPL5FsnadC4Ky3P0J6CfImo=
|
github.com/prometheus/client_golang v1.0.0/go.mod h1:db9x61etRT2tGnBNRi70OPL5FsnadC4Ky3P0J6CfImo=
|
||||||
github.com/prometheus/client_golang v1.7.1 h1:NTGy1Ja9pByO+xAeH/qiWnLrKtr3hJPNjaVUwnjpdpA=
|
|
||||||
github.com/prometheus/client_golang v1.7.1/go.mod h1:PY5Wy2awLA44sXw4AOSfFBetzPP4j5+D6mVACh+pe2M=
|
github.com/prometheus/client_golang v1.7.1/go.mod h1:PY5Wy2awLA44sXw4AOSfFBetzPP4j5+D6mVACh+pe2M=
|
||||||
github.com/prometheus/client_model v0.0.0-20180712105110-5c3871d89910/go.mod h1:MbSGuTsp3dbXC40dX6PRTWyKYBIrTGTE9sqQNg2J8bo=
|
github.com/prometheus/client_model v0.0.0-20180712105110-5c3871d89910/go.mod h1:MbSGuTsp3dbXC40dX6PRTWyKYBIrTGTE9sqQNg2J8bo=
|
||||||
github.com/prometheus/client_model v0.0.0-20190129233127-fd36f4220a90/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA=
|
github.com/prometheus/client_model v0.0.0-20190129233127-fd36f4220a90/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA=
|
||||||
github.com/prometheus/client_model v0.0.0-20190812154241-14fe0d1b01d4/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA=
|
github.com/prometheus/client_model v0.0.0-20190812154241-14fe0d1b01d4/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA=
|
||||||
github.com/prometheus/client_model v0.2.0 h1:uq5h0d+GuxiXLJLNABMgp2qUWDPiLvgCzz2dUR+/W/M=
|
|
||||||
github.com/prometheus/client_model v0.2.0/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA=
|
github.com/prometheus/client_model v0.2.0/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA=
|
||||||
github.com/prometheus/common v0.4.1/go.mod h1:TNfzLD0ON7rHzMJeJkieUDPYmFC7Snx/y86RQel1bk4=
|
github.com/prometheus/common v0.4.1/go.mod h1:TNfzLD0ON7rHzMJeJkieUDPYmFC7Snx/y86RQel1bk4=
|
||||||
github.com/prometheus/common v0.10.0 h1:RyRA7RzGXQZiW+tGMr7sxa85G1z0yOpM1qq5c8lNawc=
|
|
||||||
github.com/prometheus/common v0.10.0/go.mod h1:Tlit/dnDKsSWFlCLTWaA1cyBgKHSMdTB80sz/V91rCo=
|
github.com/prometheus/common v0.10.0/go.mod h1:Tlit/dnDKsSWFlCLTWaA1cyBgKHSMdTB80sz/V91rCo=
|
||||||
github.com/prometheus/procfs v0.0.0-20181005140218-185b4288413d/go.mod h1:c3At6R/oaqEKCNdg8wHV1ftS6bRYblBhIjjI8uT2IGk=
|
github.com/prometheus/procfs v0.0.0-20181005140218-185b4288413d/go.mod h1:c3At6R/oaqEKCNdg8wHV1ftS6bRYblBhIjjI8uT2IGk=
|
||||||
github.com/prometheus/procfs v0.0.2/go.mod h1:TjEm7ze935MbeOT/UhFTIMYKhuLP4wbCsTZCD3I8kEA=
|
github.com/prometheus/procfs v0.0.2/go.mod h1:TjEm7ze935MbeOT/UhFTIMYKhuLP4wbCsTZCD3I8kEA=
|
||||||
github.com/prometheus/procfs v0.1.3 h1:F0+tqvhOksq22sc6iCHF5WGlWjdwj92p0udFh1VFBS8=
|
|
||||||
github.com/prometheus/procfs v0.1.3/go.mod h1:lV6e/gmhEcM9IjHGsFOCxxuZ+z1YqCvr4OA4YeYWdaU=
|
github.com/prometheus/procfs v0.1.3/go.mod h1:lV6e/gmhEcM9IjHGsFOCxxuZ+z1YqCvr4OA4YeYWdaU=
|
||||||
github.com/rogpeppe/fastuuid v1.2.0/go.mod h1:jVj6XXZzXRy/MSR5jhDC/2q6DgLz+nrA6LYCDYWNEvQ=
|
|
||||||
github.com/rogpeppe/go-internal v1.3.0/go.mod h1:M8bDsm7K2OlrFYOpmOWEs/qY81heoFRclV5y23lUDJ4=
|
github.com/rogpeppe/go-internal v1.3.0/go.mod h1:M8bDsm7K2OlrFYOpmOWEs/qY81heoFRclV5y23lUDJ4=
|
||||||
github.com/sirupsen/logrus v1.2.0/go.mod h1:LxeOpSwHxABJmUn/MG1IvRgCAasNZTLOkJPxbbu5VWo=
|
github.com/sirupsen/logrus v1.2.0/go.mod h1:LxeOpSwHxABJmUn/MG1IvRgCAasNZTLOkJPxbbu5VWo=
|
||||||
github.com/sirupsen/logrus v1.4.2/go.mod h1:tLMulIdttU9McNUspp0xgXVQah82FyeX6MwdIuYE2rE=
|
github.com/sirupsen/logrus v1.4.2/go.mod h1:tLMulIdttU9McNUspp0xgXVQah82FyeX6MwdIuYE2rE=
|
||||||
github.com/sirupsen/logrus v1.6.0 h1:UBcNElsrwanuuMsnGSlYmtmgbb23qDR5dG+6X6Oo89I=
|
|
||||||
github.com/sirupsen/logrus v1.6.0/go.mod h1:7uNnSEd1DgxDLC74fIahvMZmmYsHGZGEOFrfsX/uA88=
|
github.com/sirupsen/logrus v1.6.0/go.mod h1:7uNnSEd1DgxDLC74fIahvMZmmYsHGZGEOFrfsX/uA88=
|
||||||
github.com/soheilhy/cmux v0.1.5 h1:jjzc5WVemNEDTLwv9tlmemhC73tI08BNOIGwBOo10Js=
|
|
||||||
github.com/soheilhy/cmux v0.1.5/go.mod h1:T7TcVDs9LWfQgPlPsdngu6I6QIoyIFZDDC6sNE1GqG0=
|
|
||||||
github.com/spf13/afero v1.2.2/go.mod h1:9ZxEEn6pIJ8Rxe320qSDBk6AsU0r9pR7Q4OcevTdifk=
|
github.com/spf13/afero v1.2.2/go.mod h1:9ZxEEn6pIJ8Rxe320qSDBk6AsU0r9pR7Q4OcevTdifk=
|
||||||
github.com/spf13/pflag v0.0.0-20170130214245-9ff6c6923cff/go.mod h1:DYY7MBk1bdzusC3SYhjObp+wFpr4gzcvqqNjLnInEg4=
|
github.com/spf13/pflag v0.0.0-20170130214245-9ff6c6923cff/go.mod h1:DYY7MBk1bdzusC3SYhjObp+wFpr4gzcvqqNjLnInEg4=
|
||||||
github.com/spf13/pflag v1.0.3/go.mod h1:DYY7MBk1bdzusC3SYhjObp+wFpr4gzcvqqNjLnInEg4=
|
github.com/spf13/pflag v1.0.3/go.mod h1:DYY7MBk1bdzusC3SYhjObp+wFpr4gzcvqqNjLnInEg4=
|
||||||
@@ -231,24 +182,11 @@ github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UV
|
|||||||
github.com/stretchr/testify v1.4.0/go.mod h1:j7eGeouHqKxXV5pUuKE4zz7dFj8WfuZ+81PSLYec5m4=
|
github.com/stretchr/testify v1.4.0/go.mod h1:j7eGeouHqKxXV5pUuKE4zz7dFj8WfuZ+81PSLYec5m4=
|
||||||
github.com/stretchr/testify v1.5.1 h1:nOGnQDM7FYENwehXlg/kFVnos3rEvtKTjRvOWSzb6H4=
|
github.com/stretchr/testify v1.5.1 h1:nOGnQDM7FYENwehXlg/kFVnos3rEvtKTjRvOWSzb6H4=
|
||||||
github.com/stretchr/testify v1.5.1/go.mod h1:5W2xD1RspED5o8YsWQXVCued0rvSQ+mT+I5cxcmMvtA=
|
github.com/stretchr/testify v1.5.1/go.mod h1:5W2xD1RspED5o8YsWQXVCued0rvSQ+mT+I5cxcmMvtA=
|
||||||
github.com/tmc/grpc-websocket-proxy v0.0.0-20201229170055-e5319fda7802 h1:uruHq4dN7GR16kFc5fp3d1RIYzJW5onx8Ybykw2YQFA=
|
|
||||||
github.com/tmc/grpc-websocket-proxy v0.0.0-20201229170055-e5319fda7802/go.mod h1:ncp9v5uamzpCO7NfCPTXjqaC+bZgJeR0sMTm6dMHP7U=
|
|
||||||
github.com/xiang90/probing v0.0.0-20190116061207-43a291ad63a2 h1:eY9dn8+vbi4tKz5Qo6v2eYzo7kUS51QINcR5jNpbZS8=
|
|
||||||
github.com/xiang90/probing v0.0.0-20190116061207-43a291ad63a2/go.mod h1:UETIi67q53MR2AWcXfiuqkDkRtnGDLqkBTpCHuJHxtU=
|
|
||||||
github.com/yuin/goldmark v1.1.27/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74=
|
|
||||||
github.com/yuin/goldmark v1.2.1/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74=
|
|
||||||
go.etcd.io/bbolt v1.3.5 h1:XAzx9gjCb0Rxj7EoqcClPD1d5ZBxZJk0jbuoPHenBt0=
|
|
||||||
go.etcd.io/bbolt v1.3.5/go.mod h1:G5EMThwa9y8QZGBClrRx5EY+Yw9kAhnjy3bSjsnlVTQ=
|
|
||||||
go.etcd.io/etcd v3.3.25+incompatible h1:V1RzkZJj9LqsJRy+TUBgpWSbZXITLB819lstuTFoZOY=
|
|
||||||
go.etcd.io/etcd v3.3.25+incompatible/go.mod h1:yaeTdrJi5lOmYerz05bd8+V7KubZs8YSFZfzsF9A6aI=
|
|
||||||
go.opencensus.io v0.21.0/go.mod h1:mSImk1erAIZhrmZN+AvHh14ztQfjbGwt4TtuofqLduU=
|
go.opencensus.io v0.21.0/go.mod h1:mSImk1erAIZhrmZN+AvHh14ztQfjbGwt4TtuofqLduU=
|
||||||
go.opencensus.io v0.22.0/go.mod h1:+kGneAE2xo2IficOXnaByMWTGM9T73dGwxeWcUqIpI8=
|
go.opencensus.io v0.22.0/go.mod h1:+kGneAE2xo2IficOXnaByMWTGM9T73dGwxeWcUqIpI8=
|
||||||
go.opencensus.io v0.22.2/go.mod h1:yxeiOL68Rb0Xd1ddK5vPZ/oVn4vY4Ynel7k9FzqtOIw=
|
go.opencensus.io v0.22.2/go.mod h1:yxeiOL68Rb0Xd1ddK5vPZ/oVn4vY4Ynel7k9FzqtOIw=
|
||||||
go.uber.org/atomic v1.4.0 h1:cxzIVoETapQEqDhQu3QfnvXAV4AlzcvUCxkVUFw3+EU=
|
|
||||||
go.uber.org/atomic v1.4.0/go.mod h1:gD2HeocX3+yG+ygLZcrzQJaqmWj9AIm7n08wl/qW/PE=
|
go.uber.org/atomic v1.4.0/go.mod h1:gD2HeocX3+yG+ygLZcrzQJaqmWj9AIm7n08wl/qW/PE=
|
||||||
go.uber.org/multierr v1.1.0 h1:HoEmRHQPVSqub6w2z2d2EOVs2fjyFRGyofhKuyDq0QI=
|
|
||||||
go.uber.org/multierr v1.1.0/go.mod h1:wR5kodmAFQ0UK8QlbwjlSNy0Z68gJhDJUG5sjR94q/0=
|
go.uber.org/multierr v1.1.0/go.mod h1:wR5kodmAFQ0UK8QlbwjlSNy0Z68gJhDJUG5sjR94q/0=
|
||||||
go.uber.org/zap v1.10.0 h1:ORx85nbTijNz8ljznvCMR1ZBIPKFn3jQrag10X2AsuM=
|
|
||||||
go.uber.org/zap v1.10.0/go.mod h1:vwi/ZaCAaUcBkycHslxD9B2zi4UTXhF60s6SWpuDF0Q=
|
go.uber.org/zap v1.10.0/go.mod h1:vwi/ZaCAaUcBkycHslxD9B2zi4UTXhF60s6SWpuDF0Q=
|
||||||
golang.org/x/crypto v0.0.0-20180904163835-0709b304e793/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4=
|
golang.org/x/crypto v0.0.0-20180904163835-0709b304e793/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4=
|
||||||
golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w=
|
golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w=
|
||||||
@@ -256,7 +194,6 @@ golang.org/x/crypto v0.0.0-20190510104115-cbcb75029529/go.mod h1:yigFU9vqHzYiE8U
|
|||||||
golang.org/x/crypto v0.0.0-20190605123033-f99c8df09eb5/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
|
golang.org/x/crypto v0.0.0-20190605123033-f99c8df09eb5/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
|
||||||
golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
|
golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
|
||||||
golang.org/x/crypto v0.0.0-20191206172530-e9b2fee46413/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
|
golang.org/x/crypto v0.0.0-20191206172530-e9b2fee46413/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
|
||||||
golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9 h1:psW17arqaxU48Z5kZ0CQnkZWQJsqcURM6tKiBApRjXI=
|
|
||||||
golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
|
golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
|
||||||
golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA=
|
golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA=
|
||||||
golang.org/x/exp v0.0.0-20190306152737-a1d7652674e8/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA=
|
golang.org/x/exp v0.0.0-20190306152737-a1d7652674e8/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA=
|
||||||
@@ -276,8 +213,6 @@ golang.org/x/mobile v0.0.0-20190719004257-d2bd2a29d028/go.mod h1:E/iHnbuqvinMTCc
|
|||||||
golang.org/x/mod v0.0.0-20190513183733-4bf6d317e70e/go.mod h1:mXi4GBBbnImb6dmsKGUJ2LatrhH/nqhxcFungHvyanc=
|
golang.org/x/mod v0.0.0-20190513183733-4bf6d317e70e/go.mod h1:mXi4GBBbnImb6dmsKGUJ2LatrhH/nqhxcFungHvyanc=
|
||||||
golang.org/x/mod v0.1.0/go.mod h1:0QHyrYULN0/3qlju5TqG8bIK38QM8yzMo5ekMj3DlcY=
|
golang.org/x/mod v0.1.0/go.mod h1:0QHyrYULN0/3qlju5TqG8bIK38QM8yzMo5ekMj3DlcY=
|
||||||
golang.org/x/mod v0.1.1-0.20191105210325-c90efee705ee/go.mod h1:QqPTAvyqsEbceGzBzNggFXnrqF1CaUcvgkdR5Ot7KZg=
|
golang.org/x/mod v0.1.1-0.20191105210325-c90efee705ee/go.mod h1:QqPTAvyqsEbceGzBzNggFXnrqF1CaUcvgkdR5Ot7KZg=
|
||||||
golang.org/x/mod v0.2.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA=
|
|
||||||
golang.org/x/mod v0.3.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA=
|
|
||||||
golang.org/x/net v0.0.0-20180724234803-3673e40ba225/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
|
golang.org/x/net v0.0.0-20180724234803-3673e40ba225/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
|
||||||
golang.org/x/net v0.0.0-20180906233101-161cd47e91fd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
|
golang.org/x/net v0.0.0-20180906233101-161cd47e91fd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
|
||||||
golang.org/x/net v0.0.0-20181114220301-adae6a3d119a/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
|
golang.org/x/net v0.0.0-20181114220301-adae6a3d119a/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
|
||||||
@@ -291,26 +226,20 @@ golang.org/x/net v0.0.0-20190603091049-60506f45cf65/go.mod h1:HSz+uSET+XFnRR8LxR
|
|||||||
golang.org/x/net v0.0.0-20190613194153-d28f0bde5980/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
|
golang.org/x/net v0.0.0-20190613194153-d28f0bde5980/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
|
||||||
golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
|
golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
|
||||||
golang.org/x/net v0.0.0-20191209160850-c0dbc17a3553/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
|
golang.org/x/net v0.0.0-20191209160850-c0dbc17a3553/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
|
||||||
golang.org/x/net v0.0.0-20200226121028-0de0cce0169b/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
|
|
||||||
golang.org/x/net v0.0.0-20200324143707-d3edc9973b7e/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A=
|
golang.org/x/net v0.0.0-20200324143707-d3edc9973b7e/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A=
|
||||||
golang.org/x/net v0.0.0-20200707034311-ab3426394381 h1:VXak5I6aEWmAXeQjA+QSZzlgNrpq9mjcfDemuexIKsU=
|
|
||||||
golang.org/x/net v0.0.0-20200707034311-ab3426394381/go.mod h1:/O7V0waA8r7cgGh81Ro3o1hOxt32SMVPicZroKQ2sZA=
|
golang.org/x/net v0.0.0-20200707034311-ab3426394381/go.mod h1:/O7V0waA8r7cgGh81Ro3o1hOxt32SMVPicZroKQ2sZA=
|
||||||
golang.org/x/net v0.0.0-20200822124328-c89045814202/go.mod h1:/O7V0waA8r7cgGh81Ro3o1hOxt32SMVPicZroKQ2sZA=
|
|
||||||
golang.org/x/net v0.0.0-20201021035429-f5854403a974/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU=
|
|
||||||
golang.org/x/net v0.0.0-20201202161906-c7110b5ffcbb h1:eBmm0M9fYhWpKZLjQUUKka/LtIxf46G4fxeEz5KJr9U=
|
golang.org/x/net v0.0.0-20201202161906-c7110b5ffcbb h1:eBmm0M9fYhWpKZLjQUUKka/LtIxf46G4fxeEz5KJr9U=
|
||||||
golang.org/x/net v0.0.0-20201202161906-c7110b5ffcbb/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU=
|
golang.org/x/net v0.0.0-20201202161906-c7110b5ffcbb/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU=
|
||||||
golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U=
|
golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U=
|
||||||
golang.org/x/oauth2 v0.0.0-20190226205417-e64efc72b421/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw=
|
golang.org/x/oauth2 v0.0.0-20190226205417-e64efc72b421/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw=
|
||||||
golang.org/x/oauth2 v0.0.0-20190604053449-0f29369cfe45/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw=
|
golang.org/x/oauth2 v0.0.0-20190604053449-0f29369cfe45/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw=
|
||||||
golang.org/x/oauth2 v0.0.0-20191202225959-858c2ad4c8b6/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw=
|
golang.org/x/oauth2 v0.0.0-20191202225959-858c2ad4c8b6/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw=
|
||||||
golang.org/x/oauth2 v0.0.0-20200107190931-bf48bf16ab8d/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw=
|
|
||||||
golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||||
golang.org/x/sync v0.0.0-20181108010431-42b317875d0f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
golang.org/x/sync v0.0.0-20181108010431-42b317875d0f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||||
golang.org/x/sync v0.0.0-20181221193216-37e7f081c4d4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
golang.org/x/sync v0.0.0-20181221193216-37e7f081c4d4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||||
golang.org/x/sync v0.0.0-20190227155943-e225da77a7e6/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
golang.org/x/sync v0.0.0-20190227155943-e225da77a7e6/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||||
golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||||
golang.org/x/sync v0.0.0-20190911185100-cd5d95a43a6e/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
golang.org/x/sync v0.0.0-20190911185100-cd5d95a43a6e/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||||
golang.org/x/sync v0.0.0-20201020160332-67f06af15bc9/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
|
||||||
golang.org/x/sys v0.0.0-20180905080454-ebe1bf3edb33/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
|
golang.org/x/sys v0.0.0-20180905080454-ebe1bf3edb33/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
|
||||||
golang.org/x/sys v0.0.0-20180909124046-d0be0721c37e/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
|
golang.org/x/sys v0.0.0-20180909124046-d0be0721c37e/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
|
||||||
golang.org/x/sys v0.0.0-20181116152217-5ac8a444bdc5/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
|
golang.org/x/sys v0.0.0-20181116152217-5ac8a444bdc5/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
|
||||||
@@ -326,11 +255,9 @@ golang.org/x/sys v0.0.0-20191005200804-aed5e4c7ecf9/go.mod h1:h1NjWce9XRLGQEsW7w
|
|||||||
golang.org/x/sys v0.0.0-20191204072324-ce4227a45e2e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
golang.org/x/sys v0.0.0-20191204072324-ce4227a45e2e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||||
golang.org/x/sys v0.0.0-20191228213918-04cbcbbfeed8/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
golang.org/x/sys v0.0.0-20191228213918-04cbcbbfeed8/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||||
golang.org/x/sys v0.0.0-20200106162015-b016eb3dc98e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
golang.org/x/sys v0.0.0-20200106162015-b016eb3dc98e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||||
golang.org/x/sys v0.0.0-20200202164722-d101bd2416d5/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
|
||||||
golang.org/x/sys v0.0.0-20200302150141-5c8b2ff67527/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
golang.org/x/sys v0.0.0-20200302150141-5c8b2ff67527/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||||
golang.org/x/sys v0.0.0-20200323222414-85ca7c5b95cd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
golang.org/x/sys v0.0.0-20200323222414-85ca7c5b95cd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||||
golang.org/x/sys v0.0.0-20200615200032-f1bc736245b1/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
golang.org/x/sys v0.0.0-20200615200032-f1bc736245b1/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||||
golang.org/x/sys v0.0.0-20200622214017-ed371f2e16b4 h1:5/PjkGUjvEU5Gl6BxmvKRPpqo2uNMv4rcHBMwzk/st8=
|
|
||||||
golang.org/x/sys v0.0.0-20200622214017-ed371f2e16b4/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
golang.org/x/sys v0.0.0-20200622214017-ed371f2e16b4/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||||
golang.org/x/sys v0.0.0-20200930185726-fdedc70b468f h1:+Nyd8tzPX9R7BWHguqsrbFdRx3WQ/1ib8I44HXV5yTA=
|
golang.org/x/sys v0.0.0-20200930185726-fdedc70b468f h1:+Nyd8tzPX9R7BWHguqsrbFdRx3WQ/1ib8I44HXV5yTA=
|
||||||
golang.org/x/sys v0.0.0-20200930185726-fdedc70b468f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
golang.org/x/sys v0.0.0-20200930185726-fdedc70b468f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||||
@@ -341,7 +268,6 @@ golang.org/x/text v0.3.3 h1:cokOdA+Jmi5PJGXLlLllQSgYigAEfHXJAERHVMaCc2k=
|
|||||||
golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
|
golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
|
||||||
golang.org/x/time v0.0.0-20181108054448-85acf8d2951c/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
|
golang.org/x/time v0.0.0-20181108054448-85acf8d2951c/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
|
||||||
golang.org/x/time v0.0.0-20190308202827-9d24e82272b4/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
|
golang.org/x/time v0.0.0-20190308202827-9d24e82272b4/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
|
||||||
golang.org/x/time v0.0.0-20191024005414-555d28b269f0 h1:/5xXl8Y5W96D+TtHSlonuFqGHIWVuyCkGJLwGh9JJFs=
|
|
||||||
golang.org/x/time v0.0.0-20191024005414-555d28b269f0/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
|
golang.org/x/time v0.0.0-20191024005414-555d28b269f0/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
|
||||||
golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
|
golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
|
||||||
golang.org/x/tools v0.0.0-20181011042414-1f849cf54d09/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
|
golang.org/x/tools v0.0.0-20181011042414-1f849cf54d09/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
|
||||||
@@ -360,14 +286,10 @@ golang.org/x/tools v0.0.0-20190628153133-6cdbf07be9d0/go.mod h1:/rFqwRUd4F7ZHNgw
|
|||||||
golang.org/x/tools v0.0.0-20190816200558-6889da9d5479/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
|
golang.org/x/tools v0.0.0-20190816200558-6889da9d5479/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
|
||||||
golang.org/x/tools v0.0.0-20190911174233-4f2ddba30aff/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
|
golang.org/x/tools v0.0.0-20190911174233-4f2ddba30aff/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
|
||||||
golang.org/x/tools v0.0.0-20191012152004-8de300cfc20a/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
|
golang.org/x/tools v0.0.0-20191012152004-8de300cfc20a/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
|
||||||
golang.org/x/tools v0.0.0-20191119224855-298f0cb1881e/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
|
|
||||||
golang.org/x/tools v0.0.0-20191125144606-a911d9008d1f/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
|
golang.org/x/tools v0.0.0-20191125144606-a911d9008d1f/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
|
||||||
golang.org/x/tools v0.0.0-20191227053925-7b8e75db28f4/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28=
|
golang.org/x/tools v0.0.0-20191227053925-7b8e75db28f4/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28=
|
||||||
golang.org/x/tools v0.0.0-20200619180055-7c47624df98f/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE=
|
|
||||||
golang.org/x/tools v0.0.0-20210106214847-113979e3529a/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA=
|
|
||||||
golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
|
golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
|
||||||
golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
|
golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
|
||||||
golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543 h1:E7g+9GITq07hpfrRu66IVDexMakfv52eLZ2CXBWiKr4=
|
|
||||||
golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
|
golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
|
||||||
golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1 h1:go1bK/D/BFZV2I8cIQd1NKEZ+0owSTG1fDTci4IqFcE=
|
golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1 h1:go1bK/D/BFZV2I8cIQd1NKEZ+0owSTG1fDTci4IqFcE=
|
||||||
golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
|
golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
|
||||||
@@ -388,8 +310,6 @@ google.golang.org/genproto v0.0.0-20190801165951-fa694d86fc64/go.mod h1:DMBHOl98
|
|||||||
google.golang.org/genproto v0.0.0-20190819201941-24fa4b261c55/go.mod h1:DMBHOl98Agz4BDEuKkezgsaosCRResVns1a3J2ZsMNc=
|
google.golang.org/genproto v0.0.0-20190819201941-24fa4b261c55/go.mod h1:DMBHOl98Agz4BDEuKkezgsaosCRResVns1a3J2ZsMNc=
|
||||||
google.golang.org/genproto v0.0.0-20190911173649-1774047e7e51/go.mod h1:IbNlFCBrqXvoKpeg0TB2l7cyZUmoaFKYIwrEpbDKLA8=
|
google.golang.org/genproto v0.0.0-20190911173649-1774047e7e51/go.mod h1:IbNlFCBrqXvoKpeg0TB2l7cyZUmoaFKYIwrEpbDKLA8=
|
||||||
google.golang.org/genproto v0.0.0-20191230161307-f3c370f40bfb/go.mod h1:n3cpQtvxv34hfy77yVDNjmbRyujviMdxYliBSkLhpCc=
|
google.golang.org/genproto v0.0.0-20191230161307-f3c370f40bfb/go.mod h1:n3cpQtvxv34hfy77yVDNjmbRyujviMdxYliBSkLhpCc=
|
||||||
google.golang.org/genproto v0.0.0-20200423170343-7949de9c1215/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c=
|
|
||||||
google.golang.org/genproto v0.0.0-20200513103714-09dca8ec2884/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c=
|
|
||||||
google.golang.org/genproto v0.0.0-20200526211855-cb27e3aa2013 h1:+kGHl1aib/qcwaRi1CbqBZ1rk19r85MNUf8HaBghugY=
|
google.golang.org/genproto v0.0.0-20200526211855-cb27e3aa2013 h1:+kGHl1aib/qcwaRi1CbqBZ1rk19r85MNUf8HaBghugY=
|
||||||
google.golang.org/genproto v0.0.0-20200526211855-cb27e3aa2013/go.mod h1:NbSheEEYHJ7i3ixzK3sjbqSGDJWnxyFXZblF3eUsNvo=
|
google.golang.org/genproto v0.0.0-20200526211855-cb27e3aa2013/go.mod h1:NbSheEEYHJ7i3ixzK3sjbqSGDJWnxyFXZblF3eUsNvo=
|
||||||
google.golang.org/grpc v1.25.1 h1:wdKvqQk7IttEw92GoRyKG2IDrUIpgpj6H6m81yfeMW0=
|
google.golang.org/grpc v1.25.1 h1:wdKvqQk7IttEw92GoRyKG2IDrUIpgpj6H6m81yfeMW0=
|
||||||
@@ -415,7 +335,6 @@ gopkg.in/inf.v0 v0.9.1/go.mod h1:cWUDdTG/fYaXco+Dcufb5Vnc6Gp2YChqWtbxRZE0mXw=
|
|||||||
gopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7/go.mod h1:dt/ZhP58zS4L8KSrWDmTeBkI65Dw0HsyUHuEVlX15mw=
|
gopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7/go.mod h1:dt/ZhP58zS4L8KSrWDmTeBkI65Dw0HsyUHuEVlX15mw=
|
||||||
gopkg.in/yaml.v2 v2.2.1/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
|
gopkg.in/yaml.v2 v2.2.1/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
|
||||||
gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
|
gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
|
||||||
gopkg.in/yaml.v2 v2.2.3/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
|
|
||||||
gopkg.in/yaml.v2 v2.2.4/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
|
gopkg.in/yaml.v2 v2.2.4/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
|
||||||
gopkg.in/yaml.v2 v2.2.5/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
|
gopkg.in/yaml.v2 v2.2.5/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
|
||||||
gopkg.in/yaml.v2 v2.2.8 h1:obN1ZagJSUGI0Ek/LBmuj4SNLPfIny3KsKFopxRdj10=
|
gopkg.in/yaml.v2 v2.2.8 h1:obN1ZagJSUGI0Ek/LBmuj4SNLPfIny3KsKFopxRdj10=
|
||||||
@@ -444,5 +363,4 @@ k8s.io/utils v0.0.0-20210305010621-2afb4311ab10/go.mod h1:jPW/WVKK9YHAvNhRxK0md/
|
|||||||
rsc.io/binaryregexp v0.2.0/go.mod h1:qTv7/COck+e2FymRvadv62gMdZztPaShugOCi3I+8D8=
|
rsc.io/binaryregexp v0.2.0/go.mod h1:qTv7/COck+e2FymRvadv62gMdZztPaShugOCi3I+8D8=
|
||||||
sigs.k8s.io/structured-merge-diff/v4 v4.0.1/go.mod h1:bJZC9H9iH24zzfZ/41RGcq60oK1F7G282QMXDPYydCw=
|
sigs.k8s.io/structured-merge-diff/v4 v4.0.1/go.mod h1:bJZC9H9iH24zzfZ/41RGcq60oK1F7G282QMXDPYydCw=
|
||||||
sigs.k8s.io/yaml v1.1.0/go.mod h1:UJmg0vDUVViEyp3mgSv9WPwZCDxu4rQW1olrI1uml+o=
|
sigs.k8s.io/yaml v1.1.0/go.mod h1:UJmg0vDUVViEyp3mgSv9WPwZCDxu4rQW1olrI1uml+o=
|
||||||
sigs.k8s.io/yaml v1.2.0 h1:kr/MCeFWJWTwyaHoR9c8EjH9OumOmoF9YGiZd7lFm/Q=
|
|
||||||
sigs.k8s.io/yaml v1.2.0/go.mod h1:yfXDCHCao9+ENCvLSE62v9VSji2MKu5jeNfTrofGhJc=
|
sigs.k8s.io/yaml v1.2.0/go.mod h1:yfXDCHCao9+ENCvLSE62v9VSji2MKu5jeNfTrofGhJc=
|
||||||
|
@@ -5,7 +5,7 @@ package vitastor
|
|||||||
|
|
||||||
const (
|
const (
|
||||||
vitastorCSIDriverName = "csi.vitastor.io"
|
vitastorCSIDriverName = "csi.vitastor.io"
|
||||||
vitastorCSIDriverVersion = "0.7.0"
|
vitastorCSIDriverVersion = "0.8.9"
|
||||||
)
|
)
|
||||||
|
|
||||||
// Config struct fills the parameters of request or user input
|
// Config struct fills the parameters of request or user input
|
||||||
|
@@ -6,11 +6,11 @@ package vitastor
|
|||||||
import (
|
import (
|
||||||
"context"
|
"context"
|
||||||
"encoding/json"
|
"encoding/json"
|
||||||
|
"fmt"
|
||||||
"strings"
|
"strings"
|
||||||
"bytes"
|
"bytes"
|
||||||
"strconv"
|
"strconv"
|
||||||
"time"
|
"time"
|
||||||
"fmt"
|
|
||||||
"os"
|
"os"
|
||||||
"os/exec"
|
"os/exec"
|
||||||
"io/ioutil"
|
"io/ioutil"
|
||||||
@@ -21,8 +21,6 @@ import (
|
|||||||
"google.golang.org/grpc/codes"
|
"google.golang.org/grpc/codes"
|
||||||
"google.golang.org/grpc/status"
|
"google.golang.org/grpc/status"
|
||||||
|
|
||||||
"go.etcd.io/etcd/clientv3"
|
|
||||||
|
|
||||||
"github.com/container-storage-interface/spec/lib/go/csi"
|
"github.com/container-storage-interface/spec/lib/go/csi"
|
||||||
)
|
)
|
||||||
|
|
||||||
@@ -114,6 +112,34 @@ func GetConnectionParams(params map[string]string) (map[string]string, []string,
|
|||||||
return ctxVars, etcdUrl, etcdPrefix
|
return ctxVars, etcdUrl, etcdPrefix
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func invokeCLI(ctxVars map[string]string, args []string) ([]byte, error)
|
||||||
|
{
|
||||||
|
if (ctxVars["etcdUrl"] != "")
|
||||||
|
{
|
||||||
|
args = append(args, "--etcd_address", ctxVars["etcdUrl"])
|
||||||
|
}
|
||||||
|
if (ctxVars["etcdPrefix"] != "")
|
||||||
|
{
|
||||||
|
args = append(args, "--etcd_prefix", ctxVars["etcdPrefix"])
|
||||||
|
}
|
||||||
|
if (ctxVars["configPath"] != "")
|
||||||
|
{
|
||||||
|
args = append(args, "--config_path", ctxVars["configPath"])
|
||||||
|
}
|
||||||
|
c := exec.Command("/usr/bin/vitastor-cli", args...)
|
||||||
|
var stdout, stderr bytes.Buffer
|
||||||
|
c.Stdout = &stdout
|
||||||
|
c.Stderr = &stderr
|
||||||
|
err := c.Run()
|
||||||
|
stderrStr := string(stderr.Bytes())
|
||||||
|
if (err != nil)
|
||||||
|
{
|
||||||
|
klog.Errorf("vitastor-cli %s failed: %s, status %s\n", strings.Join(args, " "), stderrStr, err)
|
||||||
|
return nil, status.Error(codes.Internal, stderrStr+" (status "+err.Error()+")")
|
||||||
|
}
|
||||||
|
return stdout.Bytes(), nil
|
||||||
|
}
|
||||||
|
|
||||||
// Create the volume
|
// Create the volume
|
||||||
func (cs *ControllerServer) CreateVolume(ctx context.Context, req *csi.CreateVolumeRequest) (*csi.CreateVolumeResponse, error)
|
func (cs *ControllerServer) CreateVolume(ctx context.Context, req *csi.CreateVolumeRequest) (*csi.CreateVolumeResponse, error)
|
||||||
{
|
{
|
||||||
@@ -146,128 +172,41 @@ func (cs *ControllerServer) CreateVolume(ctx context.Context, req *csi.CreateVol
|
|||||||
volSize = ((capRange.GetRequiredBytes() + MB - 1) / MB) * MB
|
volSize = ((capRange.GetRequiredBytes() + MB - 1) / MB) * MB
|
||||||
}
|
}
|
||||||
|
|
||||||
// FIXME: The following should PROBABLY be implemented externally in a management tool
|
ctxVars, etcdUrl, _ := GetConnectionParams(req.Parameters)
|
||||||
|
|
||||||
ctxVars, etcdUrl, etcdPrefix := GetConnectionParams(req.Parameters)
|
|
||||||
if (len(etcdUrl) == 0)
|
if (len(etcdUrl) == 0)
|
||||||
{
|
{
|
||||||
return nil, status.Error(codes.InvalidArgument, "no etcdUrl in storage class configuration and no etcd_address in vitastor.conf")
|
return nil, status.Error(codes.InvalidArgument, "no etcdUrl in storage class configuration and no etcd_address in vitastor.conf")
|
||||||
}
|
}
|
||||||
|
|
||||||
// Connect to etcd
|
// Create image using vitastor-cli
|
||||||
cli, err := clientv3.New(clientv3.Config{
|
_, err := invokeCLI(ctxVars, []string{ "create", volName, "-s", fmt.Sprintf("%v", volSize), "--pool", fmt.Sprintf("%v", poolId) })
|
||||||
DialTimeout: ETCD_TIMEOUT,
|
|
||||||
Endpoints: etcdUrl,
|
|
||||||
})
|
|
||||||
if (err != nil)
|
if (err != nil)
|
||||||
{
|
{
|
||||||
return nil, status.Error(codes.Internal, "failed to connect to etcd at "+strings.Join(etcdUrl, ",")+": "+err.Error())
|
if (strings.Index(err.Error(), "already exists") > 0)
|
||||||
}
|
|
||||||
defer cli.Close()
|
|
||||||
|
|
||||||
var imageId uint64 = 0
|
|
||||||
for
|
|
||||||
{
|
|
||||||
// Check if the image exists
|
|
||||||
ctx, cancel := context.WithTimeout(context.Background(), ETCD_TIMEOUT)
|
|
||||||
resp, err := cli.Get(ctx, etcdPrefix+"/index/image/"+volName)
|
|
||||||
cancel()
|
|
||||||
if (err != nil)
|
|
||||||
{
|
{
|
||||||
return nil, status.Error(codes.Internal, "failed to read key from etcd: "+err.Error())
|
stat, err := invokeCLI(ctxVars, []string{ "ls", "--json", volName })
|
||||||
}
|
|
||||||
if (len(resp.Kvs) > 0)
|
|
||||||
{
|
|
||||||
kv := resp.Kvs[0]
|
|
||||||
var v InodeIndex
|
|
||||||
err := json.Unmarshal(kv.Value, &v)
|
|
||||||
if (err != nil)
|
if (err != nil)
|
||||||
{
|
{
|
||||||
return nil, status.Error(codes.Internal, "invalid /index/image/"+volName+" key in etcd: "+err.Error())
|
return nil, err
|
||||||
}
|
}
|
||||||
poolId = v.PoolId
|
var inodeCfg []InodeConfig
|
||||||
imageId = v.Id
|
err = json.Unmarshal(stat, &inodeCfg)
|
||||||
inodeCfgKey := fmt.Sprintf("/config/inode/%d/%d", poolId, imageId)
|
|
||||||
ctx, cancel := context.WithTimeout(context.Background(), ETCD_TIMEOUT)
|
|
||||||
resp, err := cli.Get(ctx, etcdPrefix+inodeCfgKey)
|
|
||||||
cancel()
|
|
||||||
if (err != nil)
|
if (err != nil)
|
||||||
{
|
{
|
||||||
return nil, status.Error(codes.Internal, "failed to read key from etcd: "+err.Error())
|
return nil, status.Error(codes.Internal, "Invalid JSON in vitastor-cli ls: "+err.Error())
|
||||||
}
|
}
|
||||||
if (len(resp.Kvs) == 0)
|
if (len(inodeCfg) == 0)
|
||||||
{
|
{
|
||||||
return nil, status.Error(codes.Internal, "missing "+inodeCfgKey+" key in etcd")
|
return nil, status.Error(codes.Internal, "vitastor-cli create said that image already exists, but ls can't find it")
|
||||||
}
|
}
|
||||||
var inodeCfg InodeConfig
|
if (inodeCfg[0].Size < uint64(volSize))
|
||||||
err = json.Unmarshal(resp.Kvs[0].Value, &inodeCfg)
|
|
||||||
if (err != nil)
|
|
||||||
{
|
|
||||||
return nil, status.Error(codes.Internal, "invalid "+inodeCfgKey+" key in etcd: "+err.Error())
|
|
||||||
}
|
|
||||||
if (inodeCfg.Size < uint64(volSize))
|
|
||||||
{
|
{
|
||||||
return nil, status.Error(codes.Internal, "image "+volName+" is already created, but size is less than expected")
|
return nil, status.Error(codes.Internal, "image "+volName+" is already created, but size is less than expected")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
// Find a free ID
|
return nil, err
|
||||||
// Create image metadata in a transaction verifying that the image doesn't exist yet AND ID is still free
|
|
||||||
maxIdKey := fmt.Sprintf("%s/index/maxid/%d", etcdPrefix, poolId)
|
|
||||||
ctx, cancel := context.WithTimeout(context.Background(), ETCD_TIMEOUT)
|
|
||||||
resp, err := cli.Get(ctx, maxIdKey)
|
|
||||||
cancel()
|
|
||||||
if (err != nil)
|
|
||||||
{
|
|
||||||
return nil, status.Error(codes.Internal, "failed to read key from etcd: "+err.Error())
|
|
||||||
}
|
|
||||||
var modRev int64
|
|
||||||
var nextId uint64
|
|
||||||
if (len(resp.Kvs) > 0)
|
|
||||||
{
|
|
||||||
var err error
|
|
||||||
nextId, err = strconv.ParseUint(string(resp.Kvs[0].Value), 10, 64)
|
|
||||||
if (err != nil)
|
|
||||||
{
|
|
||||||
return nil, status.Error(codes.Internal, maxIdKey+" contains invalid ID")
|
|
||||||
}
|
|
||||||
modRev = resp.Kvs[0].ModRevision
|
|
||||||
nextId++
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
nextId = 1
|
|
||||||
}
|
|
||||||
inodeIdxJson, _ := json.Marshal(InodeIndex{
|
|
||||||
Id: nextId,
|
|
||||||
PoolId: poolId,
|
|
||||||
})
|
|
||||||
inodeCfgJson, _ := json.Marshal(InodeConfig{
|
|
||||||
Name: volName,
|
|
||||||
Size: uint64(volSize),
|
|
||||||
})
|
|
||||||
ctx, cancel = context.WithTimeout(context.Background(), ETCD_TIMEOUT)
|
|
||||||
txnResp, err := cli.Txn(ctx).If(
|
|
||||||
clientv3.Compare(clientv3.ModRevision(fmt.Sprintf("%s/index/maxid/%d", etcdPrefix, poolId)), "=", modRev),
|
|
||||||
clientv3.Compare(clientv3.CreateRevision(fmt.Sprintf("%s/index/image/%s", etcdPrefix, volName)), "=", 0),
|
|
||||||
clientv3.Compare(clientv3.CreateRevision(fmt.Sprintf("%s/config/inode/%d/%d", etcdPrefix, poolId, nextId)), "=", 0),
|
|
||||||
).Then(
|
|
||||||
clientv3.OpPut(fmt.Sprintf("%s/index/maxid/%d", etcdPrefix, poolId), fmt.Sprintf("%d", nextId)),
|
|
||||||
clientv3.OpPut(fmt.Sprintf("%s/index/image/%s", etcdPrefix, volName), string(inodeIdxJson)),
|
|
||||||
clientv3.OpPut(fmt.Sprintf("%s/config/inode/%d/%d", etcdPrefix, poolId, nextId), string(inodeCfgJson)),
|
|
||||||
).Commit()
|
|
||||||
cancel()
|
|
||||||
if (err != nil)
|
|
||||||
{
|
|
||||||
return nil, status.Error(codes.Internal, "failed to commit transaction in etcd: "+err.Error())
|
|
||||||
}
|
|
||||||
if (txnResp.Succeeded)
|
|
||||||
{
|
|
||||||
imageId = nextId
|
|
||||||
break
|
|
||||||
}
|
|
||||||
// Start over if the transaction fails
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -299,97 +238,12 @@ func (cs *ControllerServer) DeleteVolume(ctx context.Context, req *csi.DeleteVol
|
|||||||
}
|
}
|
||||||
volName := ctxVars["name"]
|
volName := ctxVars["name"]
|
||||||
|
|
||||||
_, etcdUrl, etcdPrefix := GetConnectionParams(ctxVars)
|
ctxVars, _, _ = GetConnectionParams(ctxVars)
|
||||||
if (len(etcdUrl) == 0)
|
|
||||||
{
|
|
||||||
return nil, status.Error(codes.InvalidArgument, "no etcdUrl in storage class configuration and no etcd_address in vitastor.conf")
|
|
||||||
}
|
|
||||||
|
|
||||||
cli, err := clientv3.New(clientv3.Config{
|
_, err = invokeCLI(ctxVars, []string{ "rm", volName })
|
||||||
DialTimeout: ETCD_TIMEOUT,
|
|
||||||
Endpoints: etcdUrl,
|
|
||||||
})
|
|
||||||
if (err != nil)
|
if (err != nil)
|
||||||
{
|
{
|
||||||
return nil, status.Error(codes.Internal, "failed to connect to etcd at "+strings.Join(etcdUrl, ",")+": "+err.Error())
|
return nil, err
|
||||||
}
|
|
||||||
defer cli.Close()
|
|
||||||
|
|
||||||
// Find inode by name
|
|
||||||
ctx, cancel := context.WithTimeout(context.Background(), ETCD_TIMEOUT)
|
|
||||||
resp, err := cli.Get(ctx, etcdPrefix+"/index/image/"+volName)
|
|
||||||
cancel()
|
|
||||||
if (err != nil)
|
|
||||||
{
|
|
||||||
return nil, status.Error(codes.Internal, "failed to read key from etcd: "+err.Error())
|
|
||||||
}
|
|
||||||
if (len(resp.Kvs) == 0)
|
|
||||||
{
|
|
||||||
return nil, status.Error(codes.NotFound, "volume "+volName+" does not exist")
|
|
||||||
}
|
|
||||||
var idx InodeIndex
|
|
||||||
err = json.Unmarshal(resp.Kvs[0].Value, &idx)
|
|
||||||
if (err != nil)
|
|
||||||
{
|
|
||||||
return nil, status.Error(codes.Internal, "invalid /index/image/"+volName+" key in etcd: "+err.Error())
|
|
||||||
}
|
|
||||||
|
|
||||||
// Get inode config
|
|
||||||
inodeCfgKey := fmt.Sprintf("%s/config/inode/%d/%d", etcdPrefix, idx.PoolId, idx.Id)
|
|
||||||
ctx, cancel = context.WithTimeout(context.Background(), ETCD_TIMEOUT)
|
|
||||||
resp, err = cli.Get(ctx, inodeCfgKey)
|
|
||||||
cancel()
|
|
||||||
if (err != nil)
|
|
||||||
{
|
|
||||||
return nil, status.Error(codes.Internal, "failed to read key from etcd: "+err.Error())
|
|
||||||
}
|
|
||||||
if (len(resp.Kvs) == 0)
|
|
||||||
{
|
|
||||||
return nil, status.Error(codes.NotFound, "volume "+volName+" does not exist")
|
|
||||||
}
|
|
||||||
var inodeCfg InodeConfig
|
|
||||||
err = json.Unmarshal(resp.Kvs[0].Value, &inodeCfg)
|
|
||||||
if (err != nil)
|
|
||||||
{
|
|
||||||
return nil, status.Error(codes.Internal, "invalid "+inodeCfgKey+" key in etcd: "+err.Error())
|
|
||||||
}
|
|
||||||
|
|
||||||
// Delete inode data by invoking vitastor-cli
|
|
||||||
args := []string{
|
|
||||||
"rm-data", "--etcd_address", strings.Join(etcdUrl, ","),
|
|
||||||
"--pool", fmt.Sprintf("%d", idx.PoolId),
|
|
||||||
"--inode", fmt.Sprintf("%d", idx.Id),
|
|
||||||
}
|
|
||||||
if (ctxVars["configPath"] != "")
|
|
||||||
{
|
|
||||||
args = append(args, "--config_path", ctxVars["configPath"])
|
|
||||||
}
|
|
||||||
c := exec.Command("/usr/bin/vitastor-cli", args...)
|
|
||||||
var stderr bytes.Buffer
|
|
||||||
c.Stdout = nil
|
|
||||||
c.Stderr = &stderr
|
|
||||||
err = c.Run()
|
|
||||||
stderrStr := string(stderr.Bytes())
|
|
||||||
if (err != nil)
|
|
||||||
{
|
|
||||||
klog.Errorf("vitastor-cli rm-data failed: %s, status %s\n", stderrStr, err)
|
|
||||||
return nil, status.Error(codes.Internal, stderrStr+" (status "+err.Error()+")")
|
|
||||||
}
|
|
||||||
|
|
||||||
// Delete inode config in etcd
|
|
||||||
ctx, cancel = context.WithTimeout(context.Background(), ETCD_TIMEOUT)
|
|
||||||
txnResp, err := cli.Txn(ctx).Then(
|
|
||||||
clientv3.OpDelete(fmt.Sprintf("%s/index/image/%s", etcdPrefix, volName)),
|
|
||||||
clientv3.OpDelete(fmt.Sprintf("%s/config/inode/%d/%d", etcdPrefix, idx.PoolId, idx.Id)),
|
|
||||||
).Commit()
|
|
||||||
cancel()
|
|
||||||
if (err != nil)
|
|
||||||
{
|
|
||||||
return nil, status.Error(codes.Internal, "failed to delete keys in etcd: "+err.Error())
|
|
||||||
}
|
|
||||||
if (!txnResp.Succeeded)
|
|
||||||
{
|
|
||||||
return nil, status.Error(codes.Internal, "failed to delete keys in etcd: transaction failed")
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return &csi.DeleteVolumeResponse{}, nil
|
return &csi.DeleteVolumeResponse{}, nil
|
||||||
|
16
debian/changelog
vendored
16
debian/changelog
vendored
@@ -1,4 +1,18 @@
|
|||||||
vitastor (0.7.0-1) unstable; urgency=medium
|
vitastor (0.8.9-1) unstable; urgency=medium
|
||||||
|
|
||||||
|
* Bugfixes
|
||||||
|
|
||||||
|
-- Vitaliy Filippov <vitalif@yourcmc.ru> Fri, 03 Jun 2022 02:09:44 +0300
|
||||||
|
|
||||||
|
vitastor (0.8.9-1) unstable; urgency=medium
|
||||||
|
|
||||||
|
* Implement NFS proxy
|
||||||
|
* Add documentation
|
||||||
|
* Bugfixes
|
||||||
|
|
||||||
|
-- Vitaliy Filippov <vitalif@yourcmc.ru> Sun, 29 May 2022 23:39:13 +0300
|
||||||
|
|
||||||
|
vitastor (0.6.3-1) unstable; urgency=medium
|
||||||
|
|
||||||
* RDMA support
|
* RDMA support
|
||||||
* Bugfixes
|
* Bugfixes
|
||||||
|
4
debian/control
vendored
4
debian/control
vendored
@@ -2,7 +2,7 @@ Source: vitastor
|
|||||||
Section: admin
|
Section: admin
|
||||||
Priority: optional
|
Priority: optional
|
||||||
Maintainer: Vitaliy Filippov <vitalif@yourcmc.ru>
|
Maintainer: Vitaliy Filippov <vitalif@yourcmc.ru>
|
||||||
Build-Depends: debhelper, liburing-dev (>= 0.6), g++ (>= 8), libstdc++6 (>= 8), linux-libc-dev, libgoogle-perftools-dev, libjerasure-dev, libgf-complete-dev, libibverbs-dev
|
Build-Depends: debhelper, liburing-dev (>= 0.6), g++ (>= 8), libstdc++6 (>= 8), linux-libc-dev, libgoogle-perftools-dev, libjerasure-dev, libgf-complete-dev, libibverbs-dev, libisal-dev
|
||||||
Standards-Version: 4.5.0
|
Standards-Version: 4.5.0
|
||||||
Homepage: https://vitastor.io/
|
Homepage: https://vitastor.io/
|
||||||
Rules-Requires-Root: no
|
Rules-Requires-Root: no
|
||||||
@@ -18,7 +18,7 @@ Description: Vitastor, a fast software-defined clustered block storage
|
|||||||
|
|
||||||
Package: vitastor-osd
|
Package: vitastor-osd
|
||||||
Architecture: amd64
|
Architecture: amd64
|
||||||
Depends: ${shlibs:Depends}, ${misc:Depends}, vitastor-client (= ${binary:Version})
|
Depends: ${shlibs:Depends}, ${misc:Depends}, vitastor-client (= ${binary:Version}), fdisk, util-linux, parted
|
||||||
Description: Vitastor, a fast software-defined clustered block storage - object storage daemon
|
Description: Vitastor, a fast software-defined clustered block storage - object storage daemon
|
||||||
Vitastor object storage daemon, i.e. server program that stores data.
|
Vitastor object storage daemon, i.e. server program that stores data.
|
||||||
|
|
||||||
|
11
debian/libisal.pc
vendored
Normal file
11
debian/libisal.pc
vendored
Normal file
@@ -0,0 +1,11 @@
|
|||||||
|
prefix=/usr
|
||||||
|
exec_prefix=${prefix}
|
||||||
|
libdir=${prefix}/lib/x86_64-linux-gnu
|
||||||
|
includedir=${prefix}/include
|
||||||
|
|
||||||
|
Name: libisal
|
||||||
|
Description: Library for storage systems
|
||||||
|
Version: 2.30.0
|
||||||
|
Libs: -L${libdir} -lisal
|
||||||
|
Libs.private:
|
||||||
|
Cflags: -I${includedir}
|
2
debian/pve-storage-vitastor.install
vendored
2
debian/pve-storage-vitastor.install
vendored
@@ -1 +1 @@
|
|||||||
patches/PVE_VitastorPlugin.pm usr/share/perl5/PVE/Storage/Custom/VitastorPlugin.pm
|
patches/VitastorPlugin.pm usr/share/perl5/PVE/Storage/Custom/
|
||||||
|
1
debian/vitastor-client.install
vendored
1
debian/vitastor-client.install
vendored
@@ -4,4 +4,3 @@ usr/bin/vitastor-rm
|
|||||||
usr/bin/vitastor-nbd
|
usr/bin/vitastor-nbd
|
||||||
usr/bin/vitastor-nfs
|
usr/bin/vitastor-nfs
|
||||||
usr/lib/*/libvitastor*.so*
|
usr/lib/*/libvitastor*.so*
|
||||||
mon/make-osd.sh /usr/lib/vitastor
|
|
||||||
|
1
debian/vitastor-mon.install
vendored
1
debian/vitastor-mon.install
vendored
@@ -1 +1,2 @@
|
|||||||
mon usr/lib/vitastor
|
mon usr/lib/vitastor
|
||||||
|
mon/vitastor-mon.service /lib/systemd/system
|
||||||
|
9
debian/vitastor-mon.postinst
vendored
Normal file
9
debian/vitastor-mon.postinst
vendored
Normal file
@@ -0,0 +1,9 @@
|
|||||||
|
#!/bin/sh
|
||||||
|
|
||||||
|
set -e
|
||||||
|
|
||||||
|
if [ "$1" = "configure" ]; then
|
||||||
|
addgroup --system --quiet vitastor
|
||||||
|
adduser --system --quiet --ingroup vitastor --no-create-home --home /nonexistent vitastor
|
||||||
|
mkdir -p /etc/vitastor
|
||||||
|
fi
|
4
debian/vitastor-osd.install
vendored
4
debian/vitastor-osd.install
vendored
@@ -1,2 +1,6 @@
|
|||||||
usr/bin/vitastor-osd
|
usr/bin/vitastor-osd
|
||||||
|
usr/bin/vitastor-disk
|
||||||
usr/bin/vitastor-dump-journal
|
usr/bin/vitastor-dump-journal
|
||||||
|
mon/vitastor-osd@.service /lib/systemd/system
|
||||||
|
mon/vitastor.target /lib/systemd/system
|
||||||
|
mon/90-vitastor.rules /lib/udev/rules.d
|
||||||
|
10
debian/vitastor-osd.postinst
vendored
Normal file
10
debian/vitastor-osd.postinst
vendored
Normal file
@@ -0,0 +1,10 @@
|
|||||||
|
#!/bin/sh
|
||||||
|
|
||||||
|
set -e
|
||||||
|
|
||||||
|
if [ "$1" = "configure" ]; then
|
||||||
|
addgroup --system --quiet vitastor
|
||||||
|
adduser --system --quiet --ingroup vitastor --no-create-home --home /nonexistent vitastor
|
||||||
|
install -o vitastor -g vitastor -d /var/log/vitastor
|
||||||
|
mkdir -p /etc/vitastor
|
||||||
|
fi
|
11
debian/vitastor.Dockerfile
vendored
11
debian/vitastor.Dockerfile
vendored
@@ -22,10 +22,11 @@ RUN apt-get update
|
|||||||
RUN apt-get -y install fio liburing1 liburing-dev libgoogle-perftools-dev devscripts
|
RUN apt-get -y install fio liburing1 liburing-dev libgoogle-perftools-dev devscripts
|
||||||
RUN apt-get -y build-dep fio
|
RUN apt-get -y build-dep fio
|
||||||
RUN apt-get --download-only source fio
|
RUN apt-get --download-only source fio
|
||||||
RUN apt-get update && apt-get -y install libjerasure-dev cmake libibverbs-dev
|
RUN apt-get update && apt-get -y install libjerasure-dev cmake libibverbs-dev libisal-dev
|
||||||
|
|
||||||
ADD . /root/vitastor
|
ADD . /root/vitastor
|
||||||
RUN set -e -x; \
|
RUN set -e -x; \
|
||||||
|
[ -e /usr/lib/x86_64-linux-gnu/pkgconfig/libisal.pc ] || cp /root/vitastor/debian/libisal.pc /usr/lib/x86_64-linux-gnu/pkgconfig; \
|
||||||
mkdir -p /root/fio-build/; \
|
mkdir -p /root/fio-build/; \
|
||||||
cd /root/fio-build/; \
|
cd /root/fio-build/; \
|
||||||
rm -rf /root/fio-build/*; \
|
rm -rf /root/fio-build/*; \
|
||||||
@@ -33,8 +34,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-0.7.0; \
|
cp -r /root/vitastor vitastor-0.8.9; \
|
||||||
cd vitastor-0.7.0; \
|
cd vitastor-0.8.9; \
|
||||||
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; \
|
||||||
@@ -47,8 +48,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_0.7.0.orig.tar.xz vitastor-0.7.0; \
|
tar --sort=name --mtime='2020-01-01' --owner=0 --group=0 --exclude=debian -cJf vitastor_0.8.9.orig.tar.xz vitastor-0.8.9; \
|
||||||
cd vitastor-0.7.0; \
|
cd vitastor-0.8.9; \
|
||||||
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; \
|
||||||
|
Binary file not shown.
@@ -17,14 +17,16 @@ Configuration parameters can be set in 3 places:
|
|||||||
- Configuration file (`/etc/vitastor/vitastor.conf` or other path)
|
- Configuration file (`/etc/vitastor/vitastor.conf` or other path)
|
||||||
- etcd key `/vitastor/config/global`. Most variables can be set there, but etcd
|
- etcd key `/vitastor/config/global`. Most variables can be set there, but etcd
|
||||||
connection parameters should obviously be set in the configuration file.
|
connection parameters should obviously be set in the configuration file.
|
||||||
- Command line of Vitastor components: OSD, mon, fio and QEMU options,
|
- Command line of Vitastor components: OSD (when you run it without vitastor-disk),
|
||||||
OpenStack/Proxmox/etc configuration. The latter doesn't allow to set all
|
mon, fio and QEMU options, OpenStack/Proxmox/etc configuration. The latter
|
||||||
variables directly, but it allows to override the configuration file and
|
doesn't allow to set all variables directly, but it allows to override the
|
||||||
set everything you need inside it.
|
configuration file and set everything you need inside it.
|
||||||
|
- OSD superblocks created by [vitastor-disk](../usage/disk.en.md) contain
|
||||||
|
primarily disk layout parameters of specific OSDs. In fact, these parameters
|
||||||
|
are automatically passed into the command line of vitastor-osd process, so
|
||||||
|
they have the same "status" as command-line parameters.
|
||||||
|
|
||||||
In the future, additional configuration methods may be added:
|
In the future, additional configuration methods may be added:
|
||||||
- OSD superblock which will, by design, contain parameters related to the disk
|
|
||||||
layout and to one specific OSD.
|
|
||||||
- OSD-specific keys in etcd like `/vitastor/config/osd/<number>`.
|
- OSD-specific keys in etcd like `/vitastor/config/osd/<number>`.
|
||||||
|
|
||||||
## Parameter Reference
|
## Parameter Reference
|
||||||
|
@@ -19,14 +19,17 @@
|
|||||||
- Ключе в etcd `/vitastor/config/global`. Большая часть параметров может
|
- Ключе в etcd `/vitastor/config/global`. Большая часть параметров может
|
||||||
задаваться там, кроме, естественно, самих параметров соединения с etcd,
|
задаваться там, кроме, естественно, самих параметров соединения с etcd,
|
||||||
которые должны задаваться в файле конфигурации
|
которые должны задаваться в файле конфигурации
|
||||||
- В командной строке компонентов Vitastor: OSD, монитора, опциях fio и QEMU,
|
- В командной строке компонентов Vitastor: OSD (при ручном запуске без vitastor-disk),
|
||||||
настроек OpenStack, Proxmox и т.п. Последние, как правило, не включают полный
|
монитора, опциях fio и QEMU, настроек OpenStack, Proxmox и т.п. Последние,
|
||||||
набор параметров напрямую, но разрешают определить путь к файлу конфигурации
|
как правило, не включают полный набор параметров напрямую, но позволяют
|
||||||
и задать любые параметры в нём.
|
определить путь к файлу конфигурации и задать любые параметры в нём.
|
||||||
|
- В суперблоке OSD, записываемом [vitastor-disk](../usage/disk.ru.md) - параметры,
|
||||||
|
связанные с дисковым форматом и с этим конкретным OSD. На самом деле,
|
||||||
|
при запуске OSD эти параметры автоматически передаются в командную строку
|
||||||
|
процесса vitastor-osd, то есть по "статусу" они эквивалентны параметрам
|
||||||
|
командной строки OSD.
|
||||||
|
|
||||||
В будущем также могут быть добавлены другие способы конфигурации:
|
В будущем также могут быть добавлены другие способы конфигурации:
|
||||||
- Суперблок OSD, в котором будут храниться параметры OSD, связанные с дисковым
|
|
||||||
форматом и с этим конкретным OSD.
|
|
||||||
- OSD-специфичные ключи в etcd типа `/vitastor/config/osd/<номер>`.
|
- OSD-специфичные ключи в etcd типа `/vitastor/config/osd/<номер>`.
|
||||||
|
|
||||||
## Список параметров
|
## Список параметров
|
||||||
|
@@ -9,34 +9,34 @@
|
|||||||
These parameters apply to clients and OSDs, are fixed at the moment of OSD drive
|
These parameters apply to clients and OSDs, are fixed at the moment of OSD drive
|
||||||
initialization and can't be changed after it without losing data.
|
initialization and can't be changed after it without losing data.
|
||||||
|
|
||||||
|
OSDs with different values of these parameters (for example, SSD and SSD+HDD
|
||||||
|
OSDs) can coexist in one Vitastor cluster within different pools. Each pool can
|
||||||
|
only include OSDs with identical settings of these parameters.
|
||||||
|
|
||||||
|
These parameters, when set to a non-default value, must also be specified in
|
||||||
|
etcd for clients to be aware of their values, either in /vitastor/config/global
|
||||||
|
or in pool configuration. Pool configuration overrides the global setting.
|
||||||
|
If the value for a pool in etcd doesn't match on-disk OSD configuration, the
|
||||||
|
OSD will refuse to start PGs of that pool.
|
||||||
|
|
||||||
- [block_size](#block_size)
|
- [block_size](#block_size)
|
||||||
- [bitmap_granularity](#bitmap_granularity)
|
- [bitmap_granularity](#bitmap_granularity)
|
||||||
- [immediate_commit](#immediate_commit)
|
- [immediate_commit](#immediate_commit)
|
||||||
- [client_dirty_limit](#client_dirty_limit)
|
|
||||||
|
|
||||||
## block_size
|
## block_size
|
||||||
|
|
||||||
- Type: integer
|
- Type: integer
|
||||||
- Default: 131072
|
- Default: 131072
|
||||||
|
|
||||||
Size of objects (data blocks) into which all physical and virtual drives are
|
Size of objects (data blocks) into which all physical and virtual drives
|
||||||
subdivided in Vitastor. One of current main settings in Vitastor, affects
|
(within a pool) are subdivided in Vitastor. One of current main settings
|
||||||
memory usage, write amplification and I/O load distribution effectiveness.
|
in Vitastor, affects memory usage, write amplification and I/O load
|
||||||
|
distribution effectiveness.
|
||||||
|
|
||||||
Recommended default block size is 128 KB for SSD and 4 MB for HDD. In fact,
|
Recommended default block size is 128 KB for SSD and 4 MB for HDD. In fact,
|
||||||
it's possible to use 4 MB for SSD too - it will lower memory usage, but
|
it's possible to use 4 MB for SSD too - it will lower memory usage, but
|
||||||
may increase average WA and reduce linear performance.
|
may increase average WA and reduce linear performance.
|
||||||
|
|
||||||
OSDs with different block sizes (for example, SSD and SSD+HDD OSDs) can
|
|
||||||
currently coexist in one etcd instance only within separate Vitastor
|
|
||||||
clusters with different etcd_prefix'es.
|
|
||||||
|
|
||||||
Also block size can't be changed after OSD initialization without losing
|
|
||||||
data.
|
|
||||||
|
|
||||||
You must always specify block_size in etcd in /vitastor/config/global if
|
|
||||||
you change it so all clients can know about it.
|
|
||||||
|
|
||||||
OSD memory usage is roughly (SIZE / BLOCK * 68 bytes) which is roughly
|
OSD memory usage is roughly (SIZE / BLOCK * 68 bytes) which is roughly
|
||||||
544 MB per 1 TB of used disk space with the default 128 KB block size.
|
544 MB per 1 TB of used disk space with the default 128 KB block size.
|
||||||
|
|
||||||
@@ -50,12 +50,7 @@ of disk_alignment. It's called bitmap granularity because Vitastor tracks
|
|||||||
an allocation bitmap for each object containing 2 bits per each
|
an allocation bitmap for each object containing 2 bits per each
|
||||||
(bitmap_granularity) bytes.
|
(bitmap_granularity) bytes.
|
||||||
|
|
||||||
This parameter can't be changed after OSD initialization without losing
|
Can't be smaller than the OSD data device sector.
|
||||||
data. Also it's fixed for the whole Vitastor cluster i.e. two different
|
|
||||||
values can't be used in a single Vitastor cluster.
|
|
||||||
|
|
||||||
Clients MUST be aware of this parameter value, so put it into etcd key
|
|
||||||
/vitastor/config/global if you change it for any reason.
|
|
||||||
|
|
||||||
## immediate_commit
|
## immediate_commit
|
||||||
|
|
||||||
@@ -99,26 +94,12 @@ unsafe to change by hand). The same may apply to newer HDDs with internal
|
|||||||
SSD cache or "media-cache" - for example, a lot of Seagate EXOS drives have
|
SSD cache or "media-cache" - for example, a lot of Seagate EXOS drives have
|
||||||
it (they have internal SSD cache even though it's not stated in datasheets).
|
it (they have internal SSD cache even though it's not stated in datasheets).
|
||||||
|
|
||||||
This parameter must be set both in etcd in /vitastor/config/global and in
|
Setting this parameter to "all" or "small" in OSD parameters requires enabling
|
||||||
OSD command line or configuration. Setting it to "all" or "small" requires
|
disable_journal_fsync and disable_meta_fsync, setting it to "all" also requires
|
||||||
enabling disable_journal_fsync and disable_meta_fsync, setting it to "all"
|
enabling disable_data_fsync.
|
||||||
also requires enabling disable_data_fsync.
|
|
||||||
|
|
||||||
TLDR: For optimal performance, set immediate_commit to "all" if you only use
|
TLDR: For optimal performance, set immediate_commit to "all" if you only use
|
||||||
SSDs with supercapacitor-based power loss protection (nonvolatile
|
SSDs with supercapacitor-based power loss protection (nonvolatile
|
||||||
write-through cache) for both data and journals in the whole Vitastor
|
write-through cache) for both data and journals in the whole Vitastor
|
||||||
cluster. Set it to "small" if you only use such SSDs for journals. Leave
|
cluster. Set it to "small" if you only use such SSDs for journals. Leave
|
||||||
empty if your drives have write-back cache.
|
empty if your drives have write-back cache.
|
||||||
|
|
||||||
## client_dirty_limit
|
|
||||||
|
|
||||||
- Type: integer
|
|
||||||
- Default: 33554432
|
|
||||||
|
|
||||||
Without immediate_commit=all this parameter sets the limit of "dirty"
|
|
||||||
(not committed by fsync) data allowed by the client before forcing an
|
|
||||||
additional fsync and committing the data. Also note that the client always
|
|
||||||
holds a copy of uncommitted data in memory so this setting also affects
|
|
||||||
RAM usage of clients.
|
|
||||||
|
|
||||||
This parameter doesn't affect OSDs themselves.
|
|
||||||
|
@@ -9,10 +9,19 @@
|
|||||||
Данные параметры используются клиентами и OSD, задаются в момент инициализации
|
Данные параметры используются клиентами и OSD, задаются в момент инициализации
|
||||||
диска OSD и не могут быть изменены после этого без потери данных.
|
диска OSD и не могут быть изменены после этого без потери данных.
|
||||||
|
|
||||||
|
OSD с разными значениями данных параметров (например, SSD и гибридные SSD+HDD
|
||||||
|
OSD) могут сосуществовать в одном кластере Vitastor в разных пулах. Один пул
|
||||||
|
может включать только OSD с одинаковыми настройками этих параметров.
|
||||||
|
|
||||||
|
Данные параметры, отличаясь от значения по умолчанию, должны также быть заданы
|
||||||
|
в etcd, чтобы клиенты могли узнать их значение, либо в глобальной конфигурации
|
||||||
|
/vitastor/config/global, либо в настройках пулов. Настройки пула переопределяют
|
||||||
|
глобальное значение. Если значение в настройках пула не будет соответствовать
|
||||||
|
конфигурации OSD, OSD откажется запускать PG данного пула.
|
||||||
|
|
||||||
- [block_size](#block_size)
|
- [block_size](#block_size)
|
||||||
- [bitmap_granularity](#bitmap_granularity)
|
- [bitmap_granularity](#bitmap_granularity)
|
||||||
- [immediate_commit](#immediate_commit)
|
- [immediate_commit](#immediate_commit)
|
||||||
- [client_dirty_limit](#client_dirty_limit)
|
|
||||||
|
|
||||||
## block_size
|
## block_size
|
||||||
|
|
||||||
@@ -20,24 +29,15 @@
|
|||||||
- Значение по умолчанию: 131072
|
- Значение по умолчанию: 131072
|
||||||
|
|
||||||
Размер объектов (блоков данных), на которые делятся физические и виртуальные
|
Размер объектов (блоков данных), на которые делятся физические и виртуальные
|
||||||
диски в Vitastor. Одна из ключевых на данный момент настроек, влияет на
|
диски в Vitastor (в рамках каждого пула). Одна из ключевых на данный момент
|
||||||
потребление памяти, объём избыточной записи (write amplification) и
|
настроек, влияет на потребление памяти, объём избыточной записи (write
|
||||||
эффективность распределения нагрузки по OSD.
|
amplification) и эффективность распределения нагрузки по OSD.
|
||||||
|
|
||||||
Рекомендуемые по умолчанию размеры блока - 128 килобайт для SSD и 4
|
Рекомендуемые по умолчанию размеры блока - 128 килобайт для SSD и 4
|
||||||
мегабайта для HDD. В принципе, для SSD можно тоже использовать 4 мегабайта,
|
мегабайта для HDD. В принципе, для SSD можно тоже использовать 4 мегабайта,
|
||||||
это понизит использование памяти, но ухудшит распределение нагрузки и в
|
это понизит использование памяти, но ухудшит распределение нагрузки и в
|
||||||
среднем увеличит WA.
|
среднем увеличит WA.
|
||||||
|
|
||||||
OSD с разными размерами блока (например, SSD и SSD+HDD OSD) на данный
|
|
||||||
момент могут сосуществовать в рамках одного etcd только в виде двух независимых
|
|
||||||
кластеров Vitastor с разными etcd_prefix.
|
|
||||||
|
|
||||||
Также размер блока нельзя менять после инициализации OSD без потери данных.
|
|
||||||
|
|
||||||
Если вы меняете размер блока, обязательно прописывайте его в etcd в
|
|
||||||
/vitastor/config/global, дабы все клиенты его знали.
|
|
||||||
|
|
||||||
Потребление памяти OSD составляет примерно (РАЗМЕР / БЛОК * 68 байт),
|
Потребление памяти OSD составляет примерно (РАЗМЕР / БЛОК * 68 байт),
|
||||||
т.е. примерно 544 МБ памяти на 1 ТБ занятого места на диске при
|
т.е. примерно 544 МБ памяти на 1 ТБ занятого места на диске при
|
||||||
стандартном 128 КБ блоке.
|
стандартном 128 КБ блоке.
|
||||||
@@ -52,13 +52,7 @@ OSD с разными размерами блока (например, SSD и SS
|
|||||||
потому, что Vitastor хранит битовую карту для каждого объекта, содержащую
|
потому, что Vitastor хранит битовую карту для каждого объекта, содержащую
|
||||||
по 2 бита на каждые (bitmap_granularity) байт.
|
по 2 бита на каждые (bitmap_granularity) байт.
|
||||||
|
|
||||||
Данный параметр нельзя менять после инициализации OSD без потери данных.
|
Не может быть меньше размера сектора дисков данных OSD.
|
||||||
Также он фиксирован для всего кластера Vitastor, т.е. разные значения
|
|
||||||
не могут сосуществовать в одном кластере.
|
|
||||||
|
|
||||||
Клиенты ДОЛЖНЫ знать правильное значение этого параметра, так что если вы
|
|
||||||
его меняете, обязательно прописывайте изменённое значение в etcd в ключ
|
|
||||||
/vitastor/config/global.
|
|
||||||
|
|
||||||
## immediate_commit
|
## immediate_commit
|
||||||
|
|
||||||
@@ -108,8 +102,7 @@ HDD-дисках с внутренним SSD или "медиа" кэшем - н
|
|||||||
многих дисках Seagate EXOS (у них есть внутренний SSD-кэш, хотя это и не
|
многих дисках Seagate EXOS (у них есть внутренний SSD-кэш, хотя это и не
|
||||||
указано в спецификациях).
|
указано в спецификациях).
|
||||||
|
|
||||||
Данный параметр нужно указывать и в etcd в /vitastor/config/global, и в
|
Указание "all" или "small" в настройках / командной строке OSD требует
|
||||||
командной строке или конфигурации OSD. Значения "all" и "small" требуют
|
|
||||||
включения disable_journal_fsync и disable_meta_fsync, значение "all" также
|
включения disable_journal_fsync и disable_meta_fsync, значение "all" также
|
||||||
требует включения disable_data_fsync.
|
требует включения disable_data_fsync.
|
||||||
|
|
||||||
@@ -119,16 +112,3 @@ immediate_commit в значение "all", если вы используете
|
|||||||
такие SSD для всех журналов, но не для данных - можете установить параметр
|
такие SSD для всех журналов, но не для данных - можете установить параметр
|
||||||
в "small". Если и какие-то из дисков журналов имеют волатильный кэш записи -
|
в "small". Если и какие-то из дисков журналов имеют волатильный кэш записи -
|
||||||
оставьте параметр пустым.
|
оставьте параметр пустым.
|
||||||
|
|
||||||
## client_dirty_limit
|
|
||||||
|
|
||||||
- Тип: целое число
|
|
||||||
- Значение по умолчанию: 33554432
|
|
||||||
|
|
||||||
При работе без immediate_commit=all - это лимит объёма "грязных" (не
|
|
||||||
зафиксированных fsync-ом) данных, при достижении которого клиент будет
|
|
||||||
принудительно вызывать fsync и фиксировать данные. Также стоит иметь в виду,
|
|
||||||
что в этом случае до момента fsync клиент хранит копию незафиксированных
|
|
||||||
данных в памяти, то есть, настройка влияет на потребление памяти клиентами.
|
|
||||||
|
|
||||||
Параметр не влияет на сами OSD.
|
|
||||||
|
@@ -19,6 +19,7 @@ between clients, OSDs and etcd.
|
|||||||
- [rdma_max_sge](#rdma_max_sge)
|
- [rdma_max_sge](#rdma_max_sge)
|
||||||
- [rdma_max_msg](#rdma_max_msg)
|
- [rdma_max_msg](#rdma_max_msg)
|
||||||
- [rdma_max_recv](#rdma_max_recv)
|
- [rdma_max_recv](#rdma_max_recv)
|
||||||
|
- [rdma_max_send](#rdma_max_send)
|
||||||
- [peer_connect_interval](#peer_connect_interval)
|
- [peer_connect_interval](#peer_connect_interval)
|
||||||
- [peer_connect_timeout](#peer_connect_timeout)
|
- [peer_connect_timeout](#peer_connect_timeout)
|
||||||
- [osd_idle_timeout](#osd_idle_timeout)
|
- [osd_idle_timeout](#osd_idle_timeout)
|
||||||
@@ -29,6 +30,7 @@ between clients, OSDs and etcd.
|
|||||||
- [etcd_slow_timeout](#etcd_slow_timeout)
|
- [etcd_slow_timeout](#etcd_slow_timeout)
|
||||||
- [etcd_keepalive_timeout](#etcd_keepalive_timeout)
|
- [etcd_keepalive_timeout](#etcd_keepalive_timeout)
|
||||||
- [etcd_ws_keepalive_timeout](#etcd_ws_keepalive_timeout)
|
- [etcd_ws_keepalive_timeout](#etcd_ws_keepalive_timeout)
|
||||||
|
- [client_dirty_limit](#client_dirty_limit)
|
||||||
|
|
||||||
## tcp_header_buffer_size
|
## tcp_header_buffer_size
|
||||||
|
|
||||||
@@ -73,6 +75,12 @@ to work. For example, Mellanox ConnectX-3 and older adapters don't have
|
|||||||
Implicit ODP, so they're unsupported by Vitastor. Run `ibv_devinfo -v` as
|
Implicit ODP, so they're unsupported by Vitastor. Run `ibv_devinfo -v` as
|
||||||
root to list available RDMA devices and their features.
|
root to list available RDMA devices and their features.
|
||||||
|
|
||||||
|
Remember that you also have to configure your network switches if you use
|
||||||
|
RoCE/RoCEv2, otherwise you may experience unstable performance. Refer to
|
||||||
|
the manual of your network vendor for details about setting up the switch
|
||||||
|
for RoCEv2 correctly. Usually it means setting up Lossless Ethernet with
|
||||||
|
PFC (Priority Flow Control) and ECN (Explicit Congestion Notification).
|
||||||
|
|
||||||
## rdma_port_num
|
## rdma_port_num
|
||||||
|
|
||||||
- Type: integer
|
- Type: integer
|
||||||
@@ -115,20 +123,30 @@ required to change this parameter.
|
|||||||
## rdma_max_msg
|
## rdma_max_msg
|
||||||
|
|
||||||
- Type: integer
|
- Type: integer
|
||||||
- Default: 1048576
|
- Default: 132096
|
||||||
|
|
||||||
Maximum size of a single RDMA send or receive operation in bytes.
|
Maximum size of a single RDMA send or receive operation in bytes.
|
||||||
|
|
||||||
## rdma_max_recv
|
## rdma_max_recv
|
||||||
|
|
||||||
|
- Type: integer
|
||||||
|
- Default: 16
|
||||||
|
|
||||||
|
Maximum number of RDMA receive buffers per connection (RDMA requires
|
||||||
|
preallocated buffers to receive data). Each buffer is `rdma_max_msg` bytes
|
||||||
|
in size. So this setting directly affects memory usage: a single Vitastor
|
||||||
|
RDMA client uses `rdma_max_recv * rdma_max_msg * OSD_COUNT` bytes of memory.
|
||||||
|
Default is roughly 2 MB * number of OSDs.
|
||||||
|
|
||||||
|
## rdma_max_send
|
||||||
|
|
||||||
- Type: integer
|
- Type: integer
|
||||||
- Default: 8
|
- Default: 8
|
||||||
|
|
||||||
Maximum number of parallel RDMA receive operations. Note that this number
|
Maximum number of outstanding RDMA send operations per connection. Should be
|
||||||
of receive buffers `rdma_max_msg` in size are allocated for each client,
|
less than `rdma_max_recv` so the receiving side doesn't run out of buffers.
|
||||||
so this setting actually affects memory usage. This is because RDMA receive
|
Doesn't affect memory usage - additional memory isn't allocated for send
|
||||||
operations are (sadly) still not zero-copy in Vitastor. It may be fixed in
|
operations.
|
||||||
later versions.
|
|
||||||
|
|
||||||
## peer_connect_interval
|
## peer_connect_interval
|
||||||
|
|
||||||
@@ -212,3 +230,16 @@ etcd_report_interval to guarantee that keepalive actually works.
|
|||||||
|
|
||||||
etcd websocket ping interval required to keep the connection alive and
|
etcd websocket ping interval required to keep the connection alive and
|
||||||
detect disconnections quickly.
|
detect disconnections quickly.
|
||||||
|
|
||||||
|
## client_dirty_limit
|
||||||
|
|
||||||
|
- Type: integer
|
||||||
|
- Default: 33554432
|
||||||
|
|
||||||
|
Without immediate_commit=all this parameter sets the limit of "dirty"
|
||||||
|
(not committed by fsync) data allowed by the client before forcing an
|
||||||
|
additional fsync and committing the data. Also note that the client always
|
||||||
|
holds a copy of uncommitted data in memory so this setting also affects
|
||||||
|
RAM usage of clients.
|
||||||
|
|
||||||
|
This parameter doesn't affect OSDs themselves.
|
||||||
|
@@ -19,6 +19,7 @@
|
|||||||
- [rdma_max_sge](#rdma_max_sge)
|
- [rdma_max_sge](#rdma_max_sge)
|
||||||
- [rdma_max_msg](#rdma_max_msg)
|
- [rdma_max_msg](#rdma_max_msg)
|
||||||
- [rdma_max_recv](#rdma_max_recv)
|
- [rdma_max_recv](#rdma_max_recv)
|
||||||
|
- [rdma_max_send](#rdma_max_send)
|
||||||
- [peer_connect_interval](#peer_connect_interval)
|
- [peer_connect_interval](#peer_connect_interval)
|
||||||
- [peer_connect_timeout](#peer_connect_timeout)
|
- [peer_connect_timeout](#peer_connect_timeout)
|
||||||
- [osd_idle_timeout](#osd_idle_timeout)
|
- [osd_idle_timeout](#osd_idle_timeout)
|
||||||
@@ -29,6 +30,7 @@
|
|||||||
- [etcd_slow_timeout](#etcd_slow_timeout)
|
- [etcd_slow_timeout](#etcd_slow_timeout)
|
||||||
- [etcd_keepalive_timeout](#etcd_keepalive_timeout)
|
- [etcd_keepalive_timeout](#etcd_keepalive_timeout)
|
||||||
- [etcd_ws_keepalive_timeout](#etcd_ws_keepalive_timeout)
|
- [etcd_ws_keepalive_timeout](#etcd_ws_keepalive_timeout)
|
||||||
|
- [client_dirty_limit](#client_dirty_limit)
|
||||||
|
|
||||||
## tcp_header_buffer_size
|
## tcp_header_buffer_size
|
||||||
|
|
||||||
@@ -77,6 +79,13 @@ Implicit On-Demand Paging (Implicit ODP) и Scatter/Gather (SG). Наприме
|
|||||||
суперпользователя, чтобы посмотреть список доступных RDMA-устройств, их
|
суперпользователя, чтобы посмотреть список доступных RDMA-устройств, их
|
||||||
параметры и возможности.
|
параметры и возможности.
|
||||||
|
|
||||||
|
Обратите внимание, что если вы используете RoCE/RoCEv2, вам также необходимо
|
||||||
|
правильно настроить для него коммутаторы, иначе вы можете столкнуться с
|
||||||
|
нестабильной производительностью. Подробную информацию о настройке
|
||||||
|
коммутатора для RoCEv2 ищите в документации производителя. Обычно это
|
||||||
|
подразумевает настройку сети без потерь на основе PFC (Priority Flow
|
||||||
|
Control) и ECN (Explicit Congestion Notification).
|
||||||
|
|
||||||
## rdma_port_num
|
## rdma_port_num
|
||||||
|
|
||||||
- Тип: целое число
|
- Тип: целое число
|
||||||
@@ -120,22 +129,32 @@ OSD в любом случае согласовывают реальное зн
|
|||||||
## rdma_max_msg
|
## rdma_max_msg
|
||||||
|
|
||||||
- Тип: целое число
|
- Тип: целое число
|
||||||
- Значение по умолчанию: 1048576
|
- Значение по умолчанию: 132096
|
||||||
|
|
||||||
Максимальный размер одной RDMA-операции отправки или приёма.
|
Максимальный размер одной RDMA-операции отправки или приёма.
|
||||||
|
|
||||||
## rdma_max_recv
|
## rdma_max_recv
|
||||||
|
|
||||||
|
- Тип: целое число
|
||||||
|
- Значение по умолчанию: 16
|
||||||
|
|
||||||
|
Максимальное число буферов для RDMA-приёма данных на одно соединение
|
||||||
|
(RDMA требует заранее выделенных буферов для приёма данных). Каждый буфер
|
||||||
|
имеет размер `rdma_max_msg` байт. Таким образом, настройка прямо влияет на
|
||||||
|
потребление памяти - один Vitastor-клиент с RDMA использует
|
||||||
|
`rdma_max_recv * rdma_max_msg * ЧИСЛО_OSD` байт памяти, по умолчанию -
|
||||||
|
примерно 2 МБ * число OSD.
|
||||||
|
|
||||||
|
## rdma_max_send
|
||||||
|
|
||||||
- Тип: целое число
|
- Тип: целое число
|
||||||
- Значение по умолчанию: 8
|
- Значение по умолчанию: 8
|
||||||
|
|
||||||
Максимальное число параллельных RDMA-операций получения данных. Следует
|
Максимальное число RDMA-операций отправки, отправляемых в очередь одного
|
||||||
иметь в виду, что данное число буферов размером `rdma_max_msg` выделяется
|
соединения. Желательно, чтобы оно было меньше `rdma_max_recv`, чтобы
|
||||||
для каждого подключённого клиентского соединения, так что данная настройка
|
у принимающей стороны в процессе работы не заканчивались буферы на приём.
|
||||||
влияет на потребление памяти. Это так потому, что RDMA-приём данных в
|
Не влияет на потребление памяти - дополнительная память на операции отправки
|
||||||
Vitastor, увы, всё равно не является zero-copy, т.е. всё равно 1 раз
|
не выделяется.
|
||||||
копирует данные в памяти. Данная особенность, возможно, будет исправлена в
|
|
||||||
более новых версиях Vitastor.
|
|
||||||
|
|
||||||
## peer_connect_interval
|
## peer_connect_interval
|
||||||
|
|
||||||
@@ -222,3 +241,16 @@ etcd_report_interval, чтобы keepalive гарантированно рабо
|
|||||||
- Значение по умолчанию: 30
|
- Значение по умолчанию: 30
|
||||||
|
|
||||||
Интервал проверки живости вебсокет-подключений к etcd.
|
Интервал проверки живости вебсокет-подключений к etcd.
|
||||||
|
|
||||||
|
## client_dirty_limit
|
||||||
|
|
||||||
|
- Тип: целое число
|
||||||
|
- Значение по умолчанию: 33554432
|
||||||
|
|
||||||
|
При работе без immediate_commit=all - это лимит объёма "грязных" (не
|
||||||
|
зафиксированных fsync-ом) данных, при достижении которого клиент будет
|
||||||
|
принудительно вызывать fsync и фиксировать данные. Также стоит иметь в виду,
|
||||||
|
что в этом случае до момента fsync клиент хранит копию незафиксированных
|
||||||
|
данных в памяти, то есть, настройка влияет на потребление памяти клиентами.
|
||||||
|
|
||||||
|
Параметр не влияет на сами OSD.
|
||||||
|
@@ -17,12 +17,14 @@ initialization and can be changed with an OSD restart.
|
|||||||
- [autosync_interval](#autosync_interval)
|
- [autosync_interval](#autosync_interval)
|
||||||
- [autosync_writes](#autosync_writes)
|
- [autosync_writes](#autosync_writes)
|
||||||
- [recovery_queue_depth](#recovery_queue_depth)
|
- [recovery_queue_depth](#recovery_queue_depth)
|
||||||
|
- [recovery_pg_switch](#recovery_pg_switch)
|
||||||
- [recovery_sync_batch](#recovery_sync_batch)
|
- [recovery_sync_batch](#recovery_sync_batch)
|
||||||
- [readonly](#readonly)
|
- [readonly](#readonly)
|
||||||
- [no_recovery](#no_recovery)
|
- [no_recovery](#no_recovery)
|
||||||
- [no_rebalance](#no_rebalance)
|
- [no_rebalance](#no_rebalance)
|
||||||
- [print_stats_interval](#print_stats_interval)
|
- [print_stats_interval](#print_stats_interval)
|
||||||
- [slow_log_interval](#slow_log_interval)
|
- [slow_log_interval](#slow_log_interval)
|
||||||
|
- [inode_vanish_time](#inode_vanish_time)
|
||||||
- [max_write_iodepth](#max_write_iodepth)
|
- [max_write_iodepth](#max_write_iodepth)
|
||||||
- [min_flusher_count](#min_flusher_count)
|
- [min_flusher_count](#min_flusher_count)
|
||||||
- [max_flusher_count](#max_flusher_count)
|
- [max_flusher_count](#max_flusher_count)
|
||||||
@@ -114,6 +116,16 @@ Maximum recovery operations per one primary OSD at any given moment of time.
|
|||||||
Currently it's the only parameter available to tune the speed or recovery
|
Currently it's the only parameter available to tune the speed or recovery
|
||||||
and rebalancing, but it's planned to implement more.
|
and rebalancing, but it's planned to implement more.
|
||||||
|
|
||||||
|
## recovery_pg_switch
|
||||||
|
|
||||||
|
- Type: integer
|
||||||
|
- Default: 128
|
||||||
|
|
||||||
|
Number of recovery operations before switching to recovery of the next PG.
|
||||||
|
The idea is to mix all PGs during recovery for more even space and load
|
||||||
|
distribution but still benefit from recovery queue depth greater than 1.
|
||||||
|
Degraded PGs are anyway scanned first.
|
||||||
|
|
||||||
## recovery_sync_batch
|
## recovery_sync_batch
|
||||||
|
|
||||||
- Type: integer
|
- Type: integer
|
||||||
@@ -163,6 +175,13 @@ Time interval at which OSDs dump slow or stuck operations on stdout, if
|
|||||||
they're any. Also it's the time after which an operation is considered
|
they're any. Also it's the time after which an operation is considered
|
||||||
"slow".
|
"slow".
|
||||||
|
|
||||||
|
## inode_vanish_time
|
||||||
|
|
||||||
|
- Type: seconds
|
||||||
|
- Default: 60
|
||||||
|
|
||||||
|
Number of seconds after which a deleted inode is removed from OSD statistics.
|
||||||
|
|
||||||
## max_write_iodepth
|
## max_write_iodepth
|
||||||
|
|
||||||
- Type: integer
|
- Type: integer
|
||||||
|
@@ -18,12 +18,14 @@
|
|||||||
- [autosync_interval](#autosync_interval)
|
- [autosync_interval](#autosync_interval)
|
||||||
- [autosync_writes](#autosync_writes)
|
- [autosync_writes](#autosync_writes)
|
||||||
- [recovery_queue_depth](#recovery_queue_depth)
|
- [recovery_queue_depth](#recovery_queue_depth)
|
||||||
|
- [recovery_pg_switch](#recovery_pg_switch)
|
||||||
- [recovery_sync_batch](#recovery_sync_batch)
|
- [recovery_sync_batch](#recovery_sync_batch)
|
||||||
- [readonly](#readonly)
|
- [readonly](#readonly)
|
||||||
- [no_recovery](#no_recovery)
|
- [no_recovery](#no_recovery)
|
||||||
- [no_rebalance](#no_rebalance)
|
- [no_rebalance](#no_rebalance)
|
||||||
- [print_stats_interval](#print_stats_interval)
|
- [print_stats_interval](#print_stats_interval)
|
||||||
- [slow_log_interval](#slow_log_interval)
|
- [slow_log_interval](#slow_log_interval)
|
||||||
|
- [inode_vanish_time](#inode_vanish_time)
|
||||||
- [max_write_iodepth](#max_write_iodepth)
|
- [max_write_iodepth](#max_write_iodepth)
|
||||||
- [min_flusher_count](#min_flusher_count)
|
- [min_flusher_count](#min_flusher_count)
|
||||||
- [max_flusher_count](#max_flusher_count)
|
- [max_flusher_count](#max_flusher_count)
|
||||||
@@ -118,6 +120,17 @@ OSD, чтобы успевать очищать журнал - без них OSD
|
|||||||
для ускорения или замедления восстановления и перебалансировки данных, но
|
для ускорения или замедления восстановления и перебалансировки данных, но
|
||||||
в планах реализация других параметров.
|
в планах реализация других параметров.
|
||||||
|
|
||||||
|
## recovery_pg_switch
|
||||||
|
|
||||||
|
- Тип: целое число
|
||||||
|
- Значение по умолчанию: 128
|
||||||
|
|
||||||
|
Число операций восстановления перед переключением на восстановление другой PG.
|
||||||
|
Идея заключается в том, чтобы восстанавливать все PG одновременно для более
|
||||||
|
равномерного распределения места и нагрузки, но при этом всё равно выигрывать
|
||||||
|
от глубины очереди восстановления, большей, чем 1. Деградированные PG в любом
|
||||||
|
случае сканируются первыми.
|
||||||
|
|
||||||
## recovery_sync_batch
|
## recovery_sync_batch
|
||||||
|
|
||||||
- Тип: целое число
|
- Тип: целое число
|
||||||
@@ -169,6 +182,13 @@ OSD.
|
|||||||
медленных или зависших операций, если таковые имеются. Также время, при
|
медленных или зависших операций, если таковые имеются. Также время, при
|
||||||
превышении которого операция считается "медленной".
|
превышении которого операция считается "медленной".
|
||||||
|
|
||||||
|
## inode_vanish_time
|
||||||
|
|
||||||
|
- Тип: секунды
|
||||||
|
- Значение по умолчанию: 60
|
||||||
|
|
||||||
|
Число секунд, через которое удалённые инод удаляется и из статистики OSD.
|
||||||
|
|
||||||
## max_write_iodepth
|
## max_write_iodepth
|
||||||
|
|
||||||
- Тип: целое число
|
- Тип: целое число
|
||||||
|
@@ -33,6 +33,9 @@ Parameters:
|
|||||||
- [pg_count](#pg_count)
|
- [pg_count](#pg_count)
|
||||||
- [failure_domain](#failure_domain)
|
- [failure_domain](#failure_domain)
|
||||||
- [max_osd_combinations](#max_osd_combinations)
|
- [max_osd_combinations](#max_osd_combinations)
|
||||||
|
- [block_size](#block_size)
|
||||||
|
- [bitmap_granularity](#bitmap_granularity)
|
||||||
|
- [immediate_commit](#immediate_commit)
|
||||||
- [pg_stripe_size](#pg_stripe_size)
|
- [pg_stripe_size](#pg_stripe_size)
|
||||||
- [root_node](#root_node)
|
- [root_node](#root_node)
|
||||||
- [osd_tags](#osd_tags)
|
- [osd_tags](#osd_tags)
|
||||||
@@ -79,7 +82,7 @@ Parent node reference is required for intermediate tree nodes.
|
|||||||
Separate OSD settings are set in etc keys `/vitastor/config/osd/<number>`
|
Separate OSD settings are set in etc keys `/vitastor/config/osd/<number>`
|
||||||
in JSON format `{"<key>":<value>}`.
|
in JSON format `{"<key>":<value>}`.
|
||||||
|
|
||||||
As of now, there is only one setting:
|
As of now, two settings are supported:
|
||||||
|
|
||||||
## reweight
|
## reweight
|
||||||
|
|
||||||
@@ -93,6 +96,15 @@ This means an OSD configured with reweight lower than 1 receives less PGs than
|
|||||||
it normally would. An OSD with reweight = 0 won't store any data. You can set
|
it normally would. An OSD with reweight = 0 won't store any data. You can set
|
||||||
reweight to 0 to trigger rebalance and remove all data from an OSD.
|
reweight to 0 to trigger rebalance and remove all data from an OSD.
|
||||||
|
|
||||||
|
## tags
|
||||||
|
|
||||||
|
- Type: string or array of strings
|
||||||
|
|
||||||
|
Sets tag or multiple tags for this OSD. Tags can be used to group OSDs into
|
||||||
|
subsets and then use a specific subset for pool instead of all OSDs.
|
||||||
|
For example you can mark SSD OSDs with tag "ssd" and HDD OSDs with "hdd" and
|
||||||
|
such tags will work as device classes.
|
||||||
|
|
||||||
# Pool parameters
|
# Pool parameters
|
||||||
|
|
||||||
## name
|
## name
|
||||||
@@ -106,9 +118,12 @@ Pool name.
|
|||||||
|
|
||||||
- Type: string
|
- Type: string
|
||||||
- Required
|
- Required
|
||||||
- One of: "replicated", "xor" or "jerasure"
|
- One of: "replicated", "xor", "ec" or "jerasure"
|
||||||
|
|
||||||
Redundancy scheme used for data in this pool.
|
Redundancy scheme used for data in this pool. "jerasure" is an alias for "ec",
|
||||||
|
both use Reed-Solomon-Vandermonde codes based on ISA-L or jerasure libraries.
|
||||||
|
Fast ISA-L based implementation is used automatically when it's available,
|
||||||
|
slower jerasure version is used otherwise.
|
||||||
|
|
||||||
## pg_size
|
## pg_size
|
||||||
|
|
||||||
@@ -183,6 +198,43 @@ number of combinations to generate when optimising PG placement.
|
|||||||
|
|
||||||
This parameter usually doesn't require to be changed.
|
This parameter usually doesn't require to be changed.
|
||||||
|
|
||||||
|
## block_size
|
||||||
|
|
||||||
|
- Type: integer
|
||||||
|
- Default: 131072
|
||||||
|
|
||||||
|
Block size for this pool. The value from /vitastor/config/global is used when
|
||||||
|
unspecified. If your cluster has OSDs with different block sizes then pool must
|
||||||
|
be restricted by [osd_tags](#osd_tags) to only include OSDs with matching block
|
||||||
|
size.
|
||||||
|
|
||||||
|
Read more about this parameter in [Cluster-Wide Disk Layout Parameters](layout-cluster.en.md#block_size).
|
||||||
|
|
||||||
|
## bitmap_granularity
|
||||||
|
|
||||||
|
- Type: integer
|
||||||
|
- Default: 4096
|
||||||
|
|
||||||
|
"Sector" size of virtual disks in this pool. The value from
|
||||||
|
/vitastor/config/global is used when unspecified. Similar to block_size, the
|
||||||
|
pool must be restricted by [osd_tags](#osd_tags) to only include OSDs with
|
||||||
|
matching bitmap_granularity.
|
||||||
|
|
||||||
|
Read more about this parameter in [Cluster-Wide Disk Layout Parameters](layout-cluster.en.md#bitmap_granularity).
|
||||||
|
|
||||||
|
## immediate_commit
|
||||||
|
|
||||||
|
- Type: string, one of "all", "small" and "none"
|
||||||
|
- Default: none
|
||||||
|
|
||||||
|
Immediate commit setting for this pool. The value from /vitastor/config/global
|
||||||
|
is used when unspecified. Similar to block_size, the pool must be restricted by
|
||||||
|
[osd_tags](#osd_tags) to only include OSDs with compatible immediate_commit.
|
||||||
|
Compatible means that a pool with non-immediate commit will work with OSDs with
|
||||||
|
immediate commit enabled, but not vice versa.
|
||||||
|
|
||||||
|
Read more about this parameter in [Cluster-Wide Disk Layout Parameters](layout-cluster.en.md#immediate_commit).
|
||||||
|
|
||||||
## pg_stripe_size
|
## pg_stripe_size
|
||||||
|
|
||||||
- Type: integer
|
- Type: integer
|
||||||
@@ -243,7 +295,7 @@ of the OSDs containing a data chunk for a PG.
|
|||||||
{
|
{
|
||||||
"2": {
|
"2": {
|
||||||
"name":"ecpool",
|
"name":"ecpool",
|
||||||
"scheme":"jerasure",
|
"scheme":"ec",
|
||||||
"pg_size":3,
|
"pg_size":3,
|
||||||
"parity_chunks":1,
|
"parity_chunks":1,
|
||||||
"pg_minsize":2,
|
"pg_minsize":2,
|
||||||
|
@@ -32,6 +32,9 @@
|
|||||||
- [pg_count](#pg_count)
|
- [pg_count](#pg_count)
|
||||||
- [failure_domain](#failure_domain)
|
- [failure_domain](#failure_domain)
|
||||||
- [max_osd_combinations](#max_osd_combinations)
|
- [max_osd_combinations](#max_osd_combinations)
|
||||||
|
- [block_size](#block_size)
|
||||||
|
- [bitmap_granularity](#bitmap_granularity)
|
||||||
|
- [immediate_commit](#immediate_commit)
|
||||||
- [pg_stripe_size](#pg_stripe_size)
|
- [pg_stripe_size](#pg_stripe_size)
|
||||||
- [root_node](#root_node)
|
- [root_node](#root_node)
|
||||||
- [osd_tags](#osd_tags)
|
- [osd_tags](#osd_tags)
|
||||||
@@ -78,7 +81,10 @@
|
|||||||
Настройки отдельных OSD задаются в ключах etcd `/vitastor/config/osd/<number>`
|
Настройки отдельных OSD задаются в ключах etcd `/vitastor/config/osd/<number>`
|
||||||
в JSON-формате `{"<key>":<value>}`.
|
в JSON-формате `{"<key>":<value>}`.
|
||||||
|
|
||||||
На данный момент поддерживается одна настройка:
|
На данный момент поддерживаются две настройки:
|
||||||
|
|
||||||
|
- [reweight](#reweight)
|
||||||
|
- [tags](#tags)
|
||||||
|
|
||||||
## reweight
|
## reweight
|
||||||
|
|
||||||
@@ -93,6 +99,15 @@
|
|||||||
хранении данных вообще. Вы можете установить reweight в 0, чтобы убрать
|
хранении данных вообще. Вы можете установить reweight в 0, чтобы убрать
|
||||||
все данные с OSD.
|
все данные с OSD.
|
||||||
|
|
||||||
|
## tags
|
||||||
|
|
||||||
|
- Тип: строка или массив строк
|
||||||
|
|
||||||
|
Задаёт тег или набор тегов для данного OSD. Теги можно использовать, чтобы
|
||||||
|
делить OSD на множества и потом размещать пул только на части OSD, а не на
|
||||||
|
всех. Можно, например, пометить SSD OSD тегом "ssd", а HDD тегом "hdd", в
|
||||||
|
этом смысле теги работают аналогично классам устройств.
|
||||||
|
|
||||||
# Параметры
|
# Параметры
|
||||||
|
|
||||||
## name
|
## name
|
||||||
@@ -106,9 +121,13 @@
|
|||||||
|
|
||||||
- Тип: строка
|
- Тип: строка
|
||||||
- Обязательный
|
- Обязательный
|
||||||
- Возможные значения: "replicated", "xor" или "jerasure"
|
- Возможные значения: "replicated", "xor", "ec" или "jerasure"
|
||||||
|
|
||||||
Схема избыточности, используемая в данном пуле.
|
Схема избыточности, используемая в данном пуле. "jerasure" - синоним для "ec",
|
||||||
|
в обеих схемах используются коды Рида-Соломона-Вандермонда, реализованные на
|
||||||
|
основе библиотек ISA-L или jerasure. Быстрая реализация на основе ISA-L
|
||||||
|
используется автоматически, когда доступна, в противном случае используется
|
||||||
|
более медленная jerasure-версия.
|
||||||
|
|
||||||
## pg_size
|
## pg_size
|
||||||
|
|
||||||
@@ -181,13 +200,51 @@ PG в Vitastor эферемерны, то есть вы можете менят
|
|||||||
|
|
||||||
Обычно данный параметр не требует изменений.
|
Обычно данный параметр не требует изменений.
|
||||||
|
|
||||||
|
## block_size
|
||||||
|
|
||||||
|
- Тип: целое число
|
||||||
|
- По умолчанию: 131072
|
||||||
|
|
||||||
|
Размер блока для данного пула. Если не задан, используется значение из
|
||||||
|
/vitastor/config/global. Если в вашем кластере есть OSD с разными размерами
|
||||||
|
блока, пул должен быть ограничен только OSD, блок которых равен блоку пула,
|
||||||
|
с помощью [osd_tags](#osd_tags).
|
||||||
|
|
||||||
|
О самом параметре читайте в разделе [Дисковые параметры уровня кластера](layout-cluster.ru.md#block_size).
|
||||||
|
|
||||||
|
## bitmap_granularity
|
||||||
|
|
||||||
|
- Тип: целое число
|
||||||
|
- По умолчанию: 4096
|
||||||
|
|
||||||
|
Размер "сектора" виртуальных дисков в данном пуле. Если не задан, используется
|
||||||
|
значение из /vitastor/config/global. Аналогично block_size, пул должен быть
|
||||||
|
ограничен OSD со значением bitmap_granularity, равным значению пула, с помощью
|
||||||
|
[osd_tags](#osd_tags).
|
||||||
|
|
||||||
|
О самом параметре читайте в разделе [Дисковые параметры уровня кластера](layout-cluster.ru.md#bitmap_granularity).
|
||||||
|
|
||||||
|
## immediate_commit
|
||||||
|
|
||||||
|
- Тип: строка "all", "small" или "none"
|
||||||
|
- По умолчанию: none
|
||||||
|
|
||||||
|
Настройка мгновенного коммита для данного пула. Если не задана, используется
|
||||||
|
значение из /vitastor/config/global. Аналогично block_size, пул должен быть
|
||||||
|
ограничен OSD со значением bitmap_granularity, совместимым со значением пула, с
|
||||||
|
помощью [osd_tags](#osd_tags). Совместимость означает, что пул с отключенным
|
||||||
|
мгновенным коммитом может работать на OSD с включённым мгновенным коммитом, но
|
||||||
|
не наоборот.
|
||||||
|
|
||||||
|
О самом параметре читайте в разделе [Дисковые параметры уровня кластера](layout-cluster.ru.md#immediate_commit).
|
||||||
|
|
||||||
## pg_stripe_size
|
## pg_stripe_size
|
||||||
|
|
||||||
- Тип: целое число
|
- Тип: целое число
|
||||||
- По умолчанию: 0
|
- По умолчанию: 0
|
||||||
|
|
||||||
Данный параметр задаёт размер полосы "нарезки" образов на PG. Размер полосы не может
|
Данный параметр задаёт размер полосы "нарезки" образов на PG. Размер полосы не может
|
||||||
быть меньше, чем [block_size](layout-cluster.ru.md#block_size), умноженный на
|
быть меньше, чем [block_size](#block_size), умноженный на
|
||||||
(pg_size - parity_chunks) для EC-пулов или 1 для реплицированных пулов. То же
|
(pg_size - parity_chunks) для EC-пулов или 1 для реплицированных пулов. То же
|
||||||
значение используется по умолчанию.
|
значение используется по умолчанию.
|
||||||
|
|
||||||
@@ -242,7 +299,7 @@ PG в Vitastor эферемерны, то есть вы можете менят
|
|||||||
{
|
{
|
||||||
"2": {
|
"2": {
|
||||||
"name":"ecpool",
|
"name":"ecpool",
|
||||||
"scheme":"jerasure",
|
"scheme":"ec",
|
||||||
"pg_size":3,
|
"pg_size":3,
|
||||||
"parity_chunks":1,
|
"parity_chunks":1,
|
||||||
"pg_minsize":2,
|
"pg_minsize":2,
|
||||||
|
@@ -2,3 +2,13 @@
|
|||||||
|
|
||||||
These parameters apply to clients and OSDs, are fixed at the moment of OSD drive
|
These parameters apply to clients and OSDs, are fixed at the moment of OSD drive
|
||||||
initialization and can't be changed after it without losing data.
|
initialization and can't be changed after it without losing data.
|
||||||
|
|
||||||
|
OSDs with different values of these parameters (for example, SSD and SSD+HDD
|
||||||
|
OSDs) can coexist in one Vitastor cluster within different pools. Each pool can
|
||||||
|
only include OSDs with identical settings of these parameters.
|
||||||
|
|
||||||
|
These parameters, when set to a non-default value, must also be specified in
|
||||||
|
etcd for clients to be aware of their values, either in /vitastor/config/global
|
||||||
|
or in pool configuration. Pool configuration overrides the global setting.
|
||||||
|
If the value for a pool in etcd doesn't match on-disk OSD configuration, the
|
||||||
|
OSD will refuse to start PGs of that pool.
|
||||||
|
@@ -2,3 +2,13 @@
|
|||||||
|
|
||||||
Данные параметры используются клиентами и OSD, задаются в момент инициализации
|
Данные параметры используются клиентами и OSD, задаются в момент инициализации
|
||||||
диска OSD и не могут быть изменены после этого без потери данных.
|
диска OSD и не могут быть изменены после этого без потери данных.
|
||||||
|
|
||||||
|
OSD с разными значениями данных параметров (например, SSD и гибридные SSD+HDD
|
||||||
|
OSD) могут сосуществовать в одном кластере Vitastor в разных пулах. Один пул
|
||||||
|
может включать только OSD с одинаковыми настройками этих параметров.
|
||||||
|
|
||||||
|
Данные параметры, отличаясь от значения по умолчанию, должны также быть заданы
|
||||||
|
в etcd, чтобы клиенты могли узнать их значение, либо в глобальной конфигурации
|
||||||
|
/vitastor/config/global, либо в настройках пулов. Настройки пула переопределяют
|
||||||
|
глобальное значение. Если значение в настройках пула не будет соответствовать
|
||||||
|
конфигурации OSD, OSD откажется запускать PG данного пула.
|
||||||
|
@@ -2,46 +2,28 @@
|
|||||||
type: int
|
type: int
|
||||||
default: 131072
|
default: 131072
|
||||||
info: |
|
info: |
|
||||||
Size of objects (data blocks) into which all physical and virtual drives are
|
Size of objects (data blocks) into which all physical and virtual drives
|
||||||
subdivided in Vitastor. One of current main settings in Vitastor, affects
|
(within a pool) are subdivided in Vitastor. One of current main settings
|
||||||
memory usage, write amplification and I/O load distribution effectiveness.
|
in Vitastor, affects memory usage, write amplification and I/O load
|
||||||
|
distribution effectiveness.
|
||||||
|
|
||||||
Recommended default block size is 128 KB for SSD and 4 MB for HDD. In fact,
|
Recommended default block size is 128 KB for SSD and 4 MB for HDD. In fact,
|
||||||
it's possible to use 4 MB for SSD too - it will lower memory usage, but
|
it's possible to use 4 MB for SSD too - it will lower memory usage, but
|
||||||
may increase average WA and reduce linear performance.
|
may increase average WA and reduce linear performance.
|
||||||
|
|
||||||
OSDs with different block sizes (for example, SSD and SSD+HDD OSDs) can
|
|
||||||
currently coexist in one etcd instance only within separate Vitastor
|
|
||||||
clusters with different etcd_prefix'es.
|
|
||||||
|
|
||||||
Also block size can't be changed after OSD initialization without losing
|
|
||||||
data.
|
|
||||||
|
|
||||||
You must always specify block_size in etcd in /vitastor/config/global if
|
|
||||||
you change it so all clients can know about it.
|
|
||||||
|
|
||||||
OSD memory usage is roughly (SIZE / BLOCK * 68 bytes) which is roughly
|
OSD memory usage is roughly (SIZE / BLOCK * 68 bytes) which is roughly
|
||||||
544 MB per 1 TB of used disk space with the default 128 KB block size.
|
544 MB per 1 TB of used disk space with the default 128 KB block size.
|
||||||
info_ru: |
|
info_ru: |
|
||||||
Размер объектов (блоков данных), на которые делятся физические и виртуальные
|
Размер объектов (блоков данных), на которые делятся физические и виртуальные
|
||||||
диски в Vitastor. Одна из ключевых на данный момент настроек, влияет на
|
диски в Vitastor (в рамках каждого пула). Одна из ключевых на данный момент
|
||||||
потребление памяти, объём избыточной записи (write amplification) и
|
настроек, влияет на потребление памяти, объём избыточной записи (write
|
||||||
эффективность распределения нагрузки по OSD.
|
amplification) и эффективность распределения нагрузки по OSD.
|
||||||
|
|
||||||
Рекомендуемые по умолчанию размеры блока - 128 килобайт для SSD и 4
|
Рекомендуемые по умолчанию размеры блока - 128 килобайт для SSD и 4
|
||||||
мегабайта для HDD. В принципе, для SSD можно тоже использовать 4 мегабайта,
|
мегабайта для HDD. В принципе, для SSD можно тоже использовать 4 мегабайта,
|
||||||
это понизит использование памяти, но ухудшит распределение нагрузки и в
|
это понизит использование памяти, но ухудшит распределение нагрузки и в
|
||||||
среднем увеличит WA.
|
среднем увеличит WA.
|
||||||
|
|
||||||
OSD с разными размерами блока (например, SSD и SSD+HDD OSD) на данный
|
|
||||||
момент могут сосуществовать в рамках одного etcd только в виде двух независимых
|
|
||||||
кластеров Vitastor с разными etcd_prefix.
|
|
||||||
|
|
||||||
Также размер блока нельзя менять после инициализации OSD без потери данных.
|
|
||||||
|
|
||||||
Если вы меняете размер блока, обязательно прописывайте его в etcd в
|
|
||||||
/vitastor/config/global, дабы все клиенты его знали.
|
|
||||||
|
|
||||||
Потребление памяти OSD составляет примерно (РАЗМЕР / БЛОК * 68 байт),
|
Потребление памяти OSD составляет примерно (РАЗМЕР / БЛОК * 68 байт),
|
||||||
т.е. примерно 544 МБ памяти на 1 ТБ занятого места на диске при
|
т.е. примерно 544 МБ памяти на 1 ТБ занятого места на диске при
|
||||||
стандартном 128 КБ блоке.
|
стандартном 128 КБ блоке.
|
||||||
@@ -54,25 +36,14 @@
|
|||||||
an allocation bitmap for each object containing 2 bits per each
|
an allocation bitmap for each object containing 2 bits per each
|
||||||
(bitmap_granularity) bytes.
|
(bitmap_granularity) bytes.
|
||||||
|
|
||||||
This parameter can't be changed after OSD initialization without losing
|
Can't be smaller than the OSD data device sector.
|
||||||
data. Also it's fixed for the whole Vitastor cluster i.e. two different
|
|
||||||
values can't be used in a single Vitastor cluster.
|
|
||||||
|
|
||||||
Clients MUST be aware of this parameter value, so put it into etcd key
|
|
||||||
/vitastor/config/global if you change it for any reason.
|
|
||||||
info_ru: |
|
info_ru: |
|
||||||
Требуемое выравнивание записи на виртуальные диски (размер их "сектора").
|
Требуемое выравнивание записи на виртуальные диски (размер их "сектора").
|
||||||
Должен быть кратен disk_alignment. Называется гранулярностью битовой карты
|
Должен быть кратен disk_alignment. Называется гранулярностью битовой карты
|
||||||
потому, что Vitastor хранит битовую карту для каждого объекта, содержащую
|
потому, что Vitastor хранит битовую карту для каждого объекта, содержащую
|
||||||
по 2 бита на каждые (bitmap_granularity) байт.
|
по 2 бита на каждые (bitmap_granularity) байт.
|
||||||
|
|
||||||
Данный параметр нельзя менять после инициализации OSD без потери данных.
|
Не может быть меньше размера сектора дисков данных OSD.
|
||||||
Также он фиксирован для всего кластера Vitastor, т.е. разные значения
|
|
||||||
не могут сосуществовать в одном кластере.
|
|
||||||
|
|
||||||
Клиенты ДОЛЖНЫ знать правильное значение этого параметра, так что если вы
|
|
||||||
его меняете, обязательно прописывайте изменённое значение в etcd в ключ
|
|
||||||
/vitastor/config/global.
|
|
||||||
- name: immediate_commit
|
- name: immediate_commit
|
||||||
type: string
|
type: string
|
||||||
default: false
|
default: false
|
||||||
@@ -114,10 +85,9 @@
|
|||||||
SSD cache or "media-cache" - for example, a lot of Seagate EXOS drives have
|
SSD cache or "media-cache" - for example, a lot of Seagate EXOS drives have
|
||||||
it (they have internal SSD cache even though it's not stated in datasheets).
|
it (they have internal SSD cache even though it's not stated in datasheets).
|
||||||
|
|
||||||
This parameter must be set both in etcd in /vitastor/config/global and in
|
Setting this parameter to "all" or "small" in OSD parameters requires enabling
|
||||||
OSD command line or configuration. Setting it to "all" or "small" requires
|
disable_journal_fsync and disable_meta_fsync, setting it to "all" also requires
|
||||||
enabling disable_journal_fsync and disable_meta_fsync, setting it to "all"
|
enabling disable_data_fsync.
|
||||||
also requires enabling disable_data_fsync.
|
|
||||||
|
|
||||||
TLDR: For optimal performance, set immediate_commit to "all" if you only use
|
TLDR: For optimal performance, set immediate_commit to "all" if you only use
|
||||||
SSDs with supercapacitor-based power loss protection (nonvolatile
|
SSDs with supercapacitor-based power loss protection (nonvolatile
|
||||||
@@ -168,8 +138,7 @@
|
|||||||
многих дисках Seagate EXOS (у них есть внутренний SSD-кэш, хотя это и не
|
многих дисках Seagate EXOS (у них есть внутренний SSD-кэш, хотя это и не
|
||||||
указано в спецификациях).
|
указано в спецификациях).
|
||||||
|
|
||||||
Данный параметр нужно указывать и в etcd в /vitastor/config/global, и в
|
Указание "all" или "small" в настройках / командной строке OSD требует
|
||||||
командной строке или конфигурации OSD. Значения "all" и "small" требуют
|
|
||||||
включения disable_journal_fsync и disable_meta_fsync, значение "all" также
|
включения disable_journal_fsync и disable_meta_fsync, значение "all" также
|
||||||
требует включения disable_data_fsync.
|
требует включения disable_data_fsync.
|
||||||
|
|
||||||
@@ -179,22 +148,3 @@
|
|||||||
такие SSD для всех журналов, но не для данных - можете установить параметр
|
такие SSD для всех журналов, но не для данных - можете установить параметр
|
||||||
в "small". Если и какие-то из дисков журналов имеют волатильный кэш записи -
|
в "small". Если и какие-то из дисков журналов имеют волатильный кэш записи -
|
||||||
оставьте параметр пустым.
|
оставьте параметр пустым.
|
||||||
- name: client_dirty_limit
|
|
||||||
type: int
|
|
||||||
default: 33554432
|
|
||||||
info: |
|
|
||||||
Without immediate_commit=all this parameter sets the limit of "dirty"
|
|
||||||
(not committed by fsync) data allowed by the client before forcing an
|
|
||||||
additional fsync and committing the data. Also note that the client always
|
|
||||||
holds a copy of uncommitted data in memory so this setting also affects
|
|
||||||
RAM usage of clients.
|
|
||||||
|
|
||||||
This parameter doesn't affect OSDs themselves.
|
|
||||||
info_ru: |
|
|
||||||
При работе без immediate_commit=all - это лимит объёма "грязных" (не
|
|
||||||
зафиксированных fsync-ом) данных, при достижении которого клиент будет
|
|
||||||
принудительно вызывать fsync и фиксировать данные. Также стоит иметь в виду,
|
|
||||||
что в этом случае до момента fsync клиент хранит копию незафиксированных
|
|
||||||
данных в памяти, то есть, настройка влияет на потребление памяти клиентами.
|
|
||||||
|
|
||||||
Параметр не влияет на сами OSD.
|
|
||||||
|
@@ -53,6 +53,12 @@
|
|||||||
to work. For example, Mellanox ConnectX-3 and older adapters don't have
|
to work. For example, Mellanox ConnectX-3 and older adapters don't have
|
||||||
Implicit ODP, so they're unsupported by Vitastor. Run `ibv_devinfo -v` as
|
Implicit ODP, so they're unsupported by Vitastor. Run `ibv_devinfo -v` as
|
||||||
root to list available RDMA devices and their features.
|
root to list available RDMA devices and their features.
|
||||||
|
|
||||||
|
Remember that you also have to configure your network switches if you use
|
||||||
|
RoCE/RoCEv2, otherwise you may experience unstable performance. Refer to
|
||||||
|
the manual of your network vendor for details about setting up the switch
|
||||||
|
for RoCEv2 correctly. Usually it means setting up Lossless Ethernet with
|
||||||
|
PFC (Priority Flow Control) and ECN (Explicit Congestion Notification).
|
||||||
info_ru: |
|
info_ru: |
|
||||||
Название RDMA-устройства для связи с Vitastor OSD (например, "rocep5s0f0").
|
Название RDMA-устройства для связи с Vitastor OSD (например, "rocep5s0f0").
|
||||||
Имейте в виду, что поддержка RDMA в Vitastor требует функций устройства
|
Имейте в виду, что поддержка RDMA в Vitastor требует функций устройства
|
||||||
@@ -61,6 +67,13 @@
|
|||||||
потому не поддерживаются в Vitastor. Запустите `ibv_devinfo -v` от имени
|
потому не поддерживаются в Vitastor. Запустите `ibv_devinfo -v` от имени
|
||||||
суперпользователя, чтобы посмотреть список доступных RDMA-устройств, их
|
суперпользователя, чтобы посмотреть список доступных RDMA-устройств, их
|
||||||
параметры и возможности.
|
параметры и возможности.
|
||||||
|
|
||||||
|
Обратите внимание, что если вы используете RoCE/RoCEv2, вам также необходимо
|
||||||
|
правильно настроить для него коммутаторы, иначе вы можете столкнуться с
|
||||||
|
нестабильной производительностью. Подробную информацию о настройке
|
||||||
|
коммутатора для RoCEv2 ищите в документации производителя. Обычно это
|
||||||
|
подразумевает настройку сети без потерь на основе PFC (Priority Flow
|
||||||
|
Control) и ECN (Explicit Congestion Notification).
|
||||||
- name: rdma_port_num
|
- name: rdma_port_num
|
||||||
type: int
|
type: int
|
||||||
default: 1
|
default: 1
|
||||||
@@ -114,26 +127,39 @@
|
|||||||
так что менять этот параметр обычно не нужно.
|
так что менять этот параметр обычно не нужно.
|
||||||
- name: rdma_max_msg
|
- name: rdma_max_msg
|
||||||
type: int
|
type: int
|
||||||
default: 1048576
|
default: 132096
|
||||||
info: Maximum size of a single RDMA send or receive operation in bytes.
|
info: Maximum size of a single RDMA send or receive operation in bytes.
|
||||||
info_ru: Максимальный размер одной RDMA-операции отправки или приёма.
|
info_ru: Максимальный размер одной RDMA-операции отправки или приёма.
|
||||||
- name: rdma_max_recv
|
- name: rdma_max_recv
|
||||||
|
type: int
|
||||||
|
default: 16
|
||||||
|
info: |
|
||||||
|
Maximum number of RDMA receive buffers per connection (RDMA requires
|
||||||
|
preallocated buffers to receive data). Each buffer is `rdma_max_msg` bytes
|
||||||
|
in size. So this setting directly affects memory usage: a single Vitastor
|
||||||
|
RDMA client uses `rdma_max_recv * rdma_max_msg * OSD_COUNT` bytes of memory.
|
||||||
|
Default is roughly 2 MB * number of OSDs.
|
||||||
|
info_ru: |
|
||||||
|
Максимальное число буферов для RDMA-приёма данных на одно соединение
|
||||||
|
(RDMA требует заранее выделенных буферов для приёма данных). Каждый буфер
|
||||||
|
имеет размер `rdma_max_msg` байт. Таким образом, настройка прямо влияет на
|
||||||
|
потребление памяти - один Vitastor-клиент с RDMA использует
|
||||||
|
`rdma_max_recv * rdma_max_msg * ЧИСЛО_OSD` байт памяти, по умолчанию -
|
||||||
|
примерно 2 МБ * число OSD.
|
||||||
|
- name: rdma_max_send
|
||||||
type: int
|
type: int
|
||||||
default: 8
|
default: 8
|
||||||
info: |
|
info: |
|
||||||
Maximum number of parallel RDMA receive operations. Note that this number
|
Maximum number of outstanding RDMA send operations per connection. Should be
|
||||||
of receive buffers `rdma_max_msg` in size are allocated for each client,
|
less than `rdma_max_recv` so the receiving side doesn't run out of buffers.
|
||||||
so this setting actually affects memory usage. This is because RDMA receive
|
Doesn't affect memory usage - additional memory isn't allocated for send
|
||||||
operations are (sadly) still not zero-copy in Vitastor. It may be fixed in
|
operations.
|
||||||
later versions.
|
|
||||||
info_ru: |
|
info_ru: |
|
||||||
Максимальное число параллельных RDMA-операций получения данных. Следует
|
Максимальное число RDMA-операций отправки, отправляемых в очередь одного
|
||||||
иметь в виду, что данное число буферов размером `rdma_max_msg` выделяется
|
соединения. Желательно, чтобы оно было меньше `rdma_max_recv`, чтобы
|
||||||
для каждого подключённого клиентского соединения, так что данная настройка
|
у принимающей стороны в процессе работы не заканчивались буферы на приём.
|
||||||
влияет на потребление памяти. Это так потому, что RDMA-приём данных в
|
Не влияет на потребление памяти - дополнительная память на операции отправки
|
||||||
Vitastor, увы, всё равно не является zero-copy, т.е. всё равно 1 раз
|
не выделяется.
|
||||||
копирует данные в памяти. Данная особенность, возможно, будет исправлена в
|
|
||||||
более новых версиях Vitastor.
|
|
||||||
- name: peer_connect_interval
|
- name: peer_connect_interval
|
||||||
type: sec
|
type: sec
|
||||||
min: 1
|
min: 1
|
||||||
@@ -223,3 +249,22 @@
|
|||||||
detect disconnections quickly.
|
detect disconnections quickly.
|
||||||
info_ru: |
|
info_ru: |
|
||||||
Интервал проверки живости вебсокет-подключений к etcd.
|
Интервал проверки живости вебсокет-подключений к etcd.
|
||||||
|
- name: client_dirty_limit
|
||||||
|
type: int
|
||||||
|
default: 33554432
|
||||||
|
info: |
|
||||||
|
Without immediate_commit=all this parameter sets the limit of "dirty"
|
||||||
|
(not committed by fsync) data allowed by the client before forcing an
|
||||||
|
additional fsync and committing the data. Also note that the client always
|
||||||
|
holds a copy of uncommitted data in memory so this setting also affects
|
||||||
|
RAM usage of clients.
|
||||||
|
|
||||||
|
This parameter doesn't affect OSDs themselves.
|
||||||
|
info_ru: |
|
||||||
|
При работе без immediate_commit=all - это лимит объёма "грязных" (не
|
||||||
|
зафиксированных fsync-ом) данных, при достижении которого клиент будет
|
||||||
|
принудительно вызывать fsync и фиксировать данные. Также стоит иметь в виду,
|
||||||
|
что в этом случае до момента fsync клиент хранит копию незафиксированных
|
||||||
|
данных в памяти, то есть, настройка влияет на потребление памяти клиентами.
|
||||||
|
|
||||||
|
Параметр не влияет на сами OSD.
|
||||||
|
@@ -102,6 +102,20 @@
|
|||||||
момент времени. На данный момент единственный параметр, который можно менять
|
момент времени. На данный момент единственный параметр, который можно менять
|
||||||
для ускорения или замедления восстановления и перебалансировки данных, но
|
для ускорения или замедления восстановления и перебалансировки данных, но
|
||||||
в планах реализация других параметров.
|
в планах реализация других параметров.
|
||||||
|
- name: recovery_pg_switch
|
||||||
|
type: int
|
||||||
|
default: 128
|
||||||
|
info: |
|
||||||
|
Number of recovery operations before switching to recovery of the next PG.
|
||||||
|
The idea is to mix all PGs during recovery for more even space and load
|
||||||
|
distribution but still benefit from recovery queue depth greater than 1.
|
||||||
|
Degraded PGs are anyway scanned first.
|
||||||
|
info_ru: |
|
||||||
|
Число операций восстановления перед переключением на восстановление другой PG.
|
||||||
|
Идея заключается в том, чтобы восстанавливать все PG одновременно для более
|
||||||
|
равномерного распределения места и нагрузки, но при этом всё равно выигрывать
|
||||||
|
от глубины очереди восстановления, большей, чем 1. Деградированные PG в любом
|
||||||
|
случае сканируются первыми.
|
||||||
- name: recovery_sync_batch
|
- name: recovery_sync_batch
|
||||||
type: int
|
type: int
|
||||||
default: 16
|
default: 16
|
||||||
@@ -158,6 +172,13 @@
|
|||||||
Временной интервал, с которым OSD выводят в стандартный вывод список
|
Временной интервал, с которым OSD выводят в стандартный вывод список
|
||||||
медленных или зависших операций, если таковые имеются. Также время, при
|
медленных или зависших операций, если таковые имеются. Также время, при
|
||||||
превышении которого операция считается "медленной".
|
превышении которого операция считается "медленной".
|
||||||
|
- name: inode_vanish_time
|
||||||
|
type: sec
|
||||||
|
default: 60
|
||||||
|
info: |
|
||||||
|
Number of seconds after which a deleted inode is removed from OSD statistics.
|
||||||
|
info_ru: |
|
||||||
|
Число секунд, через которое удалённые инод удаляется и из статистики OSD.
|
||||||
- name: max_write_iodepth
|
- name: max_write_iodepth
|
||||||
type: int
|
type: int
|
||||||
default: 128
|
default: 128
|
||||||
|
@@ -9,7 +9,7 @@
|
|||||||
## Debian
|
## Debian
|
||||||
|
|
||||||
- Trust Vitastor package signing key:
|
- Trust Vitastor package signing key:
|
||||||
`wget -q -O - https://vitastor.io/debian/pubkey | sudo apt-key add -`
|
`wget https://vitastor.io/debian/pubkey.gpg -O /etc/apt/trusted.gpg.d/vitastor.gpg`
|
||||||
- Add Vitastor package repository to your /etc/apt/sources.list:
|
- Add Vitastor package repository to your /etc/apt/sources.list:
|
||||||
- Debian 11 (Bullseye/Sid): `deb https://vitastor.io/debian bullseye main`
|
- Debian 11 (Bullseye/Sid): `deb https://vitastor.io/debian bullseye main`
|
||||||
- Debian 10 (Buster): `deb https://vitastor.io/debian buster main`
|
- Debian 10 (Buster): `deb https://vitastor.io/debian buster main`
|
||||||
@@ -20,15 +20,18 @@
|
|||||||
## CentOS
|
## CentOS
|
||||||
|
|
||||||
- Add Vitastor package repository:
|
- Add Vitastor package repository:
|
||||||
- CentOS 7: `yum install https://vitastor.io/rpms/centos/7/vitastor-release-1.0-1.el7.noarch.rpm`
|
- CentOS 7: `yum install https://vitastor.io/rpms/centos/7/vitastor-release.rpm`
|
||||||
- CentOS 8: `dnf install https://vitastor.io/rpms/centos/8/vitastor-release-1.0-1.el8.noarch.rpm`
|
- CentOS 8: `dnf install https://vitastor.io/rpms/centos/8/vitastor-release.rpm`
|
||||||
|
- AlmaLinux 9 and other RHEL 9 clones (Rocky, Oracle...): `dnf install https://vitastor.io/rpms/centos/9/vitastor-release.rpm`
|
||||||
- Enable EPEL: `yum/dnf install epel-release`
|
- Enable EPEL: `yum/dnf install epel-release`
|
||||||
- Enable additional CentOS repositories:
|
- Enable additional CentOS repositories:
|
||||||
- CentOS 7: `yum install centos-release-scl`
|
- CentOS 7: `yum install centos-release-scl`
|
||||||
- CentOS 8: `dnf install centos-release-advanced-virtualization`
|
- CentOS 8: `dnf install centos-release-advanced-virtualization`
|
||||||
|
- RHEL 9 clones: not required
|
||||||
- Enable elrepo-kernel:
|
- Enable elrepo-kernel:
|
||||||
- CentOS 7: `yum install https://www.elrepo.org/elrepo-release-7.el7.elrepo.noarch.rpm`
|
- CentOS 7: `yum install https://www.elrepo.org/elrepo-release-7.el7.elrepo.noarch.rpm`
|
||||||
- CentOS 8: `dnf install https://www.elrepo.org/elrepo-release-8.el8.elrepo.noarch.rpm`
|
- CentOS 8: `dnf install https://www.elrepo.org/elrepo-release-8.el8.elrepo.noarch.rpm`
|
||||||
|
- RHEL 9 clones: `dnf install https://www.elrepo.org/elrepo-release-9.el9.elrepo.noarch.rpm`
|
||||||
- Install packages: `yum/dnf install vitastor lpsolve etcd kernel-ml qemu-kvm`
|
- Install packages: `yum/dnf install vitastor lpsolve etcd kernel-ml qemu-kvm`
|
||||||
|
|
||||||
## Installation requirements
|
## Installation requirements
|
||||||
|
@@ -9,7 +9,7 @@
|
|||||||
## Debian
|
## Debian
|
||||||
|
|
||||||
- Добавьте ключ репозитория Vitastor:
|
- Добавьте ключ репозитория Vitastor:
|
||||||
`wget -q -O - https://vitastor.io/debian/pubkey | sudo apt-key add -`
|
`wget https://vitastor.io/debian/pubkey.gpg -O /etc/apt/trusted.gpg.d/vitastor.gpg`
|
||||||
- Добавьте репозиторий Vitastor в /etc/apt/sources.list:
|
- Добавьте репозиторий Vitastor в /etc/apt/sources.list:
|
||||||
- Debian 11 (Bullseye/Sid): `deb https://vitastor.io/debian bullseye main`
|
- Debian 11 (Bullseye/Sid): `deb https://vitastor.io/debian bullseye main`
|
||||||
- Debian 10 (Buster): `deb https://vitastor.io/debian buster main`
|
- Debian 10 (Buster): `deb https://vitastor.io/debian buster main`
|
||||||
@@ -20,15 +20,18 @@
|
|||||||
## CentOS
|
## CentOS
|
||||||
|
|
||||||
- Добавьте в систему репозиторий Vitastor:
|
- Добавьте в систему репозиторий Vitastor:
|
||||||
- CentOS 7: `yum install https://vitastor.io/rpms/centos/7/vitastor-release-1.0-1.el7.noarch.rpm`
|
- CentOS 7: `yum install https://vitastor.io/rpms/centos/7/vitastor-release.rpm`
|
||||||
- CentOS 8: `dnf install https://vitastor.io/rpms/centos/8/vitastor-release-1.0-1.el8.noarch.rpm`
|
- CentOS 8: `dnf install https://vitastor.io/rpms/centos/8/vitastor-release.rpm`
|
||||||
|
- AlmaLinux 9 и другие клоны RHEL 9 (Rocky, Oracle...): `dnf install https://vitastor.io/rpms/centos/9/vitastor-release.rpm`
|
||||||
- Включите EPEL: `yum/dnf install epel-release`
|
- Включите EPEL: `yum/dnf install epel-release`
|
||||||
- Включите дополнительные репозитории CentOS:
|
- Включите дополнительные репозитории CentOS:
|
||||||
- CentOS 7: `yum install centos-release-scl`
|
- CentOS 7: `yum install centos-release-scl`
|
||||||
- CentOS 8: `dnf install centos-release-advanced-virtualization`
|
- CentOS 8: `dnf install centos-release-advanced-virtualization`
|
||||||
|
- Клоны RHEL 9: не нужно
|
||||||
- Включите elrepo-kernel:
|
- Включите elrepo-kernel:
|
||||||
- CentOS 7: `yum install https://www.elrepo.org/elrepo-release-7.el7.elrepo.noarch.rpm`
|
- CentOS 7: `yum install https://www.elrepo.org/elrepo-release-7.el7.elrepo.noarch.rpm`
|
||||||
- CentOS 8: `dnf install https://www.elrepo.org/elrepo-release-8.el8.elrepo.noarch.rpm`
|
- CentOS 8: `dnf install https://www.elrepo.org/elrepo-release-8.el8.elrepo.noarch.rpm`
|
||||||
|
- Клоны RHEL 9: `dnf install https://www.elrepo.org/elrepo-release-9.el9.elrepo.noarch.rpm`
|
||||||
- Установите пакеты: `yum/dnf install vitastor lpsolve etcd kernel-ml qemu-kvm`
|
- Установите пакеты: `yum/dnf install vitastor lpsolve etcd kernel-ml qemu-kvm`
|
||||||
|
|
||||||
## Установочные требования
|
## Установочные требования
|
||||||
|
@@ -6,10 +6,10 @@
|
|||||||
|
|
||||||
# Proxmox VE
|
# Proxmox VE
|
||||||
|
|
||||||
To enable Vitastor support in Proxmox Virtual Environment (6.4 and 7.1 are supported):
|
To enable Vitastor support in Proxmox Virtual Environment (6.4-7.4 are supported):
|
||||||
|
|
||||||
- Add the corresponding Vitastor Debian repository into sources.list on Proxmox hosts
|
- Add the corresponding Vitastor Debian repository into sources.list on Proxmox hosts:
|
||||||
(buster for 6.4, bullseye for 7.1)
|
buster for 6.4, bullseye for 7.4, pve7.1 for 7.1, pve7.2 for 7.2, pve7.3 for 7.3
|
||||||
- Install vitastor-client, pve-qemu-kvm, pve-storage-vitastor (* or see note) packages from Vitastor repository
|
- Install vitastor-client, pve-qemu-kvm, pve-storage-vitastor (* or see note) packages from Vitastor repository
|
||||||
- Define storage in `/etc/pve/storage.cfg` (see below)
|
- Define storage in `/etc/pve/storage.cfg` (see below)
|
||||||
- Block network access from VMs to Vitastor network (to OSDs and etcd),
|
- Block network access from VMs to Vitastor network (to OSDs and etcd),
|
||||||
@@ -35,5 +35,5 @@ vitastor: vitastor
|
|||||||
vitastor_nbd 0
|
vitastor_nbd 0
|
||||||
```
|
```
|
||||||
|
|
||||||
\* Note: you can also manually copy [patches/PVE_VitastorPlugin.pm](patches/PVE_VitastorPlugin.pm) to Proxmox hosts
|
\* Note: you can also manually copy [patches/VitastorPlugin.pm](patches/VitastorPlugin.pm) to Proxmox hosts
|
||||||
as `/usr/share/perl5/PVE/Storage/Custom/VitastorPlugin.pm` instead of installing pve-storage-vitastor.
|
as `/usr/share/perl5/PVE/Storage/Custom/VitastorPlugin.pm` instead of installing pve-storage-vitastor.
|
||||||
|
@@ -6,10 +6,10 @@
|
|||||||
|
|
||||||
# Proxmox
|
# Proxmox
|
||||||
|
|
||||||
Чтобы подключить Vitastor к Proxmox Virtual Environment (поддерживаются версии 6.4 и 7.1):
|
Чтобы подключить Vitastor к Proxmox Virtual Environment (поддерживаются версии 6.4-7.4):
|
||||||
|
|
||||||
- Добавьте соответствующий Debian-репозиторий Vitastor в sources.list на хостах Proxmox
|
- Добавьте соответствующий Debian-репозиторий Vitastor в sources.list на хостах Proxmox:
|
||||||
(buster для 6.4, bullseye для 7.1)
|
buster для 6.4, bullseye для 7.4, pve7.1 для 7.1, pve7.2 для 7.2, pve7.3 для 7.3
|
||||||
- Установите пакеты vitastor-client, pve-qemu-kvm, pve-storage-vitastor (* или см. сноску) из репозитория Vitastor
|
- Установите пакеты vitastor-client, pve-qemu-kvm, pve-storage-vitastor (* или см. сноску) из репозитория Vitastor
|
||||||
- Определите тип хранилища в `/etc/pve/storage.cfg` (см. ниже)
|
- Определите тип хранилища в `/etc/pve/storage.cfg` (см. ниже)
|
||||||
- Обязательно заблокируйте доступ от виртуальных машин к сети Vitastor (OSD и etcd), т.к. Vitastor (пока) не поддерживает аутентификацию
|
- Обязательно заблокируйте доступ от виртуальных машин к сети Vitastor (OSD и etcd), т.к. Vitastor (пока) не поддерживает аутентификацию
|
||||||
@@ -35,5 +35,5 @@ vitastor: vitastor
|
|||||||
```
|
```
|
||||||
|
|
||||||
\* Примечание: вместо установки пакета pve-storage-vitastor вы можете вручную скопировать файл
|
\* Примечание: вместо установки пакета pve-storage-vitastor вы можете вручную скопировать файл
|
||||||
[patches/PVE_VitastorPlugin.pm](patches/PVE_VitastorPlugin.pm) на хосты Proxmox как
|
[patches/VitastorPlugin.pm](patches/VitastorPlugin.pm) на хосты Proxmox как
|
||||||
`/usr/share/perl5/PVE/Storage/Custom/VitastorPlugin.pm`.
|
`/usr/share/perl5/PVE/Storage/Custom/VitastorPlugin.pm`.
|
||||||
|
@@ -15,7 +15,8 @@
|
|||||||
- gcc and g++ 8 or newer, clang 10 or newer, or other compiler with C++11 plus
|
- gcc and g++ 8 or newer, clang 10 or newer, or other compiler with C++11 plus
|
||||||
designated initializers support from C++20
|
designated initializers support from C++20
|
||||||
- CMake
|
- CMake
|
||||||
- liburing, jerasure headers
|
- liburing, jerasure headers and libraries
|
||||||
|
- ISA-L, libibverbs headers and libraries (optional)
|
||||||
- tcmalloc (google-perftools-dev)
|
- tcmalloc (google-perftools-dev)
|
||||||
|
|
||||||
## Basic instructions
|
## Basic instructions
|
||||||
|
@@ -15,7 +15,8 @@
|
|||||||
- gcc и g++ >= 8, либо clang >= 10, либо другой компилятор с поддержкой C++11 плюс
|
- gcc и g++ >= 8, либо clang >= 10, либо другой компилятор с поддержкой C++11 плюс
|
||||||
назначенных инициализаторов (designated initializers) из C++20
|
назначенных инициализаторов (designated initializers) из C++20
|
||||||
- CMake
|
- CMake
|
||||||
- Заголовки liburing, jerasure
|
- Заголовки и библиотеки liburing, jerasure
|
||||||
|
- Опционально - заголовки и библиотеки ISA-L, libibverbs
|
||||||
- tcmalloc (google-perftools-dev)
|
- tcmalloc (google-perftools-dev)
|
||||||
|
|
||||||
## Базовая инструкция
|
## Базовая инструкция
|
||||||
|
@@ -127,7 +127,7 @@
|
|||||||
запросы записи клиенты копируют в памяти и при потере соединения и повторном соединении
|
запросы записи клиенты копируют в памяти и при потере соединения и повторном соединении
|
||||||
с OSD повторяют из памяти. Скопированные в память данные удаляются при успешном fsync,
|
с OSD повторяют из памяти. Скопированные в память данные удаляются при успешном fsync,
|
||||||
а чтобы хранение этих данных не приводило к чрезмерному потреблению памяти, клиенты
|
а чтобы хранение этих данных не приводило к чрезмерному потреблению памяти, клиенты
|
||||||
автоматически выполняют fsync каждые [client_dirty_limit](../config/layout-cluster.ru.md#client_dirty_limit)
|
автоматически выполняют fsync каждые [client_dirty_limit](../config/network.ru.md#client_dirty_limit)
|
||||||
записанных байт.
|
записанных байт.
|
||||||
|
|
||||||
## Схожесть с Ceph
|
## Схожесть с Ceph
|
||||||
|
@@ -33,5 +33,5 @@ Vitastor Network Public License 1.1, основанная на GNU GPL 3.0 с д
|
|||||||
и также на условиях GNU GPL 2.0 или более поздней версии. Так сделано в целях
|
и также на условиях GNU GPL 2.0 или более поздней версии. Так сделано в целях
|
||||||
совместимости с таким ПО, как QEMU и fio.
|
совместимости с таким ПО, как QEMU и fio.
|
||||||
|
|
||||||
Вы можете найти полный текст VNPL 1.1 в файле [VNPL-1.1.txt](../../VNPL-1.1.txt),
|
Вы можете найти полный текст VNPL 1.1 на английском языке в файле [VNPL-1.1.txt](../../VNPL-1.1.txt),
|
||||||
а GPL 2.0 в файле [GPL-2.0.txt](../../GPL-2.0.txt).
|
VNPL 1.1 на русском языке в файле [VNPL-1.1-RU.txt](../../VNPL-1.1-RU.txt), а GPL 2.0 в файле [GPL-2.0.txt](../../GPL-2.0.txt).
|
||||||
|
@@ -15,7 +15,7 @@
|
|||||||
- Basic part: highly-available block storage with symmetric clustering and no SPOF
|
- Basic part: highly-available block storage with symmetric clustering and no SPOF
|
||||||
- [Performance](../performance/comparison1.en.md) ;-D
|
- [Performance](../performance/comparison1.en.md) ;-D
|
||||||
- [Multiple redundancy schemes](../config/pool.en.md#scheme): Replication, XOR n+1, Reed-Solomon erasure codes
|
- [Multiple redundancy schemes](../config/pool.en.md#scheme): Replication, XOR n+1, Reed-Solomon erasure codes
|
||||||
based on jerasure library with any number of data and parity drives in a group
|
based on jerasure and ISA-L libraries with any number of data and parity drives in a group
|
||||||
- Configuration via simple JSON data structures in etcd (parameters, pools and images)
|
- Configuration via simple JSON data structures in etcd (parameters, pools and images)
|
||||||
- Automatic data distribution over OSDs, with support for:
|
- Automatic data distribution over OSDs, with support for:
|
||||||
- Mathematical optimization for better uniformity and less data movement
|
- Mathematical optimization for better uniformity and less data movement
|
||||||
@@ -34,6 +34,7 @@
|
|||||||
|
|
||||||
- [Debian and CentOS packages](../installation/packages.en.md)
|
- [Debian and CentOS packages](../installation/packages.en.md)
|
||||||
- [Image management CLI (vitastor-cli)](../usage/cli.en.md)
|
- [Image management CLI (vitastor-cli)](../usage/cli.en.md)
|
||||||
|
- [Disk management CLI (vitastor-disk)](docs/usage/disk.en.md)
|
||||||
- Generic user-space client library
|
- Generic user-space client library
|
||||||
- [Native QEMU driver](../usage/qemu.en.md)
|
- [Native QEMU driver](../usage/qemu.en.md)
|
||||||
- [Loadable fio engine for benchmarks](../usage/fio.en.md)
|
- [Loadable fio engine for benchmarks](../usage/fio.en.md)
|
||||||
@@ -47,7 +48,6 @@
|
|||||||
|
|
||||||
The following features are planned for the future:
|
The following features are planned for the future:
|
||||||
|
|
||||||
- Better OSD creation and auto-start tools
|
|
||||||
- Other administrative tools
|
- Other administrative tools
|
||||||
- Web GUI
|
- Web GUI
|
||||||
- OpenNebula plugin
|
- OpenNebula plugin
|
||||||
|
@@ -15,7 +15,7 @@
|
|||||||
- Базовая часть - надёжное кластерное блочное хранилище без единой точки отказа
|
- Базовая часть - надёжное кластерное блочное хранилище без единой точки отказа
|
||||||
- [Производительность](../comparison1.ru.md) ;-D
|
- [Производительность](../comparison1.ru.md) ;-D
|
||||||
- [Несколько схем отказоустойчивости](../config/pool.ru.md#scheme): репликация, XOR n+1 (1 диск чётности), коды коррекции ошибок
|
- [Несколько схем отказоустойчивости](../config/pool.ru.md#scheme): репликация, XOR n+1 (1 диск чётности), коды коррекции ошибок
|
||||||
Рида-Соломона на основе библиотеки jerasure с любым числом дисков данных и чётности в группе
|
Рида-Соломона на основе библиотек jerasure и ISA-L с любым числом дисков данных и чётности в группе
|
||||||
- Конфигурация через простые человекочитаемые JSON-структуры в etcd
|
- Конфигурация через простые человекочитаемые JSON-структуры в etcd
|
||||||
- Автоматическое распределение данных по OSD, с поддержкой:
|
- Автоматическое распределение данных по OSD, с поддержкой:
|
||||||
- Математической оптимизации для лучшей равномерности распределения и минимизации перемещений данных
|
- Математической оптимизации для лучшей равномерности распределения и минимизации перемещений данных
|
||||||
@@ -36,6 +36,7 @@
|
|||||||
|
|
||||||
- [Пакеты для Debian и CentOS](../installation/packages.ru.md)
|
- [Пакеты для Debian и CentOS](../installation/packages.ru.md)
|
||||||
- [Консольный интерфейс управления образами (vitastor-cli)](../usage/cli.ru.md)
|
- [Консольный интерфейс управления образами (vitastor-cli)](../usage/cli.ru.md)
|
||||||
|
- [Инструмент управления дисками (vitastor-disk)](docs/usage/disk.ru.md)
|
||||||
- Общая пользовательская клиентская библиотека для работы с кластером
|
- Общая пользовательская клиентская библиотека для работы с кластером
|
||||||
- [Драйвер диска для QEMU](../usage/qemu.ru.md)
|
- [Драйвер диска для QEMU](../usage/qemu.ru.md)
|
||||||
- [Драйвер диска для утилиты тестирования производительности fio](../usage/fio.ru.md)
|
- [Драйвер диска для утилиты тестирования производительности fio](../usage/fio.ru.md)
|
||||||
@@ -47,7 +48,6 @@
|
|||||||
|
|
||||||
## Планы развития
|
## Планы развития
|
||||||
|
|
||||||
- Более корректные скрипты разметки дисков и автоматического запуска OSD
|
|
||||||
- Другие инструменты администрирования
|
- Другие инструменты администрирования
|
||||||
- Web-интерфейс
|
- Web-интерфейс
|
||||||
- Плагин для OpenNebula
|
- Плагин для OpenNebula
|
||||||
|
@@ -26,9 +26,14 @@
|
|||||||
## Configure monitors
|
## Configure monitors
|
||||||
|
|
||||||
On the monitor hosts:
|
On the monitor hosts:
|
||||||
- Edit variables at the top of `/usr/lib/vitastor/mon/make-units.sh` to desired values.
|
- Put identical etcd_address into `/etc/vitastor/vitastor.conf`. Example:
|
||||||
- Create systemd units for the monitor and etcd: `/usr/lib/vitastor/mon/make-units.sh`
|
```
|
||||||
- Start etcd and monitors: `systemctl start etcd vitastor-mon`
|
{
|
||||||
|
"etcd_address": ["10.200.1.10:2379","10.200.1.11:2379","10.200.1.12:2379"]
|
||||||
|
}
|
||||||
|
```
|
||||||
|
- Create systemd units for etcd by running: `/usr/lib/vitastor/mon/make-etcd`
|
||||||
|
- Start etcd and monitors: `systemctl enable --now etcd vitastor-mon`
|
||||||
|
|
||||||
## Configure OSDs
|
## Configure OSDs
|
||||||
|
|
||||||
@@ -40,17 +45,19 @@ On the monitor hosts:
|
|||||||
}
|
}
|
||||||
```
|
```
|
||||||
- Initialize OSDs:
|
- Initialize OSDs:
|
||||||
- Simplest, SSD-only: `/usr/lib/vitastor/mon/make-osd.sh /dev/disk/by-partuuid/XXX [/dev/disk/by-partuuid/YYY ...]`
|
- SSD-only: `vitastor-disk prepare /dev/sdXXX [/dev/sdYYY ...]`. You can add
|
||||||
**Warning!** This very simple script by default makes units for server-grade SSDs with write-through cache!
|
`--disable_data_fsync off` to leave disk cache enabled if you use desktop
|
||||||
If it's not your case, you MUST remove disable_data_fsync and immediate_commit from systemd units.
|
SSDs without capacitors.
|
||||||
- Hybrid, HDD+SSD: `/usr/lib/vitastor/mon/make-osd-hybrid.js /dev/sda /dev/sdb ...` — pass all your
|
- Hybrid, SSD+HDD: `vitastor-disk prepare --hybrid /dev/sdXXX [/dev/sdYYY ...]`.
|
||||||
devices (HDD and SSD) to this script — it will partition disks and initialize journals on its own.
|
Pass all your devices (HDD and SSD) to this script — it will partition disks and initialize journals on its own.
|
||||||
This script skips HDDs which are already partitioned so if you want to use non-empty disks for
|
This script skips HDDs which are already partitioned so if you want to use non-empty disks for
|
||||||
Vitastor you should first wipe them with `wipefs -a`. SSDs with GPT partition table are not skipped,
|
Vitastor you should first wipe them with `wipefs -a`. SSDs with GPT partition table are not skipped,
|
||||||
but some free unpartitioned space must be available because the script creates new partitions for journals.
|
but some free unpartitioned space must be available because the script creates new partitions for journals.
|
||||||
- You can change OSD configuration in units or in `vitastor.conf`.
|
- You can change OSD configuration in units or in `vitastor.conf`.
|
||||||
Check [Configuration Reference](../config.en.md) for parameter descriptions.
|
Check [Configuration Reference](../config.en.md) for parameter descriptions.
|
||||||
- If all your drives have capacitors, create global configuration in etcd: \
|
- If all your drives have capacitors, and even if not, but if you ran `vitastor-disk`
|
||||||
|
without `--disable_data_fsync off` at the first step, then put the following
|
||||||
|
setting into etcd: \
|
||||||
`etcdctl --endpoints=... put /vitastor/config/global '{"immediate_commit":"all"}'`
|
`etcdctl --endpoints=... put /vitastor/config/global '{"immediate_commit":"all"}'`
|
||||||
- Start all OSDs: `systemctl start vitastor.target`
|
- Start all OSDs: `systemctl start vitastor.target`
|
||||||
|
|
||||||
@@ -63,15 +70,19 @@ etcdctl --endpoints=... put /vitastor/config/pools '{"1":{"name":"testpool",
|
|||||||
"scheme":"replicated","pg_size":2,"pg_minsize":1,"pg_count":256,"failure_domain":"host"}}'
|
"scheme":"replicated","pg_size":2,"pg_minsize":1,"pg_count":256,"failure_domain":"host"}}'
|
||||||
```
|
```
|
||||||
|
|
||||||
For jerasure pools the configuration should look like the following:
|
For EC pools the configuration should look like the following:
|
||||||
|
|
||||||
```
|
```
|
||||||
etcdctl --endpoints=... put /vitastor/config/pools '{"2":{"name":"ecpool",
|
etcdctl --endpoints=... put /vitastor/config/pools '{"2":{"name":"ecpool",
|
||||||
"scheme":"jerasure","pg_size":4,"parity_chunks":2,"pg_minsize":2,"pg_count":256,"failure_domain":"host"}`
|
"scheme":"ec","pg_size":4,"parity_chunks":2,"pg_minsize":2,"pg_count":256,"failure_domain":"host"}}'
|
||||||
```
|
```
|
||||||
|
|
||||||
After you do this, one of the monitors will configure PGs and OSDs will start them.
|
After you do this, one of the monitors will configure PGs and OSDs will start them.
|
||||||
|
|
||||||
|
If you use HDDs you should also add `"block_size": 1048576` to pool configuration.
|
||||||
|
The other option is to add it into /vitastor/config/global, in this case it will
|
||||||
|
apply to all pools by default.
|
||||||
|
|
||||||
## Check cluster status
|
## Check cluster status
|
||||||
|
|
||||||
`vitastor-cli status`
|
`vitastor-cli status`
|
||||||
|
@@ -26,16 +26,14 @@
|
|||||||
## Настройте мониторы
|
## Настройте мониторы
|
||||||
|
|
||||||
На хостах, выделенных под мониторы:
|
На хостах, выделенных под мониторы:
|
||||||
- Пропишите нужные вам значения в файле `/usr/lib/vitastor/mon/make-units.sh`
|
- Пропишите одинаковые etcd_address в `/etc/vitastor/vitastor.conf`. Например:
|
||||||
- Создайте юниты systemd для etcd и мониторов: `/usr/lib/vitastor/mon/make-units.sh`
|
|
||||||
- Запустите etcd и мониторы: `systemctl start etcd vitastor-mon`
|
|
||||||
- Пропишите etcd_address и osd_network в `/etc/vitastor/vitastor.conf`. Например:
|
|
||||||
```
|
```
|
||||||
{
|
{
|
||||||
"etcd_address": ["10.200.1.10:2379","10.200.1.11:2379","10.200.1.12:2379"],
|
"etcd_address": ["10.200.1.10:2379","10.200.1.11:2379","10.200.1.12:2379"]
|
||||||
"osd_network": "10.200.1.0/24"
|
|
||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
- Инициализируйте сервисы etcd, запустив `/usr/lib/vitastor/mon/make-etcd`
|
||||||
|
- Запустите etcd и мониторы: `systemctl enable --now etcd vitastor-mon`
|
||||||
|
|
||||||
## Настройте OSD
|
## Настройте OSD
|
||||||
|
|
||||||
@@ -47,19 +45,22 @@
|
|||||||
}
|
}
|
||||||
```
|
```
|
||||||
- Инициализуйте OSD:
|
- Инициализуйте OSD:
|
||||||
- SSD: `/usr/lib/vitastor/make-osd.sh /dev/disk/by-partuuid/XXX [/dev/disk/by-partuuid/YYY ...]`. \
|
- SSD: `vitastor-disk prepare /dev/sdXXX [/dev/sdYYY ...]`. Если вы используете
|
||||||
**Внимание!** Скрипт по умолчанию рассчитан на то, что у вас диски с конденсаторами и отключённым
|
десктопные SSD без конденсаторов, можете оставить кэш включённым, добавив
|
||||||
кэшем! Если это не так, из юнитов systemd нужно убрать строчки disable_data_fsync и immediate_commit!
|
опцию `--disable_data_fsync off`.
|
||||||
- Гибридные, HDD+SSD: `/usr/lib/vitastor/mon/make-osd-hybrid.js /dev/sda /dev/sdb ...` - передайте
|
- Гибридные, SSD+HDD: `vitastor-disk prepare --hybrid /dev/sdXXX [/dev/sdYYY ...]`.
|
||||||
все ваши SSD и HDD скрипту в командной строке подряд, скрипт автоматически выделит разделы под
|
Передайте все ваши SSD и HDD скрипту в командной строке подряд, скрипт автоматически выделит
|
||||||
журналы на SSD и данные на HDD. Скрипт пропускает HDD, на которых уже есть разделы
|
разделы под журналы на SSD и данные на HDD. Скрипт пропускает HDD, на которых уже есть разделы
|
||||||
или вообще какие-то данные, поэтому если диски непустые, сначала очистите их с помощью
|
или вообще какие-то данные, поэтому если диски непустые, сначала очистите их с помощью
|
||||||
`wipefs -a`. SSD с таблицей разделов не пропускаются, но так как скрипт создаёт новые разделы
|
`wipefs -a`. SSD с таблицей разделов не пропускаются, но так как скрипт создаёт новые разделы
|
||||||
для журналов, на SSD должно быть доступно свободное нераспределённое место.
|
для журналов, на SSD должно быть доступно свободное нераспределённое место.
|
||||||
- Вы можете менять параметры OSD в юнитах systemd или в `vitastor.conf`. Описания параметров
|
- Вы можете менять параметры OSD в юнитах systemd или в `vitastor.conf`. Описания параметров
|
||||||
смотрите в [справке по конфигурации](../config.ru.md).
|
смотрите в [справке по конфигурации](../config.ru.md).
|
||||||
- Если все ваши диски - серверные с конденсаторами, пропишите это в глобальную конфигурацию в etcd: \
|
- Если все ваши диски - серверные с конденсаторами, и даже если нет, но при этом
|
||||||
`etcdctl --endpoints=... put /vitastor/config/global '{"immediate_commit":"all"}'`
|
вы не добавляли опцию `--disable_data_fsync off` на первом шаге, а `vitastor-disk`
|
||||||
|
не ругался на невозможность отключения кэша дисков, пропишите следующую настройку
|
||||||
|
в глобальную конфигурацию в etcd: \
|
||||||
|
`etcdctl --endpoints=... put /vitastor/config/global '{"immediate_commit":"all"}'`.
|
||||||
- Запустите все OSD: `systemctl start vitastor.target`
|
- Запустите все OSD: `systemctl start vitastor.target`
|
||||||
|
|
||||||
## Создайте пул
|
## Создайте пул
|
||||||
@@ -75,11 +76,15 @@ etcdctl --endpoints=... put /vitastor/config/pools '{"1":{"name":"testpool",
|
|||||||
|
|
||||||
```
|
```
|
||||||
etcdctl --endpoints=... put /vitastor/config/pools '{"2":{"name":"ecpool",
|
etcdctl --endpoints=... put /vitastor/config/pools '{"2":{"name":"ecpool",
|
||||||
"scheme":"jerasure","pg_size":4,"parity_chunks":2,"pg_minsize":2,"pg_count":256,"failure_domain":"host"}`
|
"scheme":"ec","pg_size":4,"parity_chunks":2,"pg_minsize":2,"pg_count":256,"failure_domain":"host"}}'
|
||||||
```
|
```
|
||||||
|
|
||||||
После этого один из мониторов должен сконфигурировать PG, а OSD должны запустить их.
|
После этого один из мониторов должен сконфигурировать PG, а OSD должны запустить их.
|
||||||
|
|
||||||
|
Если вы используете HDD-диски, то добавьте в конфигурацию пулов опцию `"block_size": 1048576`.
|
||||||
|
Также эту опцию можно добавить в /vitastor/config/global, в этом случае она будет
|
||||||
|
применяться ко всем пулам по умолчанию.
|
||||||
|
|
||||||
## Проверьте состояние кластера
|
## Проверьте состояние кластера
|
||||||
|
|
||||||
`vitastor-cli status`
|
`vitastor-cli status`
|
||||||
|
@@ -35,15 +35,24 @@ Write amplification for 4 KB blocks is usually 3-5 in Vitastor:
|
|||||||
If you manage to get an SSD which handles 512 byte blocks well (Optane?) you may
|
If you manage to get an SSD which handles 512 byte blocks well (Optane?) you may
|
||||||
lower 1, 3 and 4 to 512 bytes (1/8 of data size) and get WA as low as 2.375.
|
lower 1, 3 and 4 to 512 bytes (1/8 of data size) and get WA as low as 2.375.
|
||||||
|
|
||||||
|
Implemented NVDIMM support can basically eliminate WA at all - all extra writes will
|
||||||
|
go to DRAM memory. But this requires a test cluster with NVDIMM - please contact me
|
||||||
|
if you want to provide me with such cluster for tests.
|
||||||
|
|
||||||
Lazy fsync also reduces WA for parallel workloads because journal blocks are only
|
Lazy fsync also reduces WA for parallel workloads because journal blocks are only
|
||||||
written when they fill up or fsync is requested.
|
written when they fill up or fsync is requested.
|
||||||
|
|
||||||
## In Practice
|
## In Practice
|
||||||
|
|
||||||
In practice, using tests from [Understanding Performance](understanding.en.md)
|
In practice, using tests from [Understanding Performance](understanding.en.md), decent TCP network,
|
||||||
and good server-grade SSD/NVMe drives, you should head for:
|
good server-grade SSD/NVMe drives and disabled CPU power saving, you should head for:
|
||||||
- At least 5000 T1Q1 replicated read and write iops (maximum 0.2ms latency)
|
- At least 5000 T1Q1 replicated read and write iops (maximum 0.2ms latency)
|
||||||
|
- At least 5000 T1Q1 EC read IOPS and at least 2200 EC write IOPS (maximum 0.45ms latency)
|
||||||
- At least ~80k parallel read iops or ~30k write iops per 1 core (1 OSD)
|
- At least ~80k parallel read iops or ~30k write iops per 1 core (1 OSD)
|
||||||
- Disk-speed or wire-speed linear reads and writes, whichever is the bottleneck in your case
|
- Disk-speed or wire-speed linear reads and writes, whichever is the bottleneck in your case
|
||||||
|
|
||||||
Lower results may mean that you have bad drives, bad network or some kind of misconfiguration.
|
Lower results may mean that you have bad drives, bad network or some kind of misconfiguration.
|
||||||
|
|
||||||
|
Current latency records:
|
||||||
|
- 9668 T1Q1 replicated write iops (0.103 ms latency) with TCP and NVMe
|
||||||
|
- 9143 T1Q1 replicated read iops (0.109 ms latency) with TCP and NVMe
|
||||||
|
@@ -36,6 +36,25 @@ WA (мультипликатор записи) для 4 КБ блоков в Vit
|
|||||||
Если вы найдёте SSD, хорошо работающий с 512-байтными блоками данных (Optane?),
|
Если вы найдёте SSD, хорошо работающий с 512-байтными блоками данных (Optane?),
|
||||||
то 1, 3 и 4 можно снизить до 512 байт (1/8 от размера данных) и получить WA всего 2.375.
|
то 1, 3 и 4 можно снизить до 512 байт (1/8 от размера данных) и получить WA всего 2.375.
|
||||||
|
|
||||||
|
Если реализовать поддержку NVDIMM, то WA можно, условно говоря, ликвидировать вообще - все
|
||||||
|
дополнительные операции записи смогут обслуживаться DRAM памятью. Но для этого необходим
|
||||||
|
тестовый кластер с NVDIMM - пишите, если готовы предоставить такой для тестов.
|
||||||
|
|
||||||
Кроме того, WA снижается при использовании отложенного/ленивого сброса при параллельной
|
Кроме того, WA снижается при использовании отложенного/ленивого сброса при параллельной
|
||||||
нагрузке, т.к. блоки журнала записываются на диск только когда они заполняются или явным
|
нагрузке, т.к. блоки журнала записываются на диск только когда они заполняются или явным
|
||||||
образом запрашивается fsync.
|
образом запрашивается fsync.
|
||||||
|
|
||||||
|
## На практике
|
||||||
|
|
||||||
|
На практике, используя тесты fio со страницы [Понимание сути производительности систем хранения](understanding.ru.md),
|
||||||
|
нормальную TCP-сеть, хорошие серверные SSD/NVMe, при отключённом энергосбережении процессоров вы можете рассчитывать на:
|
||||||
|
- От 5000 IOPS в 1 поток (T1Q1) и на чтение, и на запись при использовании репликации (задержка до 0.2мс)
|
||||||
|
- От 5000 IOPS в 1 поток (T1Q1) на чтение и 2200 IOPS в 1 поток на запись при использовании EC (задержка до 0.45мс)
|
||||||
|
- От 80000 IOPS на чтение в параллельном режиме на 1 ядро, от 30000 IOPS на запись на 1 ядро (на 1 OSD)
|
||||||
|
- Скорость параллельного линейного чтения и записи, равная меньшему значению из скорости дисков или сети
|
||||||
|
|
||||||
|
Худшие результаты означают, что у вас либо медленные диски, либо медленная сеть, либо что-то неправильно настроено.
|
||||||
|
|
||||||
|
Зафиксированный на данный момент рекорд задержки:
|
||||||
|
- 9668 IOPS (0.103 мс задержка) в 1 поток (T1Q1) на запись с TCP и NVMe при использовании репликации
|
||||||
|
- 9143 IOPS (0.109 мс задержка) в 1 поток (T1Q1) на чтение с TCP и NVMe при использовании репликации
|
||||||
|
@@ -14,13 +14,14 @@ It supports the following commands:
|
|||||||
- [df](#df)
|
- [df](#df)
|
||||||
- [ls](#ls)
|
- [ls](#ls)
|
||||||
- [create](#create)
|
- [create](#create)
|
||||||
|
- [snap-create](#create)
|
||||||
- [modify](#modify)
|
- [modify](#modify)
|
||||||
- [rm](#rm)
|
- [rm](#rm)
|
||||||
- [flatten](#flatten)
|
- [flatten](#flatten)
|
||||||
- [rm-data](#rm-data)
|
- [rm-data](#rm-data)
|
||||||
- [merge-data](#merge-data)
|
- [merge-data](#merge-data)
|
||||||
- [alloc-osd](#alloc-osd)
|
- [alloc-osd](#alloc-osd)
|
||||||
- [simple-offsets](#simple-offsets)
|
- [rm-osd](#rm-osd)
|
||||||
|
|
||||||
Global options:
|
Global options:
|
||||||
|
|
||||||
@@ -38,9 +39,9 @@ Global options:
|
|||||||
|
|
||||||
`vitastor-cli status`
|
`vitastor-cli status`
|
||||||
|
|
||||||
Показать состояние кластера.
|
Show cluster status.
|
||||||
|
|
||||||
Пример вывода:
|
Example output:
|
||||||
|
|
||||||
```
|
```
|
||||||
cluster:
|
cluster:
|
||||||
@@ -65,9 +66,9 @@ Global options:
|
|||||||
|
|
||||||
`vitastor-cli df`
|
`vitastor-cli df`
|
||||||
|
|
||||||
Показать список пулов и занятое место.
|
Show pool space statistics.
|
||||||
|
|
||||||
Пример вывода:
|
Example output:
|
||||||
|
|
||||||
```
|
```
|
||||||
NAME SCHEME PGS TOTAL USED AVAILABLE USED% EFFICIENCY
|
NAME SCHEME PGS TOTAL USED AVAILABLE USED% EFFICIENCY
|
||||||
@@ -76,27 +77,26 @@ size1 1/1 32 199.9 G 10 G 121.5 G 39.23% 100%
|
|||||||
kaveri 2/1 32 0 B 10 G 0 B 100% 0%
|
kaveri 2/1 32 0 B 10 G 0 B 100% 0%
|
||||||
```
|
```
|
||||||
|
|
||||||
В примере у пула "kaveri" эффективность равна нулю, так как все OSD выключены.
|
In the example above, "kaveri" pool has "zero" efficiency because all its OSD are down.
|
||||||
|
|
||||||
## ls
|
## ls
|
||||||
|
|
||||||
`vitastor-cli ls [-l] [-p POOL] [--sort FIELD] [-r] [-n N] [<glob> ...]`
|
`vitastor-cli ls [-l] [-p POOL] [--sort FIELD] [-r] [-n N] [<glob> ...]`
|
||||||
|
|
||||||
Показать список образов, если переданы шаблоны `<glob>`, то только с именами,
|
List images (only matching `<glob>` pattern(s) if passed).
|
||||||
соответствующими этим шаблонам (стандартные ФС-шаблоны с * и ?).
|
|
||||||
|
|
||||||
Опции:
|
Options:
|
||||||
|
|
||||||
```
|
```
|
||||||
-p|--pool POOL Фильтровать образы по пулу (ID или имени)
|
-p|--pool POOL Filter images by pool ID or name
|
||||||
-l|--long Также выводить статистику занятого места и ввода-вывода
|
-l|--long Also report allocated size and I/O statistics
|
||||||
--del Также выводить статистику операций удаления
|
--del Also include delete operation statistics
|
||||||
--sort FIELD Сортировать по заданному полю (name, size, used_size, <read|write|delete>_<iops|bps|lat|queue>)
|
--sort FIELD Sort by specified field (name, size, used_size, <read|write|delete>_<iops|bps|lat|queue>)
|
||||||
-r|--reverse Сортировать в обратном порядке
|
-r|--reverse Sort in descending order
|
||||||
-n|--count N Показывать только первые N записей
|
-n|--count N Only list first N items
|
||||||
```
|
```
|
||||||
|
|
||||||
Пример вывода:
|
Example output:
|
||||||
|
|
||||||
```
|
```
|
||||||
NAME POOL SIZE USED READ IOPS QUEUE LAT WRITE IOPS QUEUE LAT FLAGS PARENT
|
NAME POOL SIZE USED READ IOPS QUEUE LAT WRITE IOPS QUEUE LAT FLAGS PARENT
|
||||||
@@ -113,94 +113,80 @@ bench-kaveri kaveri 10 G 10 G 0 B/s 0 0 0 us 0 B/s 0
|
|||||||
|
|
||||||
`vitastor-cli create -s|--size <size> [-p|--pool <id|name>] [--parent <parent_name>[@<snapshot>]] <name>`
|
`vitastor-cli create -s|--size <size> [-p|--pool <id|name>] [--parent <parent_name>[@<snapshot>]] <name>`
|
||||||
|
|
||||||
Создать образ. Для размера `<size>` можно использовать суффиксы K/M/G/T (килобайт-мегабайт-гигабайт-терабайт).
|
Create an image. You may use K/M/G/T suffixes for `<size>`. If `--parent` is specified,
|
||||||
Если указана опция `--parent`, создаётся клон образа. Родитель `<parent_name>[@<snapshot>]` должен быть
|
a copy-on-write image clone is created. Parent must be a snapshot (readonly image).
|
||||||
снимком (или просто немодифицируемым образом). Пул обязательно указывать, если в кластере больше одного пула.
|
Pool must be specified if there is more than one pool.
|
||||||
|
|
||||||
```
|
```
|
||||||
vitastor-cli create --snapshot <snapshot> [-p|--pool <id|name>] <image>
|
vitastor-cli create --snapshot <snapshot> [-p|--pool <id|name>] <image>
|
||||||
vitastor-cli snap-create [-p|--pool <id|name>] <image>@<snapshot>
|
vitastor-cli snap-create [-p|--pool <id|name>] <image>@<snapshot>
|
||||||
```
|
```
|
||||||
|
|
||||||
Создать снимок образа `<name>` (можно использовать любую форму команды). Снимок можно создавать без остановки
|
Create a snapshot of image `<name>` (either form can be used). May be used live if only a single writer is active.
|
||||||
клиентов, если пишущий клиент максимум 1.
|
|
||||||
|
See also about [how to export snapshots](qemu.en.md#exporting-snapshots).
|
||||||
|
|
||||||
## modify
|
## modify
|
||||||
|
|
||||||
`vitastor-cli modify <name> [--rename <new-name>] [--resize <size>] [--readonly | --readwrite] [-f|--force]`
|
`vitastor-cli modify <name> [--rename <new-name>] [--resize <size>] [--readonly | --readwrite] [-f|--force]`
|
||||||
|
|
||||||
Изменить размер, имя образа или флаг "только для чтения". Снимать флаг "только для чтения"
|
Rename, resize image or change its readonly status. Images with children can't be made read-write.
|
||||||
и уменьшать размер образов, у которых есть дочерние клоны, без `--force` нельзя.
|
If the new size is smaller than the old size, extra data will be purged.
|
||||||
|
You should resize file system in the image, if present, before shrinking it.
|
||||||
Если новый размер меньше старого, "лишние" данные будут удалены, поэтому перед уменьшением
|
|
||||||
образа сначала уменьшите файловую систему в нём.
|
|
||||||
|
|
||||||
```
|
```
|
||||||
-f|--force Разрешить уменьшение или перевод в чтение-запись образа, у которого есть клоны.
|
-f|--force Proceed with shrinking or setting readwrite flag even if the image has children.
|
||||||
```
|
```
|
||||||
|
|
||||||
## rm
|
## rm
|
||||||
|
|
||||||
`vitastor-cli rm <from> [<to>] [--writers-stopped]`
|
`vitastor-cli rm <from> [<to>] [--writers-stopped]`
|
||||||
|
|
||||||
Удалить образ `<from>` или все слои от `<from>` до `<to>` (`<to>` должен быть дочерним
|
Remove `<from>` or all layers between `<from>` and `<to>` (`<to>` must be a child of `<from>`),
|
||||||
образом `<from>`), одновременно меняя родительские образы их клонов (если таковые есть).
|
rebasing all their children accordingly. --writers-stopped allows merging to be a bit
|
||||||
|
more effective in case of a single 'slim' read-write child and 'fat' removed parent:
|
||||||
`--writers-stopped` позволяет чуть более эффективно удалять образы в частом случае, когда
|
the child is merged into parent and parent is renamed to child in that case.
|
||||||
у удаляемой цепочки есть только один дочерний образ, содержащий небольшой объём данных.
|
In other cases parent layers are always merged into children.
|
||||||
В этом случае дочерний образ вливается в родительский и удаляется, а родительский
|
|
||||||
переименовывается в дочерний.
|
|
||||||
|
|
||||||
В других случаях родительские слои вливаются в дочерние.
|
|
||||||
|
|
||||||
## flatten
|
## flatten
|
||||||
|
|
||||||
`vitastor-cli flatten <layer>`
|
`vitastor-cli flatten <layer>`
|
||||||
|
|
||||||
Сделай образ `<layer>` плоским, то есть, скопировать в него данные и разорвать его
|
Flatten a layer, i.e. merge data and detach it from parents.
|
||||||
соединение с родительскими.
|
|
||||||
|
|
||||||
## rm-data
|
## rm-data
|
||||||
|
|
||||||
`vitastor-cli rm-data --pool <pool> --inode <inode> [--wait-list] [--min-offset <offset>]`
|
`vitastor-cli rm-data --pool <pool> --inode <inode> [--wait-list] [--min-offset <offset>]`
|
||||||
|
|
||||||
Удалить данные инода, не меняя метаданные образов.
|
Remove inode data without changing metadata.
|
||||||
|
|
||||||
```
|
```
|
||||||
--wait-list Сначала запросить полный листинг объектов, а потом начать удалять.
|
--wait-list Retrieve full objects listings before starting to remove objects.
|
||||||
Требует больше памяти, но позволяет правильно печатать прогресс удаления.
|
Requires more memory, but allows to show correct removal progress.
|
||||||
--min-offset Удалять только данные, начиная с заданного смещения.
|
--min-offset Purge only data starting with specified offset.
|
||||||
```
|
```
|
||||||
|
|
||||||
## merge-data
|
## merge-data
|
||||||
|
|
||||||
`vitastor-cli merge-data <from> <to> [--target <target>]`
|
`vitastor-cli merge-data <from> <to> [--target <target>]`
|
||||||
|
|
||||||
Слить данные слоёв, не меняя метаданные. Вливает данные из слоёв от `<from>` до `<to>`
|
Merge layer data without changing metadata. Merge `<from>`..`<to>` to `<target>`.
|
||||||
в целевой образ `<target>`. `<to>` должен быть дочерним образом `<from>`, а `<target>`
|
`<to>` must be a child of `<from>` and `<target>` may be one of the layers between
|
||||||
должен быть одним из слоёв между `<from>` и `<to>`, включая сами `<from>` и `<to>`.
|
`<from>` and `<to>`, including `<from>` and `<to>`.
|
||||||
|
|
||||||
## alloc-osd
|
## alloc-osd
|
||||||
|
|
||||||
`vitastor-cli alloc-osd`
|
`vitastor-cli alloc-osd`
|
||||||
|
|
||||||
Атомарно выделить новый номер OSD и зарезервировать его, создав в etcd пустой
|
Allocate a new OSD number and reserve it by creating empty `/osd/stats/<n>` key.
|
||||||
ключ `/osd/stats/<n>`.
|
|
||||||
|
|
||||||
## simple-offsets
|
## rm-osd
|
||||||
|
|
||||||
`vitastor-cli simple-offsets <device>`
|
`vitastor-cli rm-osd [--force] [--allow-data-loss] [--dry-run] <osd_id> [osd_id...]`
|
||||||
|
|
||||||
Рассчитать смещения для простого и тупого создания OSD на диске (без суперблока).
|
Remove metadata and configuration for specified OSD(s) from etcd.
|
||||||
|
|
||||||
Опции (см. также [Дисковые параметры уровня кластера](../config/layout-cluster.ru.md)):
|
Refuses to remove OSDs with data without `--force` and `--allow-data-loss`.
|
||||||
|
|
||||||
```
|
With `--dry-run` only checks if deletion is possible without data loss and
|
||||||
--object_size 128k Размер блока хранилища
|
redundancy degradation.
|
||||||
--bitmap_granularity 4k Гранулярность битовых карт
|
|
||||||
--journal_size 32M Размер журнала
|
|
||||||
--device_block_size 4k Размер блока устройства
|
|
||||||
--journal_offset 0 Смещение журнала
|
|
||||||
--device_size 0 Размер устройства
|
|
||||||
--format text Формат результата: json, options, env или text
|
|
||||||
```
|
|
||||||
|
@@ -15,13 +15,14 @@ vitastor-cli - интерфейс командной строки для адм
|
|||||||
- [df](#df)
|
- [df](#df)
|
||||||
- [ls](#ls)
|
- [ls](#ls)
|
||||||
- [create](#create)
|
- [create](#create)
|
||||||
|
- [snap-create](#create)
|
||||||
- [modify](#modify)
|
- [modify](#modify)
|
||||||
- [rm](#rm)
|
- [rm](#rm)
|
||||||
- [flatten](#flatten)
|
- [flatten](#flatten)
|
||||||
- [rm-data](#rm-data)
|
- [rm-data](#rm-data)
|
||||||
- [merge-data](#merge-data)
|
- [merge-data](#merge-data)
|
||||||
- [alloc-osd](#alloc-osd)
|
- [alloc-osd](#alloc-osd)
|
||||||
- [simple-offsets](#simple-offsets)
|
- [rm-osd](#rm-osd)
|
||||||
|
|
||||||
Глобальные опции:
|
Глобальные опции:
|
||||||
|
|
||||||
@@ -39,9 +40,9 @@ vitastor-cli - интерфейс командной строки для адм
|
|||||||
|
|
||||||
`vitastor-cli status`
|
`vitastor-cli status`
|
||||||
|
|
||||||
Show cluster status.
|
Показать состояние кластера.
|
||||||
|
|
||||||
Example output:
|
Пример вывода:
|
||||||
|
|
||||||
```
|
```
|
||||||
cluster:
|
cluster:
|
||||||
@@ -66,9 +67,9 @@ Example output:
|
|||||||
|
|
||||||
`vitastor-cli df`
|
`vitastor-cli df`
|
||||||
|
|
||||||
Show pool space statistics.
|
Показать список пулов и занятое место.
|
||||||
|
|
||||||
Example output:
|
Пример вывода:
|
||||||
|
|
||||||
```
|
```
|
||||||
NAME SCHEME PGS TOTAL USED AVAILABLE USED% EFFICIENCY
|
NAME SCHEME PGS TOTAL USED AVAILABLE USED% EFFICIENCY
|
||||||
@@ -77,26 +78,27 @@ size1 1/1 32 199.9 G 10 G 121.5 G 39.23% 100%
|
|||||||
kaveri 2/1 32 0 B 10 G 0 B 100% 0%
|
kaveri 2/1 32 0 B 10 G 0 B 100% 0%
|
||||||
```
|
```
|
||||||
|
|
||||||
In the example above, "kaveri" pool has "zero" efficiency because all its OSD are down.
|
В примере у пула "kaveri" эффективность равна нулю, так как все OSD выключены.
|
||||||
|
|
||||||
## ls
|
## ls
|
||||||
|
|
||||||
`vitastor-cli ls [-l] [-p POOL] [--sort FIELD] [-r] [-n N] [<glob> ...]`
|
`vitastor-cli ls [-l] [-p POOL] [--sort FIELD] [-r] [-n N] [<glob> ...]`
|
||||||
|
|
||||||
List images (only matching `<glob>` pattern(s) if passed).
|
Показать список образов, если переданы шаблоны `<glob>`, то только с именами,
|
||||||
|
соответствующими этим шаблонам (стандартные ФС-шаблоны с * и ?).
|
||||||
|
|
||||||
Options:
|
Опции:
|
||||||
|
|
||||||
```
|
```
|
||||||
-p|--pool POOL Filter images by pool ID or name
|
-p|--pool POOL Фильтровать образы по пулу (ID или имени)
|
||||||
-l|--long Also report allocated size and I/O statistics
|
-l|--long Также выводить статистику занятого места и ввода-вывода
|
||||||
--del Also include delete operation statistics
|
--del Также выводить статистику операций удаления
|
||||||
--sort FIELD Sort by specified field (name, size, used_size, <read|write|delete>_<iops|bps|lat|queue>)
|
--sort FIELD Сортировать по заданному полю (name, size, used_size, <read|write|delete>_<iops|bps|lat|queue>)
|
||||||
-r|--reverse Sort in descending order
|
-r|--reverse Сортировать в обратном порядке
|
||||||
-n|--count N Only list first N items
|
-n|--count N Показывать только первые N записей
|
||||||
```
|
```
|
||||||
|
|
||||||
Example output:
|
Пример вывода:
|
||||||
|
|
||||||
```
|
```
|
||||||
NAME POOL SIZE USED READ IOPS QUEUE LAT WRITE IOPS QUEUE LAT FLAGS PARENT
|
NAME POOL SIZE USED READ IOPS QUEUE LAT WRITE IOPS QUEUE LAT FLAGS PARENT
|
||||||
@@ -113,85 +115,89 @@ bench-kaveri kaveri 10 G 10 G 0 B/s 0 0 0 us 0 B/s 0
|
|||||||
|
|
||||||
`vitastor-cli create -s|--size <size> [-p|--pool <id|name>] [--parent <parent_name>[@<snapshot>]] <name>`
|
`vitastor-cli create -s|--size <size> [-p|--pool <id|name>] [--parent <parent_name>[@<snapshot>]] <name>`
|
||||||
|
|
||||||
Create an image. You may use K/M/G/T suffixes for `<size>`. If `--parent` is specified,
|
Создать образ. Для размера `<size>` можно использовать суффиксы K/M/G/T (килобайт-мегабайт-гигабайт-терабайт).
|
||||||
a copy-on-write image clone is created. Parent must be a snapshot (readonly image).
|
Если указана опция `--parent`, создаётся клон образа. Родитель `<parent_name>[@<snapshot>]` должен быть
|
||||||
Pool must be specified if there is more than one pool.
|
снимком (или просто немодифицируемым образом). Пул обязательно указывать, если в кластере больше одного пула.
|
||||||
|
|
||||||
```
|
```
|
||||||
vitastor-cli create --snapshot <snapshot> [-p|--pool <id|name>] <image>
|
vitastor-cli create --snapshot <snapshot> [-p|--pool <id|name>] <image>
|
||||||
vitastor-cli snap-create [-p|--pool <id|name>] <image>@<snapshot>
|
vitastor-cli snap-create [-p|--pool <id|name>] <image>@<snapshot>
|
||||||
```
|
```
|
||||||
|
|
||||||
Create a snapshot of image `<name>` (either form can be used). May be used live if only a single writer is active.
|
Создать снимок образа `<name>` (можно использовать любую форму команды). Снимок можно создавать без остановки
|
||||||
|
клиентов, если пишущий клиент максимум 1.
|
||||||
|
|
||||||
|
Смотрите также информацию о том, [как экспортировать снимки](qemu.ru.md#экспорт-снимков).
|
||||||
|
|
||||||
## modify
|
## modify
|
||||||
|
|
||||||
`vitastor-cli modify <name> [--rename <new-name>] [--resize <size>] [--readonly | --readwrite] [-f|--force]`
|
`vitastor-cli modify <name> [--rename <new-name>] [--resize <size>] [--readonly | --readwrite] [-f|--force]`
|
||||||
|
|
||||||
Rename, resize image or change its readonly status. Images with children can't be made read-write.
|
Изменить размер, имя образа или флаг "только для чтения". Снимать флаг "только для чтения"
|
||||||
If the new size is smaller than the old size, extra data will be purged.
|
и уменьшать размер образов, у которых есть дочерние клоны, без `--force` нельзя.
|
||||||
You should resize file system in the image, if present, before shrinking it.
|
|
||||||
|
Если новый размер меньше старого, "лишние" данные будут удалены, поэтому перед уменьшением
|
||||||
|
образа сначала уменьшите файловую систему в нём.
|
||||||
|
|
||||||
```
|
```
|
||||||
-f|--force Proceed with shrinking or setting readwrite flag even if the image has children.
|
-f|--force Разрешить уменьшение или перевод в чтение-запись образа, у которого есть клоны.
|
||||||
```
|
```
|
||||||
|
|
||||||
## rm
|
## rm
|
||||||
|
|
||||||
`vitastor-cli rm <from> [<to>] [--writers-stopped]`
|
`vitastor-cli rm <from> [<to>] [--writers-stopped]`
|
||||||
|
|
||||||
Remove `<from>` or all layers between `<from>` and `<to>` (`<to>` must be a child of `<from>`),
|
Удалить образ `<from>` или все слои от `<from>` до `<to>` (`<to>` должен быть дочерним
|
||||||
rebasing all their children accordingly. --writers-stopped allows merging to be a bit
|
образом `<from>`), одновременно меняя родительские образы их клонов (если таковые есть).
|
||||||
more effective in case of a single 'slim' read-write child and 'fat' removed parent:
|
|
||||||
the child is merged into parent and parent is renamed to child in that case.
|
`--writers-stopped` позволяет чуть более эффективно удалять образы в частом случае, когда
|
||||||
In other cases parent layers are always merged into children.
|
у удаляемой цепочки есть только один дочерний образ, содержащий небольшой объём данных.
|
||||||
|
В этом случае дочерний образ вливается в родительский и удаляется, а родительский
|
||||||
|
переименовывается в дочерний.
|
||||||
|
|
||||||
|
В других случаях родительские слои вливаются в дочерние.
|
||||||
|
|
||||||
## flatten
|
## flatten
|
||||||
|
|
||||||
`vitastor-cli flatten <layer>`
|
`vitastor-cli flatten <layer>`
|
||||||
|
|
||||||
Flatten a layer, i.e. merge data and detach it from parents.
|
Сделай образ `<layer>` плоским, то есть, скопировать в него данные и разорвать его
|
||||||
|
соединение с родительскими.
|
||||||
|
|
||||||
## rm-data
|
## rm-data
|
||||||
|
|
||||||
`vitastor-cli rm-data --pool <pool> --inode <inode> [--wait-list] [--min-offset <offset>]`
|
`vitastor-cli rm-data --pool <pool> --inode <inode> [--wait-list] [--min-offset <offset>]`
|
||||||
|
|
||||||
Remove inode data without changing metadata.
|
Удалить данные инода, не меняя метаданные образов.
|
||||||
|
|
||||||
```
|
```
|
||||||
--wait-list Retrieve full objects listings before starting to remove objects.
|
--wait-list Сначала запросить полный листинг объектов, а потом начать удалять.
|
||||||
Requires more memory, but allows to show correct removal progress.
|
Требует больше памяти, но позволяет правильно печатать прогресс удаления.
|
||||||
--min-offset Purge only data starting with specified offset.
|
--min-offset Удалять только данные, начиная с заданного смещения.
|
||||||
```
|
```
|
||||||
|
|
||||||
## merge-data
|
## merge-data
|
||||||
|
|
||||||
`vitastor-cli merge-data <from> <to> [--target <target>]`
|
`vitastor-cli merge-data <from> <to> [--target <target>]`
|
||||||
|
|
||||||
Merge layer data without changing metadata. Merge `<from>`..`<to>` to `<target>`.
|
Слить данные слоёв, не меняя метаданные. Вливает данные из слоёв от `<from>` до `<to>`
|
||||||
`<to>` must be a child of `<from>` and `<target>` may be one of the layers between
|
в целевой образ `<target>`. `<to>` должен быть дочерним образом `<from>`, а `<target>`
|
||||||
`<from>` and `<to>`, including `<from>` and `<to>`.
|
должен быть одним из слоёв между `<from>` и `<to>`, включая сами `<from>` и `<to>`.
|
||||||
|
|
||||||
## alloc-osd
|
## alloc-osd
|
||||||
|
|
||||||
`vitastor-cli alloc-osd`
|
`vitastor-cli alloc-osd`
|
||||||
|
|
||||||
Allocate a new OSD number and reserve it by creating empty `/osd/stats/<n>` key.
|
Атомарно выделить новый номер OSD и зарезервировать его, создав в etcd пустой
|
||||||
|
ключ `/osd/stats/<n>`.
|
||||||
|
|
||||||
## simple-offsets
|
## rm-osd
|
||||||
|
|
||||||
`vitastor-cli simple-offsets <device>`
|
`vitastor-cli rm-osd [--force] [--allow-data-loss] [--dry-run] <osd_id> [osd_id...]`
|
||||||
|
|
||||||
Calculate offsets for simple&stupid (no superblock) OSD deployment.
|
Удалить метаданные и конфигурацию для заданных OSD из etcd.
|
||||||
|
|
||||||
Options (see also [Cluster-Wide Disk Layout Parameters](../config/layout-cluster.en.md)):
|
Отказывается удалять OSD с данными без опций `--force` и `--allow-data-loss`.
|
||||||
|
|
||||||
```
|
С опцией `--dry-run` только проверяет, возможно ли удаление без потери данных и деградации
|
||||||
--object_size 128k Set blockstore block size
|
избыточности.
|
||||||
--bitmap_granularity 4k Set bitmap granularity
|
|
||||||
--journal_size 32M Set journal size
|
|
||||||
--device_block_size 4k Set device block size
|
|
||||||
--journal_offset 0 Set journal offset
|
|
||||||
--device_size 0 Set device size
|
|
||||||
--format text Result format: json, options, env, or text
|
|
||||||
```
|
|
||||||
|
257
docs/usage/disk.en.md
Normal file
257
docs/usage/disk.en.md
Normal file
@@ -0,0 +1,257 @@
|
|||||||
|
[Documentation](../../README.md#documentation) → Usage → Disk management tool
|
||||||
|
|
||||||
|
-----
|
||||||
|
|
||||||
|
[Читать на русском](disk.ru.md)
|
||||||
|
|
||||||
|
# Disk management tool
|
||||||
|
|
||||||
|
vitastor-disk is a command-line tool for physical Vitastor disk management.
|
||||||
|
|
||||||
|
It supports the following commands:
|
||||||
|
|
||||||
|
- [prepare](#prepare)
|
||||||
|
- [upgrade-simple](#upgrade-simple)
|
||||||
|
- [resize](#resize)
|
||||||
|
- [start/stop/restart/enable/disable](#start/stop/restart/enable/disable)
|
||||||
|
- [purge](#purge)
|
||||||
|
- [read-sb](#read-sb)
|
||||||
|
- [write-sb](#write-sb)
|
||||||
|
- [udev](#udev)
|
||||||
|
- [exec-osd](#exec-osd)
|
||||||
|
- [pre-exec](#pre-exec)
|
||||||
|
- Debugging:
|
||||||
|
- [dump-journal](#dump-journal)
|
||||||
|
- [write-journal](#write-journal)
|
||||||
|
- [dump-meta](#dump-meta)
|
||||||
|
- [write-meta](#write-meta)
|
||||||
|
- [simple-offsets](#simple-offsets)
|
||||||
|
|
||||||
|
## prepare
|
||||||
|
|
||||||
|
`vitastor-disk prepare [OPTIONS] [devices...]`
|
||||||
|
|
||||||
|
Initialize disk(s) for Vitastor OSD(s).
|
||||||
|
|
||||||
|
There are two modes of this command. In the first mode, you pass `<devices>` which
|
||||||
|
must be raw disks (not partitions). They are partitioned automatically and OSDs
|
||||||
|
are initialized on all of them.
|
||||||
|
|
||||||
|
In the second mode, you omit `<devices>` and pass `--data_device`, `--journal_device`
|
||||||
|
and/or `--meta_device` which must be already existing partitions identified by their
|
||||||
|
GPT partition UUIDs. In this case a single OSD is created.
|
||||||
|
|
||||||
|
Requires `vitastor-cli`, `wipefs`, `sfdisk` and `partprobe` (from parted) utilities.
|
||||||
|
|
||||||
|
Options (automatic mode):
|
||||||
|
|
||||||
|
```
|
||||||
|
--osd_per_disk <N>
|
||||||
|
Create <N> OSDs on each disk (default 1)
|
||||||
|
--hybrid
|
||||||
|
Prepare hybrid (HDD+SSD) OSDs using provided devices. SSDs will be used for
|
||||||
|
journals and metadata, HDDs will be used for data. Partitions for journals and
|
||||||
|
metadata will be created automatically. Whether disks are SSD or HDD is decided
|
||||||
|
by the `/sys/block/.../queue/rotational` flag. In hybrid mode, default object
|
||||||
|
size is 1 MB instead of 128 KB, default journal size is 1 GB instead of 32 MB,
|
||||||
|
and throttle_small_writes is enabled by default.
|
||||||
|
--disable_data_fsync auto
|
||||||
|
Disable data device cache and fsync (1/yes/true = on, default auto)
|
||||||
|
--disable_meta_fsync auto
|
||||||
|
Disable metadata/journal device cache and fsync (default auto)
|
||||||
|
--meta_reserve 2x,1G
|
||||||
|
New metadata partitions in --hybrid mode are created larger than actual
|
||||||
|
metadata size to ease possible future extension. The default is to allocate
|
||||||
|
2 times more space and at least 1G. Use this option to override.
|
||||||
|
--max_other 10%
|
||||||
|
Use disks for OSD data even if they already have non-Vitastor partitions,
|
||||||
|
but only if these take up no more than this percent of disk space.
|
||||||
|
```
|
||||||
|
|
||||||
|
Options (single-device mode):
|
||||||
|
|
||||||
|
```
|
||||||
|
--data_device <DEV> Use partition <DEV> for data
|
||||||
|
--meta_device <DEV> Use partition <DEV> for metadata (optional)
|
||||||
|
--journal_device <DEV> Use partition <DEV> for journal (optional)
|
||||||
|
--disable_data_fsync 0 Disable data device cache and fsync (default off)
|
||||||
|
--disable_meta_fsync 0 Disable metadata device cache and fsync (default off)
|
||||||
|
--disable_journal_fsync 0 Disable journal device cache and fsync (default off)
|
||||||
|
--force Bypass partition safety checks (for emptiness and so on)
|
||||||
|
```
|
||||||
|
|
||||||
|
Options (both modes):
|
||||||
|
|
||||||
|
```
|
||||||
|
--journal_size 1G/32M Set journal size (area or partition size)
|
||||||
|
--block_size 1M/128k Set blockstore object size
|
||||||
|
--bitmap_granularity 4k Set bitmap granularity
|
||||||
|
--data_device_block 4k Override data device block size
|
||||||
|
--meta_device_block 4k Override metadata device block size
|
||||||
|
--journal_device_block 4k Override journal device block size
|
||||||
|
```
|
||||||
|
|
||||||
|
[immediate_commit](../config/layout-cluster.en.md#immediate_commit) setting is
|
||||||
|
automatically derived from "disable fsync" options. It's set to "all" when fsync
|
||||||
|
is disabled on all devices, and to "small" if fsync is only disabled on journal device.
|
||||||
|
|
||||||
|
When data/meta/journal fsyncs are disabled, the OSD startup script automatically
|
||||||
|
checks the device cache status on start and tries to disable cache for SATA/SAS disks.
|
||||||
|
If it doesn't succeed it issues a warning in the system log.
|
||||||
|
|
||||||
|
You can also pass other OSD options here as arguments and they'll be persisted
|
||||||
|
to the superblock: max_write_iodepth, max_write_iodepth, min_flusher_count,
|
||||||
|
max_flusher_count, inmemory_metadata, inmemory_journal, journal_sector_buffer_count,
|
||||||
|
journal_no_same_sector_overwrites, throttle_small_writes, throttle_target_iops,
|
||||||
|
throttle_target_mbs, throttle_target_parallelism, throttle_threshold_us.
|
||||||
|
See [Runtime OSD Parameters](../config/osd.en.md) for details.
|
||||||
|
|
||||||
|
## upgrade-simple
|
||||||
|
|
||||||
|
`vitastor-disk upgrade-simple <UNIT_FILE|OSD_NUMBER>`
|
||||||
|
|
||||||
|
Upgrade an OSD created by old (0.7.1 and older) `make-osd.sh` or `make-osd-hybrid.js` scripts.
|
||||||
|
|
||||||
|
Adds superblocks to OSD devices, disables old `vitastor-osdN` unit and replaces it with `vitastor-osd@N`.
|
||||||
|
Can be invoked with an osd number of with a path to systemd service file `UNIT_FILE` which
|
||||||
|
must be `/etc/systemd/system/vitastor-osd<OSD_NUMBER>.service`.
|
||||||
|
|
||||||
|
Note that the procedure isn't atomic and may ruin OSD data in case of an interrupt,
|
||||||
|
so don't upgrade all your OSDs in parallel.
|
||||||
|
|
||||||
|
Requires the `sfdisk` utility.
|
||||||
|
|
||||||
|
## resize
|
||||||
|
|
||||||
|
`vitastor-disk resize <ALL_OSD_PARAMETERS> <NEW_LAYOUT> [--iodepth 32]`
|
||||||
|
|
||||||
|
Resize data area and/or rewrite/move journal and metadata.
|
||||||
|
|
||||||
|
`ALL_OSD_PARAMETERS` must include all (at least all disk-related)
|
||||||
|
parameters from OSD command line (i.e. from systemd unit or superblock).
|
||||||
|
|
||||||
|
`NEW_LAYOUT` may include new disk layout parameters:
|
||||||
|
|
||||||
|
```
|
||||||
|
--new_data_offset SIZE resize data area so it starts at SIZE
|
||||||
|
--new_data_len SIZE resize data area to SIZE bytes
|
||||||
|
--new_meta_device PATH use PATH for new metadata
|
||||||
|
--new_meta_offset SIZE make new metadata area start at SIZE
|
||||||
|
--new_meta_len SIZE make new metadata area SIZE bytes long
|
||||||
|
--new_journal_device PATH use PATH for new journal
|
||||||
|
--new_journal_offset SIZE make new journal area start at SIZE
|
||||||
|
--new_journal_len SIZE make new journal area SIZE bytes long
|
||||||
|
```
|
||||||
|
|
||||||
|
SIZE may include k/m/g/t suffixes. If any of the new layout parameter
|
||||||
|
options are not specified, old values will be used.
|
||||||
|
|
||||||
|
## start/stop/restart/enable/disable
|
||||||
|
|
||||||
|
`vitastor-disk start|stop|restart|enable|disable [--now] <device> [device2 device3 ...]`
|
||||||
|
|
||||||
|
Manipulate Vitastor OSDs using systemd by their device paths.
|
||||||
|
|
||||||
|
Commands are passed to `systemctl` with `vitastor-osd@<num>` units as arguments.
|
||||||
|
|
||||||
|
When `--now` is added to enable/disable, OSDs are also immediately started/stopped.
|
||||||
|
|
||||||
|
## purge
|
||||||
|
|
||||||
|
`vitastor-disk purge [--force] [--allow-data-loss] <device> [device2 device3 ...]`
|
||||||
|
|
||||||
|
Purge Vitastor OSD(s) on specified device(s). Uses `vitastor-cli rm-osd` to check
|
||||||
|
if deletion is possible without data loss and to actually remove metadata from etcd.
|
||||||
|
`--force` and `--allow-data-loss` options may be used to ignore safety check results.
|
||||||
|
|
||||||
|
Requires `vitastor-cli`, `sfdisk` and `partprobe` (from parted) utilities.
|
||||||
|
|
||||||
|
## read-sb
|
||||||
|
|
||||||
|
`vitastor-disk read-sb [--force] <device>`
|
||||||
|
|
||||||
|
Try to read Vitastor OSD superblock from `<device>` and print it in JSON format.
|
||||||
|
`--force` allows to ignore validation errors.
|
||||||
|
|
||||||
|
## write-sb
|
||||||
|
|
||||||
|
`vitastor-disk write-sb <device>`
|
||||||
|
|
||||||
|
Read JSON from STDIN and write it into Vitastor OSD superblock on `<device>`.
|
||||||
|
|
||||||
|
## udev
|
||||||
|
|
||||||
|
`vitastor-disk udev <device>`
|
||||||
|
|
||||||
|
Try to read Vitastor OSD superblock from `<device>` and print variables for udev.
|
||||||
|
|
||||||
|
## exec-osd
|
||||||
|
|
||||||
|
`vitastor-disk exec-osd <device>`
|
||||||
|
|
||||||
|
Read Vitastor OSD superblock from `<device>` and start the OSD with parameters from it.
|
||||||
|
|
||||||
|
Intended for use from startup scripts (i.e. from systemd units).
|
||||||
|
|
||||||
|
## pre-exec
|
||||||
|
|
||||||
|
`vitastor-disk pre-exec <device>`
|
||||||
|
|
||||||
|
Read Vitastor OSD superblock from `<device>` and perform pre-start checks for the OSD.
|
||||||
|
|
||||||
|
For now, this only checks that device cache is in write-through mode if fsync is disabled.
|
||||||
|
|
||||||
|
Intended for use from startup scripts (i.e. from systemd units).
|
||||||
|
|
||||||
|
## dump-journal
|
||||||
|
|
||||||
|
`vitastor-disk dump-journal [OPTIONS] <journal_file> <journal_block_size> <offset> <size>`
|
||||||
|
|
||||||
|
Dump journal in human-readable or JSON (if `--json` is specified) format.
|
||||||
|
|
||||||
|
Options:
|
||||||
|
|
||||||
|
```
|
||||||
|
--all Scan the whole journal area for entries and dump them, even outdated ones
|
||||||
|
--json Dump journal in JSON format
|
||||||
|
--format entries (Default) Dump actual journal entries as an array, without data
|
||||||
|
--format data Same as "entries", but also include small write data
|
||||||
|
--format blocks Dump as an array of journal blocks each containing array of entries
|
||||||
|
```
|
||||||
|
|
||||||
|
## write-journal
|
||||||
|
|
||||||
|
`vitastor-disk write-journal <journal_file> <journal_block_size> <bitmap_size> <offset> <size>`
|
||||||
|
|
||||||
|
Write journal from JSON taken from standard input in the same format as produced by
|
||||||
|
`dump-journal --json --format data`.
|
||||||
|
|
||||||
|
## dump-meta
|
||||||
|
|
||||||
|
`vitastor-disk dump-meta <meta_file> <meta_block_size> <offset> <size>`
|
||||||
|
|
||||||
|
Dump metadata in JSON format.
|
||||||
|
|
||||||
|
## write-meta
|
||||||
|
|
||||||
|
`vitastor-disk write-meta <meta_file> <offset> <size>`
|
||||||
|
|
||||||
|
Write metadata from JSON taken from standard input in the same format as produced by `dump-meta`.
|
||||||
|
|
||||||
|
## simple-offsets
|
||||||
|
|
||||||
|
`vitastor-disk simple-offsets <device>`
|
||||||
|
|
||||||
|
Calculate offsets for old simple&stupid (no superblock) OSD deployment.
|
||||||
|
|
||||||
|
Options (see also [Cluster-Wide Disk Layout Parameters](../config/layout-cluster.en.md)):
|
||||||
|
|
||||||
|
```
|
||||||
|
--object_size 128k Set blockstore block size
|
||||||
|
--bitmap_granularity 4k Set bitmap granularity
|
||||||
|
--journal_size 32M Set journal size
|
||||||
|
--device_block_size 4k Set device block size
|
||||||
|
--journal_offset 0 Set journal offset
|
||||||
|
--device_size 0 Set device size
|
||||||
|
--format text Result format: json, options, env, or text
|
||||||
|
```
|
262
docs/usage/disk.ru.md
Normal file
262
docs/usage/disk.ru.md
Normal file
@@ -0,0 +1,262 @@
|
|||||||
|
[Документация](../../README-ru.md#документация) → Использование → Инструмент управления дисками
|
||||||
|
|
||||||
|
-----
|
||||||
|
|
||||||
|
[Read in English](disk.en.md)
|
||||||
|
|
||||||
|
# Инструмент управления дисками
|
||||||
|
|
||||||
|
vitastor-disk - инструмент командной строки для управления дисками Vitastor OSD.
|
||||||
|
|
||||||
|
Поддерживаются следующие команды:
|
||||||
|
|
||||||
|
- [prepare](#prepare)
|
||||||
|
- [upgrade-simple](#upgrade-simple)
|
||||||
|
- [resize](#resize)
|
||||||
|
- [start/stop/restart/enable/disable](#start/stop/restart/enable/disable)
|
||||||
|
- [purge](#purge)
|
||||||
|
- [read-sb](#read-sb)
|
||||||
|
- [write-sb](#write-sb)
|
||||||
|
- [udev](#udev)
|
||||||
|
- [exec-osd](#exec-osd)
|
||||||
|
- [pre-exec](#pre-exec)
|
||||||
|
- Для отладки:
|
||||||
|
- [dump-journal](#dump-journal)
|
||||||
|
- [write-journal](#write-journal)
|
||||||
|
- [dump-meta](#dump-meta)
|
||||||
|
- [write-meta](#write-meta)
|
||||||
|
- [simple-offsets](#simple-offsets)
|
||||||
|
|
||||||
|
## prepare
|
||||||
|
|
||||||
|
`vitastor-disk prepare [OPTIONS] [devices...]`
|
||||||
|
|
||||||
|
Подготовить диск(и) для OSD Vitastor.
|
||||||
|
|
||||||
|
У команды есть 2 режима. В первом режиме вы указываете список устройств `<devices>`,
|
||||||
|
которые должны быть целыми дисками (не разделами). На них автоматически создаются
|
||||||
|
разделы и инициализируются OSD.
|
||||||
|
|
||||||
|
Во втором режиме вместо списка устройств вы указываете пути к отдельным устройствам
|
||||||
|
`--data_device`, `--journal_device` и/или `--meta_device`, которые должны быть
|
||||||
|
уже существующими GPT-разделами. В этом случае инициализируется ровно один OSD.
|
||||||
|
|
||||||
|
Команде требуются утилиты `vitastor-cli`, `wipefs`, `sfdisk` и `partprobe` (из состава parted).
|
||||||
|
|
||||||
|
Опции для автоматического режима:
|
||||||
|
|
||||||
|
```
|
||||||
|
--osd_per_disk <N>
|
||||||
|
Создавать по несколько (<N>) OSD на каждом диске (по умолчанию 1)
|
||||||
|
--hybrid
|
||||||
|
Инициализировать гибридные (HDD+SSD) OSD на указанных дисках. SSD будут
|
||||||
|
использованы для журналов и метаданных, а HDD - для данных. Разделы для журналов
|
||||||
|
и метаданных будут созданы автоматически. Является ли диск SSD или HDD, определяется
|
||||||
|
по флагу `/sys/block/.../queue/rotational`. В гибридном режиме по умолчанию
|
||||||
|
используется размер объекта 1 МБ вместо 128 КБ, размер журнала 1 ГБ вместо 32 МБ
|
||||||
|
и включённый throttle_small_writes.
|
||||||
|
--disable_data_fsync auto
|
||||||
|
Отключать кэш и fsync-и для устройств данных. (1/yes/true = да, по умолчанию автоопределение)
|
||||||
|
--disable_meta_fsync auto
|
||||||
|
Отключать кэш и fsync-и для журналов и метаданных (по умолчанию автоопределение)
|
||||||
|
--meta_reserve 2x,1G
|
||||||
|
В гибридном режиме для метаданных выделяется больше места, чем нужно на самом
|
||||||
|
деле, чтобы оставить запас под будущее расширение. По умолчанию выделяется
|
||||||
|
в 2 раза больше места, и не менее 1 ГБ. Чтобы изменить это поведение,
|
||||||
|
воспользуйтесь данной опцией.
|
||||||
|
--max_other 10%
|
||||||
|
Использовать диски под данные OSD, даже если на них уже есть не-Vitastor-овые
|
||||||
|
разделы, но только в случае, если они занимают не более данного процента диска.
|
||||||
|
```
|
||||||
|
|
||||||
|
Опции для режима одного OSD:
|
||||||
|
|
||||||
|
```
|
||||||
|
--data_device <DEV> Использовать раздел <DEV> для данных
|
||||||
|
--meta_device <DEV> Использовать раздел <DEV> для метаданных (опционально)
|
||||||
|
--journal_device <DEV> Использовать раздел <DEV> для журнала (опционально)
|
||||||
|
--disable_data_fsync 0 Отключить кэш и fsync устройства данных (по умолчанию нет)
|
||||||
|
--disable_meta_fsync 0 Отключить кэш и fsync метаданных (по умолчанию нет)
|
||||||
|
--disable_journal_fsync 0 Отключить кэш и fsync журнала (по умолчанию нет)
|
||||||
|
--force Пропустить проверки разделов (на пустоту и т.п.)
|
||||||
|
```
|
||||||
|
|
||||||
|
Опции для обоих режимов:
|
||||||
|
|
||||||
|
```
|
||||||
|
--journal_size 1G/32M Задать размер журнала (области или раздела журнала)
|
||||||
|
--block_size 1M/128k Задать размер объекта хранилища
|
||||||
|
--bitmap_granularity 4k Задать гранулярность битовых карт
|
||||||
|
--data_device_block 4k Задать размер блока устройства данных
|
||||||
|
--meta_device_block 4k Задать размер блока метаданных
|
||||||
|
--journal_device_block 4k Задать размер блока журнала
|
||||||
|
```
|
||||||
|
|
||||||
|
Настройка [immediate_commit](../config/layout-cluster.ru.md#immediate_commit)
|
||||||
|
автоматически выводится из опций отключения кэша - она устанавливается в "all", если кэш
|
||||||
|
отключён на всех устройствах, и в "small", если он отключён только на устройстве журнала.
|
||||||
|
|
||||||
|
Когда fsync данных/метаданных/журнала отключён, скрипты запуска OSD автоматически
|
||||||
|
проверяют состояние кэша диска и стараются его отключить для SATA/SAS дисков. Если
|
||||||
|
это не удаётся, в системный журнал выводится предупреждение.
|
||||||
|
|
||||||
|
Вы можете передать данной команде и некоторые другие опции OSD в качестве аргументов
|
||||||
|
и они тоже будут сохранены в суперблок: max_write_iodepth, max_write_iodepth, min_flusher_count,
|
||||||
|
max_flusher_count, inmemory_metadata, inmemory_journal, journal_sector_buffer_count,
|
||||||
|
journal_no_same_sector_overwrites, throttle_small_writes, throttle_target_iops,
|
||||||
|
throttle_target_mbs, throttle_target_parallelism, throttle_threshold_us.
|
||||||
|
Читайте об этих параметрах подробнее в разделе [Изменяемые параметры OSD](../config/osd.ru.md).
|
||||||
|
|
||||||
|
## upgrade-simple
|
||||||
|
|
||||||
|
`vitastor-disk upgrade-simple <UNIT_FILE|OSD_NUMBER>`
|
||||||
|
|
||||||
|
Обновить OSD, созданный старыми (0.7.1 и старее) скриптами `make-osd.sh` и `make-osd-hybrid.js`.
|
||||||
|
|
||||||
|
Добавляет суперблок на разделы OSD, отключает старый сервис `vitastor-osdN` и заменяет его на `vitastor-osd@N`.
|
||||||
|
|
||||||
|
Можно вызывать, указывая либо номер OSD, либо путь к файлу сервиса `UNIT_FILE`, но он обязан
|
||||||
|
иметь вид `/etc/systemd/system/vitastor-osd<OSD_NUMBER>.service`.
|
||||||
|
|
||||||
|
Имейте в виду, что процедура обновления не атомарна и при прерывании может уничтожить данные OSD,
|
||||||
|
так что обновляйте ваши OSD по очереди.
|
||||||
|
|
||||||
|
Команде требуется утилита `sfdisk`.
|
||||||
|
|
||||||
|
## resize
|
||||||
|
|
||||||
|
`vitastor-disk resize <ALL_OSD_PARAMETERS> <NEW_LAYOUT> [--iodepth 32]`
|
||||||
|
|
||||||
|
Изменить размер области данных и/или переместить журнал и метаданные.
|
||||||
|
|
||||||
|
В `ALL_OSD_PARAMETERS` нужно указать все относящиеся к диску параметры OSD
|
||||||
|
из суперблока OSD или из файла сервиса systemd (в старых версиях).
|
||||||
|
|
||||||
|
В `NEW_LAYOUT` нужно указать новые параметры расположения данных:
|
||||||
|
|
||||||
|
```
|
||||||
|
--new_data_offset РАЗМЕР сдвинуть начало области данных на РАЗМЕР байт
|
||||||
|
--new_data_len РАЗМЕР изменить размер области данных до РАЗМЕР байт
|
||||||
|
--new_meta_device ПУТЬ использовать ПУТЬ как новое устройство метаданных
|
||||||
|
--new_meta_offset РАЗМЕР разместить новые метаданные по смещению РАЗМЕР байт
|
||||||
|
--new_meta_len РАЗМЕР сделать новые метаданные размером РАЗМЕР байт
|
||||||
|
--new_journal_device ПУТЬ использовать ПУТЬ как новое устройство журнала
|
||||||
|
--new_journal_offset РАЗМЕР разместить новый журнал по смещению РАЗМЕР байт
|
||||||
|
--new_journal_len РАЗМЕР сделать новый журнал размером РАЗМЕР байт
|
||||||
|
```
|
||||||
|
|
||||||
|
РАЗМЕР может быть указан с суффиксами k/m/g/t. Если любой из новых параметров
|
||||||
|
расположения не указан, он принимается равным старому значению.
|
||||||
|
|
||||||
|
## start/stop/restart/enable/disable
|
||||||
|
|
||||||
|
`vitastor-disk start|stop|restart|enable|disable [--now] <device> [device2 device3 ...]`
|
||||||
|
|
||||||
|
Команды управления OSD по путям дисков через systemd.
|
||||||
|
|
||||||
|
Команды транслируются `systemctl` с сервисами `vitastor-osd@<num>` в виде аргументов.
|
||||||
|
|
||||||
|
Когда к командам включения/выключения добавляется параметр `--now`, OSD также сразу
|
||||||
|
запускаются/останавливаются.
|
||||||
|
|
||||||
|
## purge
|
||||||
|
|
||||||
|
`vitastor-disk purge [--force] [--allow-data-loss] <device> [device2 device3 ...]`
|
||||||
|
|
||||||
|
Удалить OSD на заданном диске/дисках. Использует `vitastor-cli rm-osd` для проверки
|
||||||
|
возможности удаления без потери данных и для удаления OSD из etcd. Опции `--force`
|
||||||
|
и `--allow-data-loss` служат для обхода данной защиты в случае необходимости.
|
||||||
|
|
||||||
|
Команде требуются утилиты `vitastor-cli`, `sfdisk` и `partprobe` (из состава parted).
|
||||||
|
|
||||||
|
## read-sb
|
||||||
|
|
||||||
|
`vitastor-disk read-sb [--force] <device>`
|
||||||
|
|
||||||
|
Прочитать суперблок OSD с диска `<device>` и вывести его в формате JSON.
|
||||||
|
|
||||||
|
Опция `--force` позволяет читать суперблок, даже если он считается некорректным
|
||||||
|
из-за ошибок валидации.
|
||||||
|
|
||||||
|
## write-sb
|
||||||
|
|
||||||
|
`vitastor-disk write-sb <device>`
|
||||||
|
|
||||||
|
Прочитать JSON со стандартного ввода и записать его в суперблок OSD на диск `<device>`.
|
||||||
|
|
||||||
|
## udev
|
||||||
|
|
||||||
|
`vitastor-disk udev <device>`
|
||||||
|
|
||||||
|
Прочитать суперблок OSD с диска `<device>` и вывести переменные для udev.
|
||||||
|
|
||||||
|
## exec-osd
|
||||||
|
|
||||||
|
`vitastor-disk exec-osd <device>`
|
||||||
|
|
||||||
|
Прочитать суперблок OSD с диска `<device>` и запустить исполняемый файл OSD с параметрами оттуда.
|
||||||
|
|
||||||
|
Команда предназначена для использования из скриптов запуска (например, из сервисов systemd).
|
||||||
|
|
||||||
|
## pre-exec
|
||||||
|
|
||||||
|
`vitastor-disk pre-exec <device>`
|
||||||
|
|
||||||
|
Прочитать суперблок OSD с диска `<device>` и провести проверки OSD перед запуском.
|
||||||
|
|
||||||
|
На данный момент только отключает кэш диска или проверяет, что он отключён, если в параметрах
|
||||||
|
OSD отключены fsync-и.
|
||||||
|
|
||||||
|
Команда предназначена для использования из скриптов запуска (например, из сервисов systemd).
|
||||||
|
|
||||||
|
## dump-journal
|
||||||
|
|
||||||
|
`vitastor-disk dump-journal [OPTIONS] <journal_file> <journal_block_size> <offset> <size>`
|
||||||
|
|
||||||
|
Вывести журнал в человекочитаемом или в JSON (с опцией `--json`) виде.
|
||||||
|
|
||||||
|
Опции:
|
||||||
|
|
||||||
|
```
|
||||||
|
--all Просканировать всю область журнала и вывести даже старые записи
|
||||||
|
--json Вывести журнал в формате JSON
|
||||||
|
--format entries (По умолчанию) Вывести только актуальные записи журнала без данных
|
||||||
|
--format data Вывести только актуальные записи журнала с данными
|
||||||
|
--format blocks Вывести массив блоков журнала, а в каждом массив актуальных записей без данных
|
||||||
|
```
|
||||||
|
|
||||||
|
## write-journal
|
||||||
|
|
||||||
|
`vitastor-disk write-journal <journal_file> <journal_block_size> <bitmap_size> <offset> <size>`
|
||||||
|
|
||||||
|
Записать журнал из JSON со стандартного ввода в формате, аналогичном `dump-journal --json --format data`.
|
||||||
|
|
||||||
|
## dump-meta
|
||||||
|
|
||||||
|
`vitastor-disk dump-meta <meta_file> <meta_block_size> <offset> <size>`
|
||||||
|
|
||||||
|
Вывести метаданные в формате JSON.
|
||||||
|
|
||||||
|
## write-meta
|
||||||
|
|
||||||
|
`vitastor-disk write-meta <meta_file> <offset> <size>`
|
||||||
|
|
||||||
|
Записать метаданные из JSON со стандартного ввода в формате, аналогичном `dump-meta`.
|
||||||
|
|
||||||
|
## simple-offsets
|
||||||
|
|
||||||
|
`vitastor-disk simple-offsets <device>`
|
||||||
|
|
||||||
|
Рассчитать смещения для старого ("простого и тупого") создания OSD на диске (без суперблока).
|
||||||
|
|
||||||
|
Опции (см. также [Дисковые параметры уровня кластера](../config/layout-cluster.ru.md)):
|
||||||
|
|
||||||
|
```
|
||||||
|
--object_size 128k Размер блока хранилища
|
||||||
|
--bitmap_granularity 4k Гранулярность битовых карт
|
||||||
|
--journal_size 32M Размер журнала
|
||||||
|
--device_block_size 4k Размер блока устройства
|
||||||
|
--journal_offset 0 Смещение журнала
|
||||||
|
--device_size 0 Размер устройства
|
||||||
|
--format text Формат результата: json, options, env или text
|
||||||
|
```
|
@@ -46,3 +46,40 @@ qemu-img convert -f qcow2 debian10.qcow2 -p -O raw 'vitastor:etcd_host=192.168.7
|
|||||||
|
|
||||||
You can also specify `:pool=<POOL>:inode=<INODE>:size=<SIZE>` instead of `:image=<IMAGE>`
|
You can also specify `:pool=<POOL>:inode=<INODE>:size=<SIZE>` instead of `:image=<IMAGE>`
|
||||||
if you don't want to use inode metadata.
|
if you don't want to use inode metadata.
|
||||||
|
|
||||||
|
### Exporting snapshots
|
||||||
|
|
||||||
|
Starting with 0.8.4, you can also export individual layers (snapshot diffs) using `qemu-img`.
|
||||||
|
|
||||||
|
Suppose you have an image `testimg` and a snapshot `testimg@0` created with `vitastor-cli snap-create testimg@0`.
|
||||||
|
|
||||||
|
Then you can export the `testimg@0` snapshot and the data written to `testimg` after creating
|
||||||
|
the snapshot separately using the following commands (key points are using `skip-parents=1` and
|
||||||
|
`-B backing_file` option):
|
||||||
|
|
||||||
|
```
|
||||||
|
qemu-img convert -f raw 'vitastor:etcd_host=192.168.7.2\:2379/v3:image=testimg@0' \
|
||||||
|
-O qcow2 testimg_0.qcow2
|
||||||
|
|
||||||
|
qemu-img convert -f raw 'vitastor:etcd_host=192.168.7.2\:2379/v3:image=testimg:skip-parents=1' \
|
||||||
|
-O qcow2 -o 'cluster_size=4k' -B testimg_0.qcow2 testimg.qcow2
|
||||||
|
```
|
||||||
|
|
||||||
|
In fact, with `cluster_size=4k` any QCOW2 file can be used instead `-B testimg_0.qcow2`, even an empty one.
|
||||||
|
|
||||||
|
QCOW2 `cluster_size=4k` option is required if you want `testimg.qcow2` to contain only the data
|
||||||
|
overwritten **exactly** in the child layer. With the default 64 KB QCOW2 cluster size you'll
|
||||||
|
get a bit of extra data from parent layers, i.e. a 4 KB overwrite will result in `testimg.qcow2`
|
||||||
|
containing 64 KB of data. And this extra data will be taken by `qemu-img` from the file passed
|
||||||
|
in `-B` option, so you really need 4 KB cluster if you use an empty image in `-B`.
|
||||||
|
|
||||||
|
After this procedure you'll get two chained QCOW2 images. To detach `testimg.qcow2` from
|
||||||
|
its parent, run:
|
||||||
|
|
||||||
|
```
|
||||||
|
qemu-img rebase -u -b '' testimg.qcow2
|
||||||
|
```
|
||||||
|
|
||||||
|
This can be used for backups. Just note that exporting an image that is currently being written to
|
||||||
|
is of course unsafe and doesn't produce a consistent result, so only export snapshots if you do this
|
||||||
|
on a live VM.
|
||||||
|
@@ -50,3 +50,40 @@ qemu-img convert -f qcow2 debian10.qcow2 -p -O raw 'vitastor:etcd_host=10.115.0.
|
|||||||
|
|
||||||
Если вы не хотите обращаться к образу по имени, вместо `:image=<IMAGE>` можно указать номер пула, номер инода и размер:
|
Если вы не хотите обращаться к образу по имени, вместо `:image=<IMAGE>` можно указать номер пула, номер инода и размер:
|
||||||
`:pool=<POOL>:inode=<INODE>:size=<SIZE>`.
|
`:pool=<POOL>:inode=<INODE>:size=<SIZE>`.
|
||||||
|
|
||||||
|
### Экспорт снимков
|
||||||
|
|
||||||
|
Начиная с 0.8.4 вы можете экспортировать отдельные слои (изменения в снимках) с помощью `qemu-img`.
|
||||||
|
|
||||||
|
Допустим, что у вас есть образ `testimg` и его снимок `testimg@0`, созданный с помощью `vitastor-cli snap-create testimg@0`.
|
||||||
|
|
||||||
|
Тогда вы можете выгрузить снимок `testimg@0` и данные, изменённые в `testimg` после создания снимка, отдельно,
|
||||||
|
с помощью следующих команд (ключевые моменты - использование `skip-parents=1` и опции `-B backing_file.qcow2`):
|
||||||
|
|
||||||
|
```
|
||||||
|
qemu-img convert -f raw 'vitastor:etcd_host=192.168.7.2\:2379/v3:image=testimg@0' \
|
||||||
|
-O qcow2 testimg_0.qcow2
|
||||||
|
|
||||||
|
qemu-img convert -f raw 'vitastor:etcd_host=192.168.7.2\:2379/v3:image=testimg:skip-parents=1' \
|
||||||
|
-O qcow2 -o 'cluster_size=4k' -B testimg_0.qcow2 testimg.qcow2
|
||||||
|
```
|
||||||
|
|
||||||
|
На самом деле, с `cluster_size=4k` вместо `-B testimg_0.qcow2` можно использовать любой qcow2-файл,
|
||||||
|
даже пустой.
|
||||||
|
|
||||||
|
Опция QCOW2 `cluster_size=4k` нужна, если вы хотите, чтобы `testimg.qcow2` содержал **в точности**
|
||||||
|
данные, перезаписанные в дочернем слое. С размером кластера QCOW2 по умолчанию, составляющим 64 КБ,
|
||||||
|
вы получите немного "лишних" данных из родительских слоёв - перезапись 4 КБ будет приводить к тому,
|
||||||
|
что в `testimg.qcow2` будет появляться 64 КБ данных. Причём "лишние" данные qemu-img будет брать
|
||||||
|
как раз из файла, указанного в опции `-B`, так что если там указан пустой образ, кластер обязан быть 4 КБ.
|
||||||
|
|
||||||
|
После данной процедуры вы получите два QCOW2-образа, связанных в цепочку. Чтобы "отцепить" образ
|
||||||
|
`testimg.qcow2` от базового, выполните:
|
||||||
|
|
||||||
|
```
|
||||||
|
qemu-img rebase -u -b '' testimg.qcow2
|
||||||
|
```
|
||||||
|
|
||||||
|
Это можно использовать для резервного копирования. Только помните, что экспортировать образ, в который
|
||||||
|
в то же время идёт запись, небезопасно - результат чтения не будет целостным. Так что если вы работаете
|
||||||
|
с активными виртуальными машинами, экспортируйте только их снимки, но не сам образ.
|
||||||
|
2
json11
2
json11
Submodule json11 updated: 52a3af664f...fd37016cf8
7
mon/90-vitastor.rules
Normal file
7
mon/90-vitastor.rules
Normal file
@@ -0,0 +1,7 @@
|
|||||||
|
SUBSYSTEM=="block", ENV{ID_PART_ENTRY_TYPE}=="e7009fac-a5a1-4d72-af72-53de13059903", \
|
||||||
|
OWNER="vitastor", GROUP="vitastor", \
|
||||||
|
IMPORT{program}="/usr/bin/vitastor-disk udev $devnode", \
|
||||||
|
SYMLINK+="vitastor/$env{VITASTOR_ALIAS}"
|
||||||
|
|
||||||
|
ENV{VITASTOR_OSD_NUM}!="", ACTION=="add", RUN{program}+="/usr/bin/systemctl enable --now vitastor-osd@$env{VITASTOR_OSD_NUM}"
|
||||||
|
ENV{VITASTOR_OSD_NUM}!="", ACTION=="remove", RUN{program}+="/usr/bin/systemctl disable --now vitastor-osd@$env{VITASTOR_OSD_NUM}"
|
@@ -21,7 +21,7 @@ function add_pg_history(new_pg_history, new_pg, prev_pgs, prev_pg_history, old_p
|
|||||||
{
|
{
|
||||||
for (const pg of oh.osd_sets)
|
for (const pg of oh.osd_sets)
|
||||||
{
|
{
|
||||||
nh.osd_sets[pg.join(' ')] = pg;
|
nh.osd_sets[pg.join(' ')] = pg.map(osd_num => Number(osd_num));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (oh && oh.all_peers && oh.all_peers.length)
|
if (oh && oh.all_peers && oh.all_peers.length)
|
||||||
@@ -43,16 +43,16 @@ function finish_pg_history(merged_history)
|
|||||||
merged_history.all_peers = Object.values(merged_history.all_peers);
|
merged_history.all_peers = Object.values(merged_history.all_peers);
|
||||||
}
|
}
|
||||||
|
|
||||||
function scale_pg_count(prev_pgs, prev_pg_history, new_pg_history, new_pg_count)
|
function scale_pg_count(prev_pgs, real_prev_pgs, prev_pg_history, new_pg_history, new_pg_count)
|
||||||
{
|
{
|
||||||
const old_pg_count = prev_pgs.length;
|
const old_pg_count = real_prev_pgs.length;
|
||||||
// Add all possibly intersecting PGs to the history of new PGs
|
// Add all possibly intersecting PGs to the history of new PGs
|
||||||
if (!(new_pg_count % old_pg_count))
|
if (!(new_pg_count % old_pg_count))
|
||||||
{
|
{
|
||||||
// New PG count is a multiple of old PG count
|
// New PG count is a multiple of old PG count
|
||||||
for (let i = 0; i < new_pg_count; i++)
|
for (let i = 0; i < new_pg_count; i++)
|
||||||
{
|
{
|
||||||
add_pg_history(new_pg_history, i, prev_pgs, prev_pg_history, i % old_pg_count);
|
add_pg_history(new_pg_history, i, real_prev_pgs, prev_pg_history, i % old_pg_count);
|
||||||
finish_pg_history(new_pg_history[i]);
|
finish_pg_history(new_pg_history[i]);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -64,7 +64,7 @@ function scale_pg_count(prev_pgs, prev_pg_history, new_pg_history, new_pg_count)
|
|||||||
{
|
{
|
||||||
for (let j = 0; j < mul; j++)
|
for (let j = 0; j < mul; j++)
|
||||||
{
|
{
|
||||||
add_pg_history(new_pg_history, i, prev_pgs, prev_pg_history, i+j*new_pg_count);
|
add_pg_history(new_pg_history, i, real_prev_pgs, prev_pg_history, i+j*new_pg_count);
|
||||||
}
|
}
|
||||||
finish_pg_history(new_pg_history[i]);
|
finish_pg_history(new_pg_history[i]);
|
||||||
}
|
}
|
||||||
@@ -76,7 +76,7 @@ function scale_pg_count(prev_pgs, prev_pg_history, new_pg_history, new_pg_count)
|
|||||||
let merged_history = {};
|
let merged_history = {};
|
||||||
for (let i = 0; i < old_pg_count; i++)
|
for (let i = 0; i < old_pg_count; i++)
|
||||||
{
|
{
|
||||||
add_pg_history(merged_history, 1, prev_pgs, prev_pg_history, i);
|
add_pg_history(merged_history, 1, real_prev_pgs, prev_pg_history, i);
|
||||||
}
|
}
|
||||||
finish_pg_history(merged_history[1]);
|
finish_pg_history(merged_history[1]);
|
||||||
for (let i = 0; i < new_pg_count; i++)
|
for (let i = 0; i < new_pg_count; i++)
|
||||||
@@ -90,15 +90,15 @@ function scale_pg_count(prev_pgs, prev_pg_history, new_pg_history, new_pg_count)
|
|||||||
new_pg_history[i] = null;
|
new_pg_history[i] = null;
|
||||||
}
|
}
|
||||||
// Just for the lp_solve optimizer - pick a "previous" PG for each "new" one
|
// Just for the lp_solve optimizer - pick a "previous" PG for each "new" one
|
||||||
if (old_pg_count < new_pg_count)
|
if (prev_pgs.length < new_pg_count)
|
||||||
{
|
{
|
||||||
for (let i = old_pg_count; i < new_pg_count; i++)
|
for (let i = prev_pgs.length; i < new_pg_count; i++)
|
||||||
{
|
{
|
||||||
prev_pgs[i] = prev_pgs[i % old_pg_count];
|
prev_pgs[i] = prev_pgs[i % prev_pgs.length];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else if (old_pg_count > new_pg_count)
|
else if (prev_pgs.length > new_pg_count)
|
||||||
{
|
{
|
||||||
prev_pgs.splice(new_pg_count, old_pg_count-new_pg_count);
|
prev_pgs.splice(new_pg_count, prev_pgs.length-new_pg_count);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@@ -50,7 +50,8 @@ async function lp_solve(text)
|
|||||||
return { score, vars };
|
return { score, vars };
|
||||||
}
|
}
|
||||||
|
|
||||||
async function optimize_initial({ osd_tree, pg_count, pg_size = 3, pg_minsize = 2, max_combinations = 10000, parity_space = 1, ordered = false })
|
async function optimize_initial({ osd_tree, pg_count, pg_size = 3, pg_minsize = 2, hier_sizes = null,
|
||||||
|
max_combinations = 10000, parity_space = 1, ordered = false, seq_layout = false })
|
||||||
{
|
{
|
||||||
if (!pg_count || !osd_tree)
|
if (!pg_count || !osd_tree)
|
||||||
{
|
{
|
||||||
@@ -58,7 +59,7 @@ async function optimize_initial({ osd_tree, pg_count, pg_size = 3, pg_minsize =
|
|||||||
}
|
}
|
||||||
const all_weights = Object.assign({}, ...Object.values(osd_tree));
|
const all_weights = Object.assign({}, ...Object.values(osd_tree));
|
||||||
const total_weight = Object.values(all_weights).reduce((a, c) => Number(a) + Number(c), 0);
|
const total_weight = Object.values(all_weights).reduce((a, c) => Number(a) + Number(c), 0);
|
||||||
const all_pgs = Object.values(random_combinations(osd_tree, pg_size, max_combinations, parity_space > 1));
|
const all_pgs = Object.values(random_hier_combinations(osd_tree, hier_sizes || [ pg_size, 1 ], max_combinations, parity_space > 1, seq_layout));
|
||||||
const pg_per_osd = {};
|
const pg_per_osd = {};
|
||||||
for (const pg of all_pgs)
|
for (const pg of all_pgs)
|
||||||
{
|
{
|
||||||
@@ -216,39 +217,45 @@ function calc_intersect_weights(old_pg_size, pg_size, pg_count, prev_weights, al
|
|||||||
return move_weights;
|
return move_weights;
|
||||||
}
|
}
|
||||||
|
|
||||||
function add_valid_previous(osd_tree, prev_weights, all_pgs)
|
function build_parent_per_leaf(osd_tree, res = {}, parents = [])
|
||||||
|
{
|
||||||
|
for (const item in osd_tree)
|
||||||
|
{
|
||||||
|
if (osd_tree[item] instanceof Object)
|
||||||
|
build_parent_per_leaf(osd_tree[item], res, [ ...parents, item ]);
|
||||||
|
else
|
||||||
|
res[item] = parents;
|
||||||
|
}
|
||||||
|
return res;
|
||||||
|
}
|
||||||
|
|
||||||
|
function add_valid_previous(osd_tree, prev_weights, all_pgs, hier_sizes)
|
||||||
{
|
{
|
||||||
// Add previous combinations that are still valid
|
// Add previous combinations that are still valid
|
||||||
const hosts = Object.keys(osd_tree).sort();
|
const parent_per_osd = build_parent_per_leaf(osd_tree);
|
||||||
const host_per_osd = {};
|
|
||||||
for (const host in osd_tree)
|
|
||||||
{
|
|
||||||
for (const osd in osd_tree[host])
|
|
||||||
{
|
|
||||||
host_per_osd[osd] = host;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
skip_pg: for (const pg_name in prev_weights)
|
skip_pg: for (const pg_name in prev_weights)
|
||||||
{
|
{
|
||||||
const seen_hosts = {};
|
const seen = [];
|
||||||
const pg = pg_name.substr(3).split(/_/);
|
const pg = pg_name.substr(3).split(/_/);
|
||||||
for (const osd of pg)
|
for (const osd of pg)
|
||||||
{
|
{
|
||||||
if (!host_per_osd[osd] || seen_hosts[host_per_osd[osd]])
|
if (!parent_per_osd[osd])
|
||||||
{
|
|
||||||
continue skip_pg;
|
continue skip_pg;
|
||||||
|
for (let i = 0; i < parent_per_osd[osd].length; i++)
|
||||||
|
{
|
||||||
|
seen[parent_per_osd[osd][i]]++;
|
||||||
|
if (seen[parent_per_osd[osd][i]] > hier_sizes[i])
|
||||||
|
continue skip_pg;
|
||||||
}
|
}
|
||||||
seen_hosts[host_per_osd[osd]] = true;
|
|
||||||
}
|
}
|
||||||
if (!all_pgs[pg_name])
|
if (!all_pgs[pg_name])
|
||||||
{
|
|
||||||
all_pgs[pg_name] = pg;
|
all_pgs[pg_name] = pg;
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Try to minimize data movement
|
// Try to minimize data movement
|
||||||
async function optimize_change({ prev_pgs: prev_int_pgs, osd_tree, pg_size = 3, pg_minsize = 2, max_combinations = 10000, parity_space = 1, ordered = false })
|
async function optimize_change({ prev_pgs: prev_int_pgs, osd_tree, pg_size = 3, pg_minsize = 2,
|
||||||
|
hier_sizes = null, max_combinations = 10000, parity_space = 1, ordered = false, seq_layout = false })
|
||||||
{
|
{
|
||||||
if (!osd_tree)
|
if (!osd_tree)
|
||||||
{
|
{
|
||||||
@@ -273,10 +280,10 @@ async function optimize_change({ prev_pgs: prev_int_pgs, osd_tree, pg_size = 3,
|
|||||||
}
|
}
|
||||||
const old_pg_size = prev_int_pgs[0].length;
|
const old_pg_size = prev_int_pgs[0].length;
|
||||||
// Get all combinations
|
// Get all combinations
|
||||||
let all_pgs = random_combinations(osd_tree, pg_size, max_combinations, parity_space > 1);
|
let all_pgs = random_hier_combinations(osd_tree, hier_sizes || [ pg_size, 1 ], max_combinations, parity_space > 1, seq_layout);
|
||||||
if (old_pg_size == pg_size)
|
if (old_pg_size == pg_size)
|
||||||
{
|
{
|
||||||
add_valid_previous(osd_tree, prev_weights, all_pgs);
|
add_valid_previous(osd_tree, prev_weights, all_pgs, hier_sizes || [ pg_size, 1 ]);
|
||||||
}
|
}
|
||||||
all_pgs = Object.values(all_pgs);
|
all_pgs = Object.values(all_pgs);
|
||||||
const pg_per_osd = {};
|
const pg_per_osd = {};
|
||||||
@@ -502,41 +509,147 @@ function put_aligned_pgs(aligned_pgs, int_pgs, prev_int_pgs, keygen)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Convert multi-level osd_tree = { level: number|string, id?: string, size?: number, children?: osd_tree }[]
|
// Convert multi-level tree_node = { level: number|string, id?: string, size?: number, children?: tree_node[] }
|
||||||
// levels = { string: number }
|
// levels = { string: number }
|
||||||
// to a two-level osd_tree suitable for all_combinations()
|
// to a multi-level OSD tree suitable for random_hier_combinations()
|
||||||
function flatten_tree(osd_tree, levels, failure_domain_level, osd_level, domains = {}, i = { i: 1 })
|
// (or in case of just 2 levels - for all_combinations() / random_combinations())
|
||||||
|
//
|
||||||
|
// Example:
|
||||||
|
// tree_node = { level: 'dc', children: [ { level: 'rack', children: [ { level: 'host', children: [ { level: 'osd', size: 10 } ] } ] } ] }
|
||||||
|
// extract_levels = [ 'rack', 'osd' ]
|
||||||
|
// level_defs = { dc: 1, rack: 2, host: 3, osd: 4 }
|
||||||
|
//
|
||||||
|
// Result:
|
||||||
|
// { rack0: { osd1: 10 } }
|
||||||
|
function extract_tree_levels(tree_node, extract_levels, level_defs, new_tree = { idx: 1, items: {} })
|
||||||
{
|
{
|
||||||
osd_level = levels[osd_level] || osd_level;
|
const next_level = Number(level_defs[extract_levels[0]] || extract_levels[0]) || 0;
|
||||||
failure_domain_level = levels[failure_domain_level] || failure_domain_level;
|
const level_name = level_defs[extract_levels[0]] ? extract_levels[0] : 'l'+extract_levels[0]+'_';
|
||||||
for (const node of osd_tree)
|
const is_leaf = extract_levels.length == 1;
|
||||||
|
if ((level_defs[tree_node.level] || tree_node.level) >= next_level)
|
||||||
{
|
{
|
||||||
if ((levels[node.level] || node.level) < failure_domain_level)
|
if (!is_leaf)
|
||||||
{
|
{
|
||||||
flatten_tree(node.children||[], levels, failure_domain_level, osd_level, domains, i);
|
// Insert a (possibly fake) level
|
||||||
|
const nt = { idx: 1, items: {} };
|
||||||
|
new_tree.items[level_name+(new_tree.idx++)] = nt.items;
|
||||||
|
extract_tree_levels(tree_node, extract_levels.slice(1), level_defs, nt);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
domains['dom'+(i.i++)] = extract_osds([ node ], levels, osd_level);
|
// Insert a leaf node
|
||||||
|
const leaf_id = tree_node.id || (level_name+(new_tree.idx++));
|
||||||
|
new_tree.items[leaf_id] = tree_node.size;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return domains;
|
else
|
||||||
|
{
|
||||||
|
for (const child_node of tree_node.children||[])
|
||||||
|
{
|
||||||
|
extract_tree_levels(child_node, extract_levels, level_defs, new_tree);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return new_tree.items;
|
||||||
}
|
}
|
||||||
|
|
||||||
function extract_osds(osd_tree, levels, osd_level, osds = {})
|
// generate random PGs with hierarchical failure domains, i.e. for example 3 DC each with 2 HOSTS
|
||||||
|
// osd_tree = { level3_id: { level2_id: { level1_id: scalar_value } }, ... }
|
||||||
|
// osd_tree may contain arbitrary number of levels, but level count must be the same across the whole tree
|
||||||
|
// size_per_level = number of items to select on each level, for example [3, 2, 1].
|
||||||
|
// must have the same number of items as the osd_tree level count.
|
||||||
|
// count = PG count to generate
|
||||||
|
// ordered = don't treat (x,y) and (y,x) as equal
|
||||||
|
// seq_layout = true for the [DC1,DC1,DC2,DC2,DC3,DC3] layout, false for [DC1,DC2,DC3,DC1,DC2,DC3] layout
|
||||||
|
function random_hier_combinations(osd_tree, size_per_level, count, ordered, seq_layout)
|
||||||
{
|
{
|
||||||
for (const node of osd_tree)
|
let seed = 0x5f020e43;
|
||||||
|
const rng = () =>
|
||||||
{
|
{
|
||||||
if ((levels[node.level] || node.level) >= osd_level)
|
seed ^= seed << 13;
|
||||||
|
seed ^= seed >> 17;
|
||||||
|
seed ^= seed << 5;
|
||||||
|
return seed + 2147483648;
|
||||||
|
};
|
||||||
|
const get_max_level = (o) =>
|
||||||
|
{
|
||||||
|
let lvl = 0;
|
||||||
|
while (o instanceof Object)
|
||||||
{
|
{
|
||||||
osds[node.id] = node.size;
|
for (const k in o)
|
||||||
|
{
|
||||||
|
lvl++;
|
||||||
|
o = o[k];
|
||||||
|
break;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
else
|
return lvl;
|
||||||
|
};
|
||||||
|
const max_level = get_max_level(osd_tree);
|
||||||
|
const gen_pg = (select) =>
|
||||||
|
{
|
||||||
|
let pg = [ osd_tree ];
|
||||||
|
for (let level = 0; level < max_level; level++)
|
||||||
{
|
{
|
||||||
extract_osds(node.children||[], levels, osd_level, osds);
|
let npg = [];
|
||||||
|
for (let i = 0; i < pg.length; i++)
|
||||||
|
{
|
||||||
|
const keys = pg[i] instanceof Object ? Object.keys(pg[i]) : [];
|
||||||
|
const max_keys = keys.length < size_per_level[level] ? keys.length : size_per_level[level];
|
||||||
|
for (let j = 0; j < max_keys; j++)
|
||||||
|
{
|
||||||
|
const r = select(level, i, j, (ordered ? keys.length : (keys.length - (max_keys - j - 1))));
|
||||||
|
const el = pg[i][keys[r]] instanceof Object ? pg[i][keys[r]] : keys[r];
|
||||||
|
npg[seq_layout ? i*size_per_level[level]+j : j*pg.length+i] = el;
|
||||||
|
keys.splice(ordered ? r : 0, ordered ? 1 : (r+1));
|
||||||
|
}
|
||||||
|
for (let j = max_keys; j < size_per_level[level]; j++)
|
||||||
|
npg[seq_layout ? i*size_per_level[level]+j : j*pg.length+i] = NO_OSD;
|
||||||
|
}
|
||||||
|
pg = npg;
|
||||||
}
|
}
|
||||||
|
return pg;
|
||||||
|
};
|
||||||
|
const r = {};
|
||||||
|
// Generate random combinations including each OSD at least once
|
||||||
|
let has_next = true;
|
||||||
|
let ctr = [];
|
||||||
|
while (has_next)
|
||||||
|
{
|
||||||
|
let pg = gen_pg((level, i, j, n) =>
|
||||||
|
{
|
||||||
|
if (i == 0 && j == 0)
|
||||||
|
{
|
||||||
|
// Select a pre-determined OSD in the first position on each level
|
||||||
|
const r = ctr[level] == null || ctr[level][1] != n ? 0 : ctr[level][0];
|
||||||
|
ctr[level] = [ r, n ];
|
||||||
|
return r;
|
||||||
|
}
|
||||||
|
return rng() % n;
|
||||||
|
});
|
||||||
|
for (let i = ctr.length-1; i >= 0; i--)
|
||||||
|
{
|
||||||
|
ctr[i][0]++;
|
||||||
|
if (ctr[i][0] < ctr[i][1])
|
||||||
|
break;
|
||||||
|
else
|
||||||
|
ctr[i] = null;
|
||||||
|
}
|
||||||
|
has_next = ctr[0] != null;
|
||||||
|
const cyclic_pgs = [ pg ];
|
||||||
|
if (ordered)
|
||||||
|
for (let i = 1; i < pg.size; i++)
|
||||||
|
cyclic_pgs.push([ ...pg.slice(i), ...pg.slice(0, i) ]);
|
||||||
|
for (const pg of cyclic_pgs)
|
||||||
|
r['pg_'+pg.join('_')] = pg;
|
||||||
}
|
}
|
||||||
return osds;
|
// Generate purely random combinations
|
||||||
|
while (count > 0)
|
||||||
|
{
|
||||||
|
let pg = gen_pg((l, i, j, n) => rng() % n);
|
||||||
|
r['pg_'+pg.join('_')] = pg;
|
||||||
|
count--;
|
||||||
|
}
|
||||||
|
return r;
|
||||||
}
|
}
|
||||||
|
|
||||||
// ordered = don't treat (x,y) and (y,x) as equal
|
// ordered = don't treat (x,y) and (y,x) as equal
|
||||||
@@ -550,8 +663,8 @@ function random_combinations(osd_tree, pg_size, count, ordered)
|
|||||||
seed ^= seed << 5;
|
seed ^= seed << 5;
|
||||||
return seed + 2147483648;
|
return seed + 2147483648;
|
||||||
};
|
};
|
||||||
const hosts = Object.keys(osd_tree).sort();
|
|
||||||
const osds = Object.keys(osd_tree).reduce((a, c) => { a[c] = Object.keys(osd_tree[c]).sort(); return a; }, {});
|
const osds = Object.keys(osd_tree).reduce((a, c) => { a[c] = Object.keys(osd_tree[c]).sort(); return a; }, {});
|
||||||
|
const hosts = Object.keys(osd_tree).sort().filter(h => osds[h].length > 0);
|
||||||
const r = {};
|
const r = {};
|
||||||
// Generate random combinations including each OSD at least once
|
// Generate random combinations including each OSD at least once
|
||||||
for (let h = 0; h < hosts.length; h++)
|
for (let h = 0; h < hosts.length; h++)
|
||||||
@@ -752,11 +865,12 @@ module.exports = {
|
|||||||
pg_weights_space_efficiency,
|
pg_weights_space_efficiency,
|
||||||
pg_list_space_efficiency,
|
pg_list_space_efficiency,
|
||||||
pg_per_osd_space_efficiency,
|
pg_per_osd_space_efficiency,
|
||||||
flatten_tree,
|
extract_tree_levels,
|
||||||
|
|
||||||
lp_solve,
|
lp_solve,
|
||||||
make_int_pgs,
|
make_int_pgs,
|
||||||
align_pgs,
|
align_pgs,
|
||||||
random_combinations,
|
random_combinations,
|
||||||
|
random_hier_combinations,
|
||||||
all_combinations,
|
all_combinations,
|
||||||
};
|
};
|
||||||
|
110
mon/make-etcd
Executable file
110
mon/make-etcd
Executable file
@@ -0,0 +1,110 @@
|
|||||||
|
#!/usr/bin/node
|
||||||
|
// Simple systemd unit generator for etcd
|
||||||
|
// Copyright (c) Vitaliy Filippov, 2019+
|
||||||
|
// License: MIT
|
||||||
|
|
||||||
|
// USAGE:
|
||||||
|
// 1) Put the same etcd_address into /etc/vitastor/vitastor.conf on all monitor nodes
|
||||||
|
// 2) Run ./make-etcd.js. It will create the etcd service on one of specified IPs
|
||||||
|
|
||||||
|
const child_process = require('child_process');
|
||||||
|
const fs = require('fs');
|
||||||
|
const os = require('os');
|
||||||
|
|
||||||
|
run().catch(e => { console.error(e); process.exit(1); });
|
||||||
|
|
||||||
|
async function run()
|
||||||
|
{
|
||||||
|
const config_path = process.argv[2] || '/etc/vitastor/vitastor.conf';
|
||||||
|
if (config_path == '-h' || config_path == '--help')
|
||||||
|
{
|
||||||
|
console.log(
|
||||||
|
'Initialize systemd etcd service for Vitastor\n'+
|
||||||
|
'(c) Vitaliy Filippov, 2019+ (MIT)\n'+
|
||||||
|
'\n'+
|
||||||
|
'USAGE:\n'+
|
||||||
|
'1) Put the same etcd_address into /etc/vitastor/vitastor.conf on all monitor nodes\n'+
|
||||||
|
'2) Run '+process.argv[1]+' [config_path]\n'
|
||||||
|
);
|
||||||
|
process.exit(0);
|
||||||
|
}
|
||||||
|
if (!fs.existsSync(config_path))
|
||||||
|
{
|
||||||
|
console.log(config_path+' is missing');
|
||||||
|
process.exit(1);
|
||||||
|
}
|
||||||
|
if (fs.existsSync("/etc/systemd/system/etcd.service"))
|
||||||
|
{
|
||||||
|
console.log("/etc/systemd/system/etcd.service already exists");
|
||||||
|
process.exit(1);
|
||||||
|
}
|
||||||
|
const config = JSON.parse(fs.readFileSync(config_path, { encoding: 'utf-8' }));
|
||||||
|
if (!config.etcd_address)
|
||||||
|
{
|
||||||
|
console.log("etcd_address is missing in "+config_path);
|
||||||
|
process.exit(1);
|
||||||
|
}
|
||||||
|
const etcds = (config.etcd_address instanceof Array ? config.etcd_address : (''+config.etcd_address).split(/,/))
|
||||||
|
.map(s => (''+s).replace(/^https?:\/\/\[?|\]?(:\d+)?(\/.*)?$/g, '').toLowerCase());
|
||||||
|
const num = select_local_etcd(etcds);
|
||||||
|
if (num < 0)
|
||||||
|
{
|
||||||
|
console.log('No matching IPs in etcd_address from '+config_path);
|
||||||
|
process.exit(0);
|
||||||
|
}
|
||||||
|
const etcd_cluster = etcds.map((e, i) => `etcd${i}=http://${e}:2380`).join(',');
|
||||||
|
await system(`mkdir -p /var/lib/etcd${num}.etcd`);
|
||||||
|
fs.writeFileSync(
|
||||||
|
"/etc/systemd/system/etcd.service",
|
||||||
|
`[Unit]
|
||||||
|
Description=etcd for vitastor
|
||||||
|
After=network-online.target local-fs.target time-sync.target
|
||||||
|
Wants=network-online.target local-fs.target time-sync.target
|
||||||
|
|
||||||
|
[Service]
|
||||||
|
Restart=always
|
||||||
|
ExecStart=/usr/local/bin/etcd -name etcd${num} --data-dir /var/lib/etcd${num}.etcd \\
|
||||||
|
--advertise-client-urls http://${etcds[num]}:2379 --listen-client-urls http://${etcds[num]}:2379 \\
|
||||||
|
--initial-advertise-peer-urls http://${etcds[num]}:2380 --listen-peer-urls http://${etcds[num]}:2380 \\
|
||||||
|
--initial-cluster-token vitastor-etcd-1 --initial-cluster ${etcd_cluster} \\
|
||||||
|
--initial-cluster-state new --max-txn-ops=100000 --max-request-bytes=104857600 \\
|
||||||
|
--auto-compaction-retention=10 --auto-compaction-mode=revision
|
||||||
|
WorkingDirectory=/var/lib/etcd${num}.etcd
|
||||||
|
ExecStartPre=+chown -R etcd /var/lib/etcd${num}.etcd
|
||||||
|
User=etcd
|
||||||
|
PrivateTmp=false
|
||||||
|
TasksMax=infinity
|
||||||
|
Restart=always
|
||||||
|
StartLimitInterval=0
|
||||||
|
RestartSec=10
|
||||||
|
|
||||||
|
[Install]
|
||||||
|
WantedBy=multi-user.target
|
||||||
|
`);
|
||||||
|
await system(`useradd etcd`);
|
||||||
|
await system(`systemctl daemon-reload`);
|
||||||
|
await system(`systemctl enable etcd`);
|
||||||
|
await system(`systemctl start etcd`);
|
||||||
|
process.exit(0);
|
||||||
|
}
|
||||||
|
|
||||||
|
function select_local_etcd(etcds)
|
||||||
|
{
|
||||||
|
const ifaces = os.networkInterfaces();
|
||||||
|
for (const ifname in ifaces)
|
||||||
|
for (const iface of ifaces[ifname])
|
||||||
|
for (let i = 0; i < etcds.length; i++)
|
||||||
|
if (etcds[i] == iface.address.toLowerCase())
|
||||||
|
return i;
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
async function system(cmd)
|
||||||
|
{
|
||||||
|
const cp = child_process.spawn(cmd, { shell: true, stdio: [ 0, 1, 2 ] });
|
||||||
|
let finish_cb;
|
||||||
|
cp.on('exit', () => finish_cb && finish_cb());
|
||||||
|
if (cp.exitCode == null)
|
||||||
|
await new Promise(ok => finish_cb = ok);
|
||||||
|
return cp.exitCode;
|
||||||
|
}
|
@@ -1,414 +0,0 @@
|
|||||||
#!/usr/bin/nodejs
|
|
||||||
// systemd unit generator for hybrid (HDD+SSD) vitastor OSDs
|
|
||||||
// Copyright (c) Vitaliy Filippov, 2019+
|
|
||||||
// License: VNPL-1.1
|
|
||||||
|
|
||||||
// USAGE: nodejs make-osd-hybrid.js [--disable_ssd_cache 0] [--disable_hdd_cache 0] /dev/sda /dev/sdb /dev/sdc /dev/sdd ...
|
|
||||||
// I.e. - just pass all HDDs and SSDs mixed, the script will decide where
|
|
||||||
// to put journals on its own
|
|
||||||
|
|
||||||
const fs = require('fs');
|
|
||||||
const fsp = fs.promises;
|
|
||||||
const child_process = require('child_process');
|
|
||||||
|
|
||||||
const options = {
|
|
||||||
debug: 1,
|
|
||||||
journal_size: 1024*1024*1024,
|
|
||||||
min_meta_size: 1024*1024*1024,
|
|
||||||
object_size: 1024*1024,
|
|
||||||
bitmap_granularity: 4096,
|
|
||||||
device_block_size: 4096,
|
|
||||||
disable_ssd_cache: 1,
|
|
||||||
disable_hdd_cache: 1,
|
|
||||||
};
|
|
||||||
|
|
||||||
run().catch(console.fatal);
|
|
||||||
|
|
||||||
async function run()
|
|
||||||
{
|
|
||||||
const device_list = parse_options();
|
|
||||||
await system_or_die("mkdir -p /var/log/vitastor; chown vitastor /var/log/vitastor");
|
|
||||||
// Collect devices
|
|
||||||
const all_devices = await collect_devices(device_list);
|
|
||||||
const ssds = all_devices.filter(d => d.ssd);
|
|
||||||
const hdds = all_devices.filter(d => !d.ssd);
|
|
||||||
// Collect existing OSD units
|
|
||||||
const osd_units = await collect_osd_units();
|
|
||||||
// Count assigned HDD journals and unallocated space for each SSD
|
|
||||||
await check_journal_count(ssds, osd_units);
|
|
||||||
// Create new OSDs
|
|
||||||
await create_new_hybrid_osds(hdds, ssds, osd_units);
|
|
||||||
process.exit(0);
|
|
||||||
}
|
|
||||||
|
|
||||||
function parse_options()
|
|
||||||
{
|
|
||||||
const devices = [];
|
|
||||||
const opt = {};
|
|
||||||
for (let i = 2; i < process.argv.length; i++)
|
|
||||||
{
|
|
||||||
const arg = process.argv[i];
|
|
||||||
if (arg == '--help' || arg == '-h')
|
|
||||||
{
|
|
||||||
opt.help = true;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
else if (arg.substr(0, 2) == '--')
|
|
||||||
opt[arg.substr(2)] = process.argv[++i];
|
|
||||||
else
|
|
||||||
devices.push(arg);
|
|
||||||
}
|
|
||||||
if (opt.help || !devices.length)
|
|
||||||
{
|
|
||||||
console.log(
|
|
||||||
'Prepare hybrid (HDD+SSD) Vitastor OSDs\n'+
|
|
||||||
'(c) Vitaliy Filippov, 2019+, license: VNPL-1.1\n\n'+
|
|
||||||
'USAGE: nodejs make-osd-hybrid.js [OPTIONS] /dev/sda /dev/sdb /dev/sdc ...\n'+
|
|
||||||
'Just pass all your SSDs and HDDs in any order, the script will distribute OSDs for you.\n\n'+
|
|
||||||
'OPTIONS (with defaults):\n'+
|
|
||||||
Object.keys(options).map(k => ` --${k} ${options[k]}`).join('\n')
|
|
||||||
);
|
|
||||||
process.exit(0);
|
|
||||||
}
|
|
||||||
for (const k in opt)
|
|
||||||
options[k] = opt[k];
|
|
||||||
return devices;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Collect devices
|
|
||||||
async function collect_devices(devices_to_check)
|
|
||||||
{
|
|
||||||
const devices = [];
|
|
||||||
for (const dev of devices_to_check)
|
|
||||||
{
|
|
||||||
if (dev.substr(0, 5) != '/dev/')
|
|
||||||
{
|
|
||||||
console.log(`${dev} does not start with /dev/, skipping`);
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
if (!await file_exists('/sys/block/'+dev.substr(5)))
|
|
||||||
{
|
|
||||||
console.log(`${dev} is a partition, skipping`);
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
// Check if the device is an SSD
|
|
||||||
const rot = '/sys/block/'+dev.substr(5)+'/queue/rotational';
|
|
||||||
if (!await file_exists(rot))
|
|
||||||
{
|
|
||||||
console.log(`${dev} does not have ${rot} to check whether it's an SSD, skipping`);
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
const ssd = !parseInt(await fsp.readFile(rot, { encoding: 'utf-8' }));
|
|
||||||
// Check if the device has partition table
|
|
||||||
let [ has_partition_table, parts ] = await system(`sfdisk --dump ${dev} --json`);
|
|
||||||
if (has_partition_table != 0)
|
|
||||||
{
|
|
||||||
// Check if the device has any data
|
|
||||||
const [ has_data, out ] = await system(`blkid ${dev}`);
|
|
||||||
if (has_data == 0)
|
|
||||||
{
|
|
||||||
console.log(`${dev} contains data, skipping:\n ${out.trim().replace(/\n/g, '\n ')}`);
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
parts = parts ? JSON.parse(parts).partitiontable : null;
|
|
||||||
if (parts && parts.label != 'gpt')
|
|
||||||
{
|
|
||||||
console.log(`${dev} contains "${parts.label}" partition table, only GPT is supported, skipping`);
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
devices.push({
|
|
||||||
path: dev,
|
|
||||||
ssd,
|
|
||||||
parts,
|
|
||||||
});
|
|
||||||
}
|
|
||||||
return devices;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Collect existing OSD units
|
|
||||||
async function collect_osd_units()
|
|
||||||
{
|
|
||||||
const units = [];
|
|
||||||
for (const unit of (await system("ls /etc/systemd/system/vitastor-osd*.service"))[1].trim().split('\n'))
|
|
||||||
{
|
|
||||||
if (!unit)
|
|
||||||
{
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
let cmd = /^ExecStart\s*=\s*(([^\n]*\\\n)*[^\n]*)/.exec(await fsp.readFile(unit, { encoding: 'utf-8' }));
|
|
||||||
if (!cmd)
|
|
||||||
{
|
|
||||||
console.log('ExecStart= not found in '+unit+', skipping')
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
let kv = {}, key;
|
|
||||||
cmd = cmd[1].replace(/^bash\s+-c\s+'/, '')
|
|
||||||
.replace(/>>\s*\S+2>\s*&1\s*'$/, '')
|
|
||||||
.replace(/\s*\\\n\s*/g, ' ')
|
|
||||||
.replace(/([^\s']+)|'([^']+)'/g, (m, m1, m2) =>
|
|
||||||
{
|
|
||||||
m1 = m1||m2;
|
|
||||||
if (key == null)
|
|
||||||
{
|
|
||||||
if (m1.substr(0, 2) != '--')
|
|
||||||
{
|
|
||||||
console.log('Strange command line in '+unit+', stopping');
|
|
||||||
process.exit(1);
|
|
||||||
}
|
|
||||||
key = m1.substr(2);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
kv[key] = m1;
|
|
||||||
key = null;
|
|
||||||
}
|
|
||||||
});
|
|
||||||
units.push(kv);
|
|
||||||
}
|
|
||||||
return units;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Count assigned HDD journals and unallocated space for each SSD
|
|
||||||
async function check_journal_count(ssds, osd_units)
|
|
||||||
{
|
|
||||||
const units_by_journal = osd_units.reduce((a, c) =>
|
|
||||||
{
|
|
||||||
if (c.journal_device)
|
|
||||||
a[c.journal_device] = c;
|
|
||||||
return a;
|
|
||||||
}, {});
|
|
||||||
for (const dev of ssds)
|
|
||||||
{
|
|
||||||
dev.journals = 0;
|
|
||||||
if (dev.parts)
|
|
||||||
{
|
|
||||||
for (const part of dev.parts.partitions)
|
|
||||||
{
|
|
||||||
if (part.uuid && units_by_journal['/dev/disk/by-partuuid/'+part.uuid.toLowerCase()])
|
|
||||||
{
|
|
||||||
dev.journals++;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
dev.free = free_from_parttable(dev.parts);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
dev.free = parseInt(await system_or_die("blockdev --getsize64 "+dev.path));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
async function create_new_hybrid_osds(hdds, ssds, osd_units)
|
|
||||||
{
|
|
||||||
const units_by_disk = osd_units.reduce((a, c) => { a[c.data_device] = c; return a; }, {});
|
|
||||||
for (const dev of hdds)
|
|
||||||
{
|
|
||||||
if (!dev.parts)
|
|
||||||
{
|
|
||||||
// HDD is not partitioned yet, create a single partition
|
|
||||||
// + is the "default value" for sfdisk
|
|
||||||
await system_or_die('sfdisk '+dev.path, 'label: gpt\n\n+ +\n');
|
|
||||||
dev.parts = JSON.parse(await system_or_die('sfdisk --dump '+dev.path+' --json')).partitiontable;
|
|
||||||
}
|
|
||||||
if (dev.parts.partitions.length != 1)
|
|
||||||
{
|
|
||||||
console.log(dev.path+' has more than 1 partition, skipping');
|
|
||||||
}
|
|
||||||
else if ((dev.parts.partitions[0].start + dev.parts.partitions[0].size) != (1 + dev.parts.lastlba))
|
|
||||||
{
|
|
||||||
console.log(dev.path+'1 is not a whole-disk partition, skipping');
|
|
||||||
}
|
|
||||||
else if (!dev.parts.partitions[0].uuid)
|
|
||||||
{
|
|
||||||
console.log(dev.parts.partitions[0].node+' does not have UUID. Please repartition '+dev.path+' with GPT');
|
|
||||||
}
|
|
||||||
else if (!units_by_disk['/dev/disk/by-partuuid/'+dev.parts.partitions[0].uuid.toLowerCase()])
|
|
||||||
{
|
|
||||||
await create_hybrid_osd(dev, ssds);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
async function create_hybrid_osd(dev, ssds)
|
|
||||||
{
|
|
||||||
// Create a new OSD
|
|
||||||
// Calculate metadata size
|
|
||||||
const data_device = '/dev/disk/by-partuuid/'+dev.parts.partitions[0].uuid.toLowerCase();
|
|
||||||
const data_size = dev.parts.partitions[0].size * dev.parts.sectorsize;
|
|
||||||
const meta_entry_size = 24 + 2*options.object_size/options.bitmap_granularity/8;
|
|
||||||
const entries_per_block = Math.floor(options.device_block_size / meta_entry_size);
|
|
||||||
const object_count = Math.floor(data_size / options.object_size);
|
|
||||||
let meta_size = Math.ceil(1 + object_count / entries_per_block) * options.device_block_size;
|
|
||||||
// Leave some extra space for future metadata formats and round metadata area size to multiples of 1 MB
|
|
||||||
meta_size = 2*meta_size;
|
|
||||||
meta_size = Math.ceil(meta_size/1024/1024) * 1024*1024;
|
|
||||||
if (meta_size < options.min_meta_size)
|
|
||||||
meta_size = options.min_meta_size;
|
|
||||||
let journal_size = Math.ceil(options.journal_size/1024/1024) * 1024*1024;
|
|
||||||
// Pick an SSD for journal, balancing the number of journals across SSDs
|
|
||||||
let selected_ssd;
|
|
||||||
for (const ssd of ssds)
|
|
||||||
if (ssd.free >= (meta_size+journal_size) && (!selected_ssd || selected_ssd.journals > ssd.journals))
|
|
||||||
selected_ssd = ssd;
|
|
||||||
if (!selected_ssd)
|
|
||||||
{
|
|
||||||
console.error('Could not find free space for SSD journal and metadata for '+dev.path);
|
|
||||||
process.exit(1);
|
|
||||||
}
|
|
||||||
// Allocate an OSD number
|
|
||||||
const osd_num = (await system_or_die("vitastor-cli alloc-osd")).trim();
|
|
||||||
if (!osd_num)
|
|
||||||
{
|
|
||||||
console.error('Failed to run vitastor-cli alloc-osd');
|
|
||||||
process.exit(1);
|
|
||||||
}
|
|
||||||
console.log('Creating OSD '+osd_num+' on '+dev.path+' (HDD) with journal and metadata on '+selected_ssd.path+' (SSD)');
|
|
||||||
// Add two partitions: journal and metadata
|
|
||||||
const new_parts = await add_partitions(selected_ssd, [ journal_size, meta_size ]);
|
|
||||||
selected_ssd.journals++;
|
|
||||||
const journal_device = '/dev/disk/by-partuuid/'+new_parts[0].uuid.toLowerCase();
|
|
||||||
const meta_device = '/dev/disk/by-partuuid/'+new_parts[1].uuid.toLowerCase();
|
|
||||||
// Wait until the device symlinks appear
|
|
||||||
while (!await file_exists(journal_device))
|
|
||||||
{
|
|
||||||
await new Promise(ok => setTimeout(ok, 100));
|
|
||||||
}
|
|
||||||
while (!await file_exists(meta_device))
|
|
||||||
{
|
|
||||||
await new Promise(ok => setTimeout(ok, 100));
|
|
||||||
}
|
|
||||||
// Zero out metadata and journal
|
|
||||||
await system_or_die("dd if=/dev/zero of="+journal_device+" bs=1M count="+(journal_size/1024/1024)+" oflag=direct");
|
|
||||||
await system_or_die("dd if=/dev/zero of="+meta_device+" bs=1M count="+(meta_size/1024/1024)+" oflag=direct");
|
|
||||||
// Create unit file for the OSD
|
|
||||||
const has_scsi_cache_type = options.disable_ssd_cache &&
|
|
||||||
(await system("ls /sys/block/"+selected_ssd.path.substr(5)+"/device/scsi_disk/*/cache_type"))[0] == 0;
|
|
||||||
const write_through = options.disable_ssd_cache && (
|
|
||||||
has_scsi_cache_type || selected_ssd.path.substr(5, 4) == 'nvme'
|
|
||||||
&& (await system_or_die("/sys/block/"+selected_ssd.path.substr(5)+"/queue/write_cache")).trim() == "write through");
|
|
||||||
await fsp.writeFile('/etc/systemd/system/vitastor-osd'+osd_num+'.service',
|
|
||||||
`[Unit]
|
|
||||||
Description=Vitastor object storage daemon osd.${osd_num}
|
|
||||||
After=network-online.target local-fs.target time-sync.target
|
|
||||||
Wants=network-online.target local-fs.target time-sync.target
|
|
||||||
PartOf=vitastor.target
|
|
||||||
|
|
||||||
[Service]
|
|
||||||
LimitNOFILE=1048576
|
|
||||||
LimitNPROC=1048576
|
|
||||||
LimitMEMLOCK=infinity
|
|
||||||
ExecStart=bash -c '/usr/bin/vitastor-osd \\
|
|
||||||
--osd_num ${osd_num} ${write_through
|
|
||||||
? "--disable_meta_fsync 1 --disable_journal_fsync 1 --immediate_commit "+(options.disable_hdd_cache ? "all" : "small")
|
|
||||||
: ""} \\
|
|
||||||
--throttle_small_writes 1 \\
|
|
||||||
--disk_alignment ${options.device_block_size} \\
|
|
||||||
--journal_block_size ${options.device_block_size} \\
|
|
||||||
--meta_block_size ${options.device_block_size} \\
|
|
||||||
--journal_no_same_sector_overwrites true \\
|
|
||||||
--journal_sector_buffer_count 1024 \\
|
|
||||||
--block_size ${options.object_size} \\
|
|
||||||
--data_device ${data_device} \\
|
|
||||||
--journal_device ${journal_device} \\
|
|
||||||
--meta_device ${meta_device} >>/var/log/vitastor/osd${osd_num}.log 2>&1'
|
|
||||||
WorkingDirectory=/
|
|
||||||
ExecStartPre=+chown vitastor:vitastor ${data_device}
|
|
||||||
ExecStartPre=+chown vitastor:vitastor ${journal_device}
|
|
||||||
ExecStartPre=+chown vitastor:vitastor ${meta_device}${
|
|
||||||
has_scsi_cache_type
|
|
||||||
? "\nExecStartPre=+bash -c 'D=$$$(readlink "+journal_device+"); echo write through > $$$(dirname /sys/block/*/$$\${D##*/})/device/scsi_disk/*/cache_type'"
|
|
||||||
: ""}${
|
|
||||||
options.disable_hdd_cache
|
|
||||||
? "\nExecStartPre=+bash -c 'D=$$$(readlink "+data_device+"); echo write through > $$$(dirname /sys/block/*/$$\${D##*/})/device/scsi_disk/*/cache_type'"
|
|
||||||
: ""}
|
|
||||||
User=vitastor
|
|
||||||
PrivateTmp=false
|
|
||||||
TasksMax=infinity
|
|
||||||
Restart=always
|
|
||||||
StartLimitInterval=0
|
|
||||||
RestartSec=10
|
|
||||||
|
|
||||||
[Install]
|
|
||||||
WantedBy=vitastor.target
|
|
||||||
`);
|
|
||||||
await system_or_die("systemctl enable vitastor-osd"+osd_num);
|
|
||||||
}
|
|
||||||
|
|
||||||
async function add_partitions(dev, sizes)
|
|
||||||
{
|
|
||||||
let script = 'label: gpt\n\n';
|
|
||||||
if (dev.parts)
|
|
||||||
{
|
|
||||||
// Old partitions
|
|
||||||
for (const part of dev.parts.partitions)
|
|
||||||
{
|
|
||||||
script += part.node+': '+Object.keys(part).map(k => k == 'node' ? '' : k+'='+part[k]).filter(k => k).join(', ')+'\n';
|
|
||||||
}
|
|
||||||
}
|
|
||||||
// New partitions
|
|
||||||
for (const size of sizes)
|
|
||||||
{
|
|
||||||
script += '+ '+Math.ceil(size/1024)+'KiB\n';
|
|
||||||
}
|
|
||||||
await system_or_die('sfdisk '+dev.path, script);
|
|
||||||
// Get new partition table and find the new partition
|
|
||||||
const newpt = JSON.parse(await system_or_die('sfdisk --dump '+dev.path+' --json')).partitiontable;
|
|
||||||
const old_nodes = dev.parts ? dev.parts.partitions.reduce((a, c) => { a[c.uuid] = true; return a; }, {}) : {};
|
|
||||||
const new_nodes = newpt.partitions.filter(part => !old_nodes[part.uuid]);
|
|
||||||
if (new_nodes.length != sizes.length)
|
|
||||||
{
|
|
||||||
console.error('Failed to partition '+dev.path+': new partitions not found in table');
|
|
||||||
process.exit(1);
|
|
||||||
}
|
|
||||||
dev.parts = newpt;
|
|
||||||
dev.free = free_from_parttable(newpt);
|
|
||||||
return new_nodes;
|
|
||||||
}
|
|
||||||
|
|
||||||
function free_from_parttable(pt)
|
|
||||||
{
|
|
||||||
let free = pt.lastlba + 1 - pt.firstlba;
|
|
||||||
for (const part of pt.partitions)
|
|
||||||
{
|
|
||||||
free -= part.size;
|
|
||||||
}
|
|
||||||
free *= pt.sectorsize;
|
|
||||||
return free;
|
|
||||||
}
|
|
||||||
|
|
||||||
async function system_or_die(cmd, input = '')
|
|
||||||
{
|
|
||||||
let [ exitcode, stdout, stderr ] = await system(cmd, input);
|
|
||||||
if (exitcode != 0)
|
|
||||||
{
|
|
||||||
console.error(cmd+' failed: '+stderr);
|
|
||||||
process.exit(1);
|
|
||||||
}
|
|
||||||
return stdout;
|
|
||||||
}
|
|
||||||
|
|
||||||
async function system(cmd, input = '')
|
|
||||||
{
|
|
||||||
if (options.debug)
|
|
||||||
{
|
|
||||||
process.stderr.write('+ '+cmd+(input ? " <<EOF\n"+input.replace(/\s*$/, '\n')+"EOF" : '')+'\n');
|
|
||||||
}
|
|
||||||
const cp = child_process.spawn(cmd, { shell: true });
|
|
||||||
let stdout = '', stderr = '', finish_cb;
|
|
||||||
cp.stdout.on('data', buf => stdout += buf.toString());
|
|
||||||
cp.stderr.on('data', buf => stderr += buf.toString());
|
|
||||||
cp.on('exit', () => finish_cb && finish_cb());
|
|
||||||
cp.stdin.write(input);
|
|
||||||
cp.stdin.end();
|
|
||||||
if (cp.exitCode == null)
|
|
||||||
{
|
|
||||||
await new Promise(ok => finish_cb = ok);
|
|
||||||
}
|
|
||||||
return [ cp.exitCode, stdout, stderr ];
|
|
||||||
}
|
|
||||||
|
|
||||||
async function file_exists(filename)
|
|
||||||
{
|
|
||||||
return new Promise((ok, no) => fs.access(filename, fs.constants.R_OK, err => ok(!err)));
|
|
||||||
}
|
|
@@ -1,66 +0,0 @@
|
|||||||
#!/bin/bash
|
|
||||||
# Very simple systemd unit generator for vitastor-osd services
|
|
||||||
# Not the final solution yet, mostly for tests
|
|
||||||
# Copyright (c) Vitaliy Filippov, 2019+
|
|
||||||
# License: MIT
|
|
||||||
|
|
||||||
# USAGE:
|
|
||||||
# 1) Put etcd_address and osd_network into /etc/vitastor/vitastor.conf. Example:
|
|
||||||
# {
|
|
||||||
# "etcd_address":["http://10.200.1.10:2379/v3","http://10.200.1.11:2379/v3","http://10.200.1.12:2379/v3"],
|
|
||||||
# "osd_network":"10.200.1.0/24"
|
|
||||||
# }
|
|
||||||
# 2) Run ./make-osd.sh /dev/disk/by-partuuid/xxx [ /dev/disk/by-partuuid/yyy]...
|
|
||||||
|
|
||||||
set -e -x
|
|
||||||
|
|
||||||
# Create OSDs on all passed devices
|
|
||||||
for DEV in $*; do
|
|
||||||
|
|
||||||
OSD_NUM=$(vitastor-cli alloc-osd)
|
|
||||||
|
|
||||||
echo Creating OSD $OSD_NUM on $DEV
|
|
||||||
|
|
||||||
OPT=$(vitastor-cli simple-offsets --format options $DEV | tr '\n' ' ')
|
|
||||||
META=$(vitastor-cli simple-offsets --format json $DEV | jq .data_offset)
|
|
||||||
dd if=/dev/zero of=$DEV bs=1048576 count=$(((META+1048575)/1048576)) oflag=direct
|
|
||||||
|
|
||||||
mkdir -p /var/log/vitastor
|
|
||||||
id vitastor &>/dev/null || useradd vitastor
|
|
||||||
chown vitastor /var/log/vitastor
|
|
||||||
|
|
||||||
cat >/etc/systemd/system/vitastor-osd$OSD_NUM.service <<EOF
|
|
||||||
[Unit]
|
|
||||||
Description=Vitastor object storage daemon osd.$OSD_NUM
|
|
||||||
After=network-online.target local-fs.target time-sync.target
|
|
||||||
Wants=network-online.target local-fs.target time-sync.target
|
|
||||||
PartOf=vitastor.target
|
|
||||||
|
|
||||||
[Service]
|
|
||||||
LimitNOFILE=1048576
|
|
||||||
LimitNPROC=1048576
|
|
||||||
LimitMEMLOCK=infinity
|
|
||||||
ExecStart=bash -c '/usr/bin/vitastor-osd \\
|
|
||||||
--osd_num $OSD_NUM \\
|
|
||||||
--disable_data_fsync 1 \\
|
|
||||||
--immediate_commit all \\
|
|
||||||
--disk_alignment 4096 --journal_block_size 4096 --meta_block_size 4096 \\
|
|
||||||
--journal_no_same_sector_overwrites true \\
|
|
||||||
--journal_sector_buffer_count 1024 \\
|
|
||||||
$OPT >>/var/log/vitastor/osd$OSD_NUM.log 2>&1'
|
|
||||||
WorkingDirectory=/
|
|
||||||
ExecStartPre=+chown vitastor:vitastor $DEV
|
|
||||||
User=vitastor
|
|
||||||
PrivateTmp=false
|
|
||||||
TasksMax=infinity
|
|
||||||
Restart=always
|
|
||||||
StartLimitInterval=0
|
|
||||||
RestartSec=10
|
|
||||||
|
|
||||||
[Install]
|
|
||||||
WantedBy=vitastor.target
|
|
||||||
EOF
|
|
||||||
|
|
||||||
systemctl enable vitastor-osd$OSD_NUM
|
|
||||||
|
|
||||||
done
|
|
@@ -1,86 +0,0 @@
|
|||||||
#!/bin/bash
|
|
||||||
# Very simple systemd unit generator for etcd & vitastor-mon services
|
|
||||||
# Not the final solution yet, mostly for tests
|
|
||||||
# Copyright (c) Vitaliy Filippov, 2019+
|
|
||||||
# License: MIT
|
|
||||||
|
|
||||||
# USAGE: ./make-units.sh
|
|
||||||
|
|
||||||
IP_SUBSTR="10.200.1."
|
|
||||||
ETCD_HOSTS="etcd0=http://10.200.1.10:2380,etcd1=http://10.200.1.11:2380,etcd2=http://10.200.1.12:2380"
|
|
||||||
|
|
||||||
# determine IP
|
|
||||||
IP=`ip -json a s | jq -r '.[].addr_info[] | select(.local | startswith("'$IP_SUBSTR'")) | .local'`
|
|
||||||
[ "$IP" != "" ] || exit 1
|
|
||||||
ETCD_NUM=${ETCD_HOSTS/$IP*/}
|
|
||||||
[ "$ETCD_NUM" != "$ETCD_HOSTS" ] || exit 1
|
|
||||||
ETCD_NUM=$(echo $ETCD_NUM | tr -d -c , | wc -c)
|
|
||||||
|
|
||||||
# etcd
|
|
||||||
useradd etcd
|
|
||||||
|
|
||||||
mkdir -p /var/lib/etcd$ETCD_NUM.etcd
|
|
||||||
cat >/etc/systemd/system/etcd.service <<EOF
|
|
||||||
[Unit]
|
|
||||||
Description=etcd for vitastor
|
|
||||||
After=network-online.target local-fs.target time-sync.target
|
|
||||||
Wants=network-online.target local-fs.target time-sync.target
|
|
||||||
|
|
||||||
[Service]
|
|
||||||
Restart=always
|
|
||||||
ExecStart=/usr/local/bin/etcd -name etcd$ETCD_NUM --data-dir /var/lib/etcd$ETCD_NUM.etcd \\
|
|
||||||
--advertise-client-urls http://$IP:2379 --listen-client-urls http://$IP:2379 \\
|
|
||||||
--initial-advertise-peer-urls http://$IP:2380 --listen-peer-urls http://$IP:2380 \\
|
|
||||||
--initial-cluster-token vitastor-etcd-1 --initial-cluster $ETCD_HOSTS \\
|
|
||||||
--initial-cluster-state new --max-txn-ops=100000 --max-request-bytes=104857600 \\
|
|
||||||
--auto-compaction-retention=10 --auto-compaction-mode=revision
|
|
||||||
WorkingDirectory=/var/lib/etcd$ETCD_NUM.etcd
|
|
||||||
ExecStartPre=+chown -R etcd /var/lib/etcd$ETCD_NUM.etcd
|
|
||||||
User=etcd
|
|
||||||
PrivateTmp=false
|
|
||||||
TasksMax=infinity
|
|
||||||
Restart=always
|
|
||||||
StartLimitInterval=0
|
|
||||||
RestartSec=10
|
|
||||||
|
|
||||||
[Install]
|
|
||||||
WantedBy=local.target
|
|
||||||
EOF
|
|
||||||
|
|
||||||
systemctl daemon-reload
|
|
||||||
systemctl enable etcd
|
|
||||||
systemctl start etcd
|
|
||||||
|
|
||||||
useradd vitastor
|
|
||||||
chmod 755 /root
|
|
||||||
|
|
||||||
# Vitastor target
|
|
||||||
cat >/etc/systemd/system/vitastor.target <<EOF
|
|
||||||
[Unit]
|
|
||||||
Description=vitastor target
|
|
||||||
[Install]
|
|
||||||
WantedBy=multi-user.target
|
|
||||||
EOF
|
|
||||||
|
|
||||||
# Monitor unit
|
|
||||||
ETCD_MON=$(echo $ETCD_HOSTS | perl -pe 's/:2380/:2379/g; s/etcd\d*=//g;')
|
|
||||||
cat >/etc/systemd/system/vitastor-mon.service <<EOF
|
|
||||||
[Unit]
|
|
||||||
Description=Vitastor monitor
|
|
||||||
After=network-online.target local-fs.target time-sync.target
|
|
||||||
Wants=network-online.target local-fs.target time-sync.target
|
|
||||||
|
|
||||||
[Service]
|
|
||||||
Restart=always
|
|
||||||
ExecStart=node /usr/lib/vitastor/mon/mon-main.js --etcd_url '$ETCD_MON' --etcd_prefix '/vitastor' --etcd_start_timeout 5
|
|
||||||
WorkingDirectory=/
|
|
||||||
User=vitastor
|
|
||||||
PrivateTmp=false
|
|
||||||
TasksMax=infinity
|
|
||||||
Restart=always
|
|
||||||
StartLimitInterval=0
|
|
||||||
RestartSec=10
|
|
||||||
|
|
||||||
[Install]
|
|
||||||
WantedBy=vitastor.target
|
|
||||||
EOF
|
|
@@ -12,7 +12,7 @@ for (let i = 2; i < process.argv.length; i++)
|
|||||||
if (process.argv[i] === '-h' || process.argv[i] === '--help')
|
if (process.argv[i] === '-h' || process.argv[i] === '--help')
|
||||||
{
|
{
|
||||||
console.error('USAGE: '+process.argv[0]+' '+process.argv[1]+' [--verbose 1]'+
|
console.error('USAGE: '+process.argv[0]+' '+process.argv[1]+' [--verbose 1]'+
|
||||||
' [--etcd_address "http://127.0.0.1:2379,..."] [--config_file /etc/vitastor/vitastor.conf]'+
|
' [--etcd_address "http://127.0.0.1:2379,..."] [--config_path /etc/vitastor/vitastor.conf]'+
|
||||||
' [--etcd_prefix "/vitastor"] [--etcd_start_timeout 5]');
|
' [--etcd_prefix "/vitastor"] [--etcd_start_timeout 5]');
|
||||||
process.exit();
|
process.exit();
|
||||||
}
|
}
|
||||||
|
225
mon/mon.js
225
mon/mon.js
@@ -51,8 +51,9 @@ const etcd_tree = {
|
|||||||
// THIS IS JUST A POOR MAN'S CONFIG DOCUMENTATION
|
// THIS IS JUST A POOR MAN'S CONFIG DOCUMENTATION
|
||||||
// etcd connection
|
// etcd connection
|
||||||
config_path: "/etc/vitastor/vitastor.conf",
|
config_path: "/etc/vitastor/vitastor.conf",
|
||||||
etcd_address: "10.0.115.10:2379/v3",
|
|
||||||
etcd_prefix: "/vitastor",
|
etcd_prefix: "/vitastor",
|
||||||
|
// etcd connection - configurable online
|
||||||
|
etcd_address: "10.0.115.10:2379/v3",
|
||||||
// mon
|
// mon
|
||||||
etcd_mon_ttl: 30, // min: 10
|
etcd_mon_ttl: 30, // min: 10
|
||||||
etcd_mon_timeout: 1000, // ms. min: 0
|
etcd_mon_timeout: 1000, // ms. min: 0
|
||||||
@@ -70,14 +71,15 @@ const etcd_tree = {
|
|||||||
rdma_gid_index: 0,
|
rdma_gid_index: 0,
|
||||||
rdma_mtu: 4096,
|
rdma_mtu: 4096,
|
||||||
rdma_max_sge: 128,
|
rdma_max_sge: 128,
|
||||||
rdma_max_send: 32,
|
rdma_max_send: 8,
|
||||||
rdma_max_recv: 8,
|
rdma_max_recv: 16,
|
||||||
rdma_max_msg: 1048576,
|
rdma_max_msg: 132096,
|
||||||
log_level: 0,
|
|
||||||
block_size: 131072,
|
block_size: 131072,
|
||||||
disk_alignment: 4096,
|
disk_alignment: 4096,
|
||||||
bitmap_granularity: 4096,
|
bitmap_granularity: 4096,
|
||||||
immediate_commit: false, // 'all' or 'small'
|
immediate_commit: false, // 'all' or 'small'
|
||||||
|
// client and osd - configurable online
|
||||||
|
log_level: 0,
|
||||||
client_dirty_limit: 33554432,
|
client_dirty_limit: 33554432,
|
||||||
peer_connect_interval: 5, // seconds. min: 1
|
peer_connect_interval: 5, // seconds. min: 1
|
||||||
peer_connect_timeout: 5, // seconds. min: 1
|
peer_connect_timeout: 5, // seconds. min: 1
|
||||||
@@ -95,17 +97,19 @@ const etcd_tree = {
|
|||||||
osd_network: null, // "192.168.7.0/24" or an array of masks
|
osd_network: null, // "192.168.7.0/24" or an array of masks
|
||||||
bind_address: "0.0.0.0",
|
bind_address: "0.0.0.0",
|
||||||
bind_port: 0,
|
bind_port: 0,
|
||||||
|
readonly: false,
|
||||||
|
osd_memlock: false,
|
||||||
|
// osd - configurable online
|
||||||
autosync_interval: 5,
|
autosync_interval: 5,
|
||||||
autosync_writes: 128,
|
autosync_writes: 128,
|
||||||
client_queue_depth: 128, // unused
|
client_queue_depth: 128, // unused
|
||||||
recovery_queue_depth: 4,
|
recovery_queue_depth: 4,
|
||||||
recovery_sync_batch: 16,
|
recovery_sync_batch: 16,
|
||||||
readonly: false,
|
|
||||||
no_recovery: false,
|
no_recovery: false,
|
||||||
no_rebalance: false,
|
no_rebalance: false,
|
||||||
print_stats_interval: 3,
|
print_stats_interval: 3,
|
||||||
slow_log_interval: 10,
|
slow_log_interval: 10,
|
||||||
osd_memlock: false,
|
inode_vanish_time: 60,
|
||||||
// blockstore - fixed in superblock
|
// blockstore - fixed in superblock
|
||||||
block_size,
|
block_size,
|
||||||
disk_alignment,
|
disk_alignment,
|
||||||
@@ -124,14 +128,15 @@ const etcd_tree = {
|
|||||||
meta_offset,
|
meta_offset,
|
||||||
disable_meta_fsync,
|
disable_meta_fsync,
|
||||||
disable_device_lock,
|
disable_device_lock,
|
||||||
// blockstore - configurable
|
// blockstore - configurable offline
|
||||||
max_write_iodepth,
|
|
||||||
min_flusher_count: 1,
|
|
||||||
max_flusher_count: 256,
|
|
||||||
inmemory_metadata,
|
inmemory_metadata,
|
||||||
inmemory_journal,
|
inmemory_journal,
|
||||||
journal_sector_buffer_count,
|
journal_sector_buffer_count,
|
||||||
journal_no_same_sector_overwrites,
|
journal_no_same_sector_overwrites,
|
||||||
|
// blockstore - configurable online
|
||||||
|
max_write_iodepth,
|
||||||
|
min_flusher_count: 1,
|
||||||
|
max_flusher_count: 256,
|
||||||
throttle_small_writes: false,
|
throttle_small_writes: false,
|
||||||
throttle_target_iops: 100,
|
throttle_target_iops: 100,
|
||||||
throttle_target_mbs: 100,
|
throttle_target_mbs: 100,
|
||||||
@@ -147,16 +152,25 @@ const etcd_tree = {
|
|||||||
/* pools: {
|
/* pools: {
|
||||||
<id>: {
|
<id>: {
|
||||||
name: 'testpool',
|
name: 'testpool',
|
||||||
// jerasure uses Reed-Solomon-Vandermonde codes
|
// 'ec' uses Reed-Solomon-Vandermonde codes, 'jerasure' is an alias for 'ec'
|
||||||
scheme: 'replicated' | 'xor' | 'jerasure',
|
scheme: 'replicated' | 'xor' | 'ec' | 'jerasure',
|
||||||
pg_size: 3,
|
pg_size: 3,
|
||||||
pg_minsize: 2,
|
pg_minsize: 2,
|
||||||
// number of parity chunks, required for jerasure
|
// number of parity chunks, required for EC
|
||||||
parity_chunks?: 1,
|
parity_chunks?: 1,
|
||||||
pg_count: 100,
|
pg_count: 100,
|
||||||
|
// failure_domain = string | { string: int }
|
||||||
|
// the second case specifies multiple failure domains. example:
|
||||||
|
// { datacenter: 3, host: 2 } - means 3 datacenters with 2 hosts each, for EC 4+2
|
||||||
|
// guarantees availability on outage of either 1 datacenter or 2 hosts
|
||||||
failure_domain: 'host',
|
failure_domain: 'host',
|
||||||
max_osd_combinations: 10000,
|
max_osd_combinations: 10000,
|
||||||
pg_stripe_size: 4194304,
|
// block_size, bitmap_granularity, immediate_commit must match all OSDs used in that pool
|
||||||
|
block_size: 131072,
|
||||||
|
bitmap_granularity: 4096,
|
||||||
|
// 'all'/'small'/'none', same as in OSD options
|
||||||
|
immediate_commit: 'none',
|
||||||
|
pg_stripe_size: 0,
|
||||||
root_node?: 'rack1',
|
root_node?: 'rack1',
|
||||||
// restrict pool to OSDs having all of these tags
|
// restrict pool to OSDs having all of these tags
|
||||||
osd_tags?: 'nvme' | [ 'nvme', ... ],
|
osd_tags?: 'nvme' | [ 'nvme', ... ],
|
||||||
@@ -255,7 +269,7 @@ const etcd_tree = {
|
|||||||
/* <pool_id>: {
|
/* <pool_id>: {
|
||||||
<pg_id>: {
|
<pg_id>: {
|
||||||
primary: osd_num_t,
|
primary: osd_num_t,
|
||||||
state: ("starting"|"peering"|"peered"|"incomplete"|"active"|"repeering"|"stopping"|"offline"|
|
state: ("starting"|"peering"|"incomplete"|"active"|"repeering"|"stopping"|"offline"|
|
||||||
"degraded"|"has_incomplete"|"has_degraded"|"has_misplaced"|"has_unclean"|
|
"degraded"|"has_incomplete"|"has_degraded"|"has_misplaced"|"has_unclean"|
|
||||||
"has_invalid"|"left_on_dead")[],
|
"has_invalid"|"left_on_dead")[],
|
||||||
}
|
}
|
||||||
@@ -322,6 +336,13 @@ const etcd_tree = {
|
|||||||
misplaced: uint64_t,
|
misplaced: uint64_t,
|
||||||
degraded: uint64_t,
|
degraded: uint64_t,
|
||||||
incomplete: uint64_t,
|
incomplete: uint64_t,
|
||||||
|
},
|
||||||
|
object_bytes: {
|
||||||
|
total: uint64_t,
|
||||||
|
clean: uint64_t,
|
||||||
|
misplaced: uint64_t,
|
||||||
|
degraded: uint64_t,
|
||||||
|
incomplete: uint64_t,
|
||||||
}, */
|
}, */
|
||||||
},
|
},
|
||||||
history: {
|
history: {
|
||||||
@@ -650,12 +671,15 @@ class Mon
|
|||||||
async save_last_clean()
|
async save_last_clean()
|
||||||
{
|
{
|
||||||
// last_clean_pgs is used to avoid extra data move when observing a series of changes in the cluster
|
// last_clean_pgs is used to avoid extra data move when observing a series of changes in the cluster
|
||||||
|
const new_clean_pgs = { items: {} };
|
||||||
|
next_pool:
|
||||||
for (const pool_id in this.state.config.pools)
|
for (const pool_id in this.state.config.pools)
|
||||||
{
|
{
|
||||||
|
new_clean_pgs.items[pool_id] = (this.state.history.last_clean_pgs.items||{})[pool_id];
|
||||||
const pool_cfg = this.state.config.pools[pool_id];
|
const pool_cfg = this.state.config.pools[pool_id];
|
||||||
if (!this.validate_pool_cfg(pool_id, pool_cfg, false))
|
if (!this.validate_pool_cfg(pool_id, pool_cfg, false))
|
||||||
{
|
{
|
||||||
continue;
|
continue next_pool;
|
||||||
}
|
}
|
||||||
for (let pg_num = 1; pg_num <= pool_cfg.pg_count; pg_num++)
|
for (let pg_num = 1; pg_num <= pool_cfg.pg_count; pg_num++)
|
||||||
{
|
{
|
||||||
@@ -664,17 +688,18 @@ class Mon
|
|||||||
!(this.state.pg.state[pool_id][pg_num].state instanceof Array))
|
!(this.state.pg.state[pool_id][pg_num].state instanceof Array))
|
||||||
{
|
{
|
||||||
// Unclean
|
// Unclean
|
||||||
return;
|
continue next_pool;
|
||||||
}
|
}
|
||||||
let st = this.state.pg.state[pool_id][pg_num].state.join(',');
|
let st = this.state.pg.state[pool_id][pg_num].state.join(',');
|
||||||
if (st != 'active' && st != 'active,left_on_dead' && st != 'left_on_dead,active')
|
if (st != 'active' && st != 'active,left_on_dead' && st != 'left_on_dead,active')
|
||||||
{
|
{
|
||||||
// Unclean
|
// Unclean
|
||||||
return;
|
continue next_pool;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
new_clean_pgs.items[pool_id] = this.state.config.pgs.items[pool_id];
|
||||||
}
|
}
|
||||||
this.state.history.last_clean_pgs = JSON.parse(JSON.stringify(this.state.config.pgs));
|
this.state.history.last_clean_pgs = new_clean_pgs;
|
||||||
await this.etcd_call('/kv/txn', {
|
await this.etcd_call('/kv/txn', {
|
||||||
success: [ { requestPut: {
|
success: [ { requestPut: {
|
||||||
key: b64(this.etcd_prefix+'/history/last_clean_pgs'),
|
key: b64(this.etcd_prefix+'/history/last_clean_pgs'),
|
||||||
@@ -827,7 +852,7 @@ class Mon
|
|||||||
}
|
}
|
||||||
for (const node_id in tree)
|
for (const node_id in tree)
|
||||||
{
|
{
|
||||||
if (node_id === '')
|
if (node_id === '' || tree[node_id].level === 'osd' && (!tree[node_id].size || tree[node_id].size <= 0))
|
||||||
{
|
{
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
@@ -935,9 +960,9 @@ class Mon
|
|||||||
return alive_set[this.rng() % alive_set.length];
|
return alive_set[this.rng() % alive_set.length];
|
||||||
}
|
}
|
||||||
|
|
||||||
save_new_pgs_txn(request, pool_id, up_osds, osd_tree, prev_pgs, new_pgs, pg_history)
|
save_new_pgs_txn(save_to, request, pool_id, up_osds, osd_tree, prev_pgs, new_pgs, pg_history)
|
||||||
{
|
{
|
||||||
const aff_osds = this.get_affinity_osds(this.state.config.pools[pool_id], up_osds, osd_tree);
|
const aff_osds = this.get_affinity_osds(this.state.config.pools[pool_id] || {}, up_osds, osd_tree);
|
||||||
const pg_items = {};
|
const pg_items = {};
|
||||||
this.reset_rng();
|
this.reset_rng();
|
||||||
new_pgs.map((osd_set, i) =>
|
new_pgs.map((osd_set, i) =>
|
||||||
@@ -988,14 +1013,14 @@ class Mon
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
this.state.config.pgs.items = this.state.config.pgs.items || {};
|
save_to.items = save_to.items || {};
|
||||||
if (!new_pgs.length)
|
if (!new_pgs.length)
|
||||||
{
|
{
|
||||||
delete this.state.config.pgs.items[pool_id];
|
delete save_to.items[pool_id];
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
this.state.config.pgs.items[pool_id] = pg_items;
|
save_to.items[pool_id] = pg_items;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1006,6 +1031,32 @@ class Mon
|
|||||||
pool_cfg.parity_chunks = Math.floor(pool_cfg.parity_chunks) || undefined;
|
pool_cfg.parity_chunks = Math.floor(pool_cfg.parity_chunks) || undefined;
|
||||||
pool_cfg.pg_count = Math.floor(pool_cfg.pg_count);
|
pool_cfg.pg_count = Math.floor(pool_cfg.pg_count);
|
||||||
pool_cfg.failure_domain = pool_cfg.failure_domain || 'host';
|
pool_cfg.failure_domain = pool_cfg.failure_domain || 'host';
|
||||||
|
if (pool_cfg.failure_domain instanceof Object)
|
||||||
|
{
|
||||||
|
for (const key in pool_cfg.failure_domain)
|
||||||
|
{
|
||||||
|
const cnt = parseInt(pool_cfg.failure_domain[key]);
|
||||||
|
if (!cnt || cnt <= 0)
|
||||||
|
{
|
||||||
|
if (warn)
|
||||||
|
console.log('Pool '+pool_id+' specifies invalid item count for failure domain \"'+key+'\"');
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
if (key !== 'host' && key != 'osd' && !(key in this.config.placement_levels||{}))
|
||||||
|
{
|
||||||
|
if (warn)
|
||||||
|
console.log('Pool '+pool_id+' uses invalid failure domain \"'+key+'\"');
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if (pool_cfg.failure_domain !== 'host' && pool_cfg.failure_domain != 'osd' &&
|
||||||
|
!(pool_cfg.failure_domain in this.config.placement_levels||{}))
|
||||||
|
{
|
||||||
|
if (warn)
|
||||||
|
console.log('Pool '+pool_id+' uses invalid failure domain \"'+pool_cfg.failure_domain+'\"');
|
||||||
|
return false;
|
||||||
|
}
|
||||||
pool_cfg.max_osd_combinations = Math.floor(pool_cfg.max_osd_combinations) || 10000;
|
pool_cfg.max_osd_combinations = Math.floor(pool_cfg.max_osd_combinations) || 10000;
|
||||||
if (!/^[1-9]\d*$/.exec(''+pool_id))
|
if (!/^[1-9]\d*$/.exec(''+pool_id))
|
||||||
{
|
{
|
||||||
@@ -1013,14 +1064,15 @@ class Mon
|
|||||||
console.log('Pool ID '+pool_id+' is invalid');
|
console.log('Pool ID '+pool_id+' is invalid');
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
if (pool_cfg.scheme !== 'xor' && pool_cfg.scheme !== 'replicated' && pool_cfg.scheme !== 'jerasure')
|
if (pool_cfg.scheme !== 'xor' && pool_cfg.scheme !== 'replicated' &&
|
||||||
|
pool_cfg.scheme !== 'ec' && pool_cfg.scheme !== 'jerasure')
|
||||||
{
|
{
|
||||||
if (warn)
|
if (warn)
|
||||||
console.log('Pool '+pool_id+' has invalid coding scheme (one of "xor", "replicated" and "jerasure" required)');
|
console.log('Pool '+pool_id+' has invalid coding scheme (one of "xor", "replicated", "ec" and "jerasure" required)');
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
if (!pool_cfg.pg_size || pool_cfg.pg_size < 1 || pool_cfg.pg_size > 256 ||
|
if (!pool_cfg.pg_size || pool_cfg.pg_size < 1 || pool_cfg.pg_size > 256 ||
|
||||||
(pool_cfg.scheme === 'xor' || pool_cfg.scheme == 'jerasure') && pool_cfg.pg_size < 3)
|
pool_cfg.scheme !== 'replicated' && pool_cfg.pg_size < 3)
|
||||||
{
|
{
|
||||||
if (warn)
|
if (warn)
|
||||||
console.log('Pool '+pool_id+' has invalid pg_size');
|
console.log('Pool '+pool_id+' has invalid pg_size');
|
||||||
@@ -1039,7 +1091,8 @@ class Mon
|
|||||||
console.log('Pool '+pool_id+' has invalid parity_chunks (must be 1)');
|
console.log('Pool '+pool_id+' has invalid parity_chunks (must be 1)');
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
if (pool_cfg.scheme === 'jerasure' && (pool_cfg.parity_chunks < 1 || pool_cfg.parity_chunks > pool_cfg.pg_size-2))
|
if ((pool_cfg.scheme === 'ec' || pool_cfg.scheme === 'jerasure') &&
|
||||||
|
(pool_cfg.parity_chunks < 1 || pool_cfg.parity_chunks > pool_cfg.pg_size-2))
|
||||||
{
|
{
|
||||||
if (warn)
|
if (warn)
|
||||||
console.log('Pool '+pool_id+' has invalid parity_chunks (must be between 1 and pg_size-2)');
|
console.log('Pool '+pool_id+' has invalid parity_chunks (must be between 1 and pg_size-2)');
|
||||||
@@ -1089,27 +1142,23 @@ class Mon
|
|||||||
filter_osds_by_tags(orig_tree, flat_tree, tags)
|
filter_osds_by_tags(orig_tree, flat_tree, tags)
|
||||||
{
|
{
|
||||||
if (!tags)
|
if (!tags)
|
||||||
{
|
return 1;
|
||||||
return;
|
|
||||||
}
|
|
||||||
for (const tag of (tags instanceof Array ? tags : [ tags ]))
|
for (const tag of (tags instanceof Array ? tags : [ tags ]))
|
||||||
{
|
{
|
||||||
for (const host in flat_tree)
|
for (const item in flat_tree)
|
||||||
{
|
{
|
||||||
let found = 0;
|
if (flat_tree[item] instanceof Object)
|
||||||
for (const osd in flat_tree[host])
|
|
||||||
{
|
{
|
||||||
if (!orig_tree[osd].tags || !orig_tree[osd].tags[tag])
|
if (!filter_osds_by_tags(orig_tree, flat_tree[item], tags))
|
||||||
delete flat_tree[host][osd];
|
delete flat_tree[item];
|
||||||
else
|
|
||||||
found++;
|
|
||||||
}
|
|
||||||
if (!found)
|
|
||||||
{
|
|
||||||
delete flat_tree[host];
|
|
||||||
}
|
}
|
||||||
|
else if (!orig_tree[item].tags || !orig_tree[item].tags[tag])
|
||||||
|
delete flat_tree[item];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
for (const item in flat_tree)
|
||||||
|
return 1;
|
||||||
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
get_affinity_osds(pool_cfg, up_osds, osd_tree)
|
get_affinity_osds(pool_cfg, up_osds, osd_tree)
|
||||||
@@ -1137,6 +1186,7 @@ class Mon
|
|||||||
if (this.state.config.pgs.hash != tree_hash)
|
if (this.state.config.pgs.hash != tree_hash)
|
||||||
{
|
{
|
||||||
// Something has changed
|
// Something has changed
|
||||||
|
const new_config_pgs = JSON.parse(JSON.stringify(this.state.config.pgs));
|
||||||
const etcd_request = { compare: [], success: [] };
|
const etcd_request = { compare: [], success: [] };
|
||||||
for (const pool_id in (this.state.config.pgs||{}).items||{})
|
for (const pool_id in (this.state.config.pgs||{}).items||{})
|
||||||
{
|
{
|
||||||
@@ -1153,7 +1203,11 @@ class Mon
|
|||||||
{
|
{
|
||||||
prev_pgs[pg-1] = this.state.config.pgs.items[pool_id][pg].osd_set;
|
prev_pgs[pg-1] = this.state.config.pgs.items[pool_id][pg].osd_set;
|
||||||
}
|
}
|
||||||
this.save_new_pgs_txn(etcd_request, pool_id, up_osds, osd_tree, prev_pgs, [], []);
|
// Also delete pool statistics
|
||||||
|
etcd_request.success.push({ requestDeleteRange: {
|
||||||
|
key: b64(this.etcd_prefix+'/pool/stats/'+pool_id),
|
||||||
|
} });
|
||||||
|
this.save_new_pgs_txn(new_config_pgs, etcd_request, pool_id, up_osds, osd_tree, prev_pgs, [], []);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
for (const pool_id in this.state.config.pools)
|
for (const pool_id in this.state.config.pools)
|
||||||
@@ -1163,9 +1217,11 @@ class Mon
|
|||||||
{
|
{
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
let pool_tree = osd_tree[pool_cfg.root_node || ''];
|
let pool_tree = osd_tree[pool_cfg.root_node || ''] || {};
|
||||||
pool_tree = pool_tree ? pool_tree.children : [];
|
const failure_domains = pool_cfg.failure_domain instanceof Object
|
||||||
pool_tree = LPOptimizer.flatten_tree(pool_tree, levels, pool_cfg.failure_domain, 'osd');
|
? [ ...Object.keys(pool_cfg.failure_domain), 'osd' ]
|
||||||
|
: [ pool_cfg.failure_domain, 'osd' ];
|
||||||
|
pool_tree = LPOptimizer.extract_tree_levels(pool_tree, failure_domains, levels);
|
||||||
this.filter_osds_by_tags(osd_tree, pool_tree, pool_cfg.osd_tags);
|
this.filter_osds_by_tags(osd_tree, pool_tree, pool_cfg.osd_tags);
|
||||||
// These are for the purpose of building history.osd_sets
|
// These are for the purpose of building history.osd_sets
|
||||||
const real_prev_pgs = [];
|
const real_prev_pgs = [];
|
||||||
@@ -1192,6 +1248,9 @@ class Mon
|
|||||||
pg_count: pool_cfg.pg_count,
|
pg_count: pool_cfg.pg_count,
|
||||||
pg_size: pool_cfg.pg_size,
|
pg_size: pool_cfg.pg_size,
|
||||||
pg_minsize: pool_cfg.pg_minsize,
|
pg_minsize: pool_cfg.pg_minsize,
|
||||||
|
hier_sizes: pool_cfg.failure_domain instanceof Object
|
||||||
|
? [ ...Object.values(pool_cfg.failure_domain), 1 ]
|
||||||
|
: null,
|
||||||
max_combinations: pool_cfg.max_osd_combinations,
|
max_combinations: pool_cfg.max_osd_combinations,
|
||||||
ordered: pool_cfg.scheme != 'replicated',
|
ordered: pool_cfg.scheme != 'replicated',
|
||||||
};
|
};
|
||||||
@@ -1207,7 +1266,7 @@ class Mon
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
const new_pg_history = [];
|
const new_pg_history = [];
|
||||||
PGUtil.scale_pg_count(prev_pgs, pg_history, new_pg_history, pool_cfg.pg_count);
|
PGUtil.scale_pg_count(prev_pgs, real_prev_pgs, pg_history, new_pg_history, pool_cfg.pg_count);
|
||||||
pg_history = new_pg_history;
|
pg_history = new_pg_history;
|
||||||
}
|
}
|
||||||
for (const pg of prev_pgs)
|
for (const pg of prev_pgs)
|
||||||
@@ -1247,7 +1306,7 @@ class Mon
|
|||||||
} });
|
} });
|
||||||
}
|
}
|
||||||
LPOptimizer.print_change_stats(optimize_result);
|
LPOptimizer.print_change_stats(optimize_result);
|
||||||
const pg_effsize = Math.min(pool_cfg.pg_size, Object.keys(pool_tree).length);
|
const pg_effsize = Math.min(pool_cfg.pg_size, Object.keys(pool_tree).length); // FIXME requires hier support too
|
||||||
this.state.pool.stats[pool_id] = {
|
this.state.pool.stats[pool_id] = {
|
||||||
used_raw_tb: (this.state.pool.stats[pool_id]||{}).used_raw_tb || 0,
|
used_raw_tb: (this.state.pool.stats[pool_id]||{}).used_raw_tb || 0,
|
||||||
total_raw_tb: optimize_result.space,
|
total_raw_tb: optimize_result.space,
|
||||||
@@ -1260,14 +1319,15 @@ class Mon
|
|||||||
key: b64(this.etcd_prefix+'/pool/stats/'+pool_id),
|
key: b64(this.etcd_prefix+'/pool/stats/'+pool_id),
|
||||||
value: b64(JSON.stringify(this.state.pool.stats[pool_id])),
|
value: b64(JSON.stringify(this.state.pool.stats[pool_id])),
|
||||||
} });
|
} });
|
||||||
this.save_new_pgs_txn(etcd_request, pool_id, up_osds, osd_tree, real_prev_pgs, optimize_result.int_pgs, pg_history);
|
this.save_new_pgs_txn(new_config_pgs, etcd_request, pool_id, up_osds, osd_tree, real_prev_pgs, optimize_result.int_pgs, pg_history);
|
||||||
}
|
}
|
||||||
this.state.config.pgs.hash = tree_hash;
|
new_config_pgs.hash = tree_hash;
|
||||||
await this.save_pg_config(etcd_request);
|
await this.save_pg_config(new_config_pgs, etcd_request);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
// Nothing changed, but we still want to recheck the distribution of primaries
|
// Nothing changed, but we still want to recheck the distribution of primaries
|
||||||
|
let new_config_pgs;
|
||||||
let changed = false;
|
let changed = false;
|
||||||
for (const pool_id in this.state.config.pools)
|
for (const pool_id in this.state.config.pools)
|
||||||
{
|
{
|
||||||
@@ -1287,31 +1347,35 @@ class Mon
|
|||||||
const new_primary = this.pick_primary(pool_id, pg_cfg.osd_set, up_osds, aff_osds);
|
const new_primary = this.pick_primary(pool_id, pg_cfg.osd_set, up_osds, aff_osds);
|
||||||
if (pg_cfg.primary != new_primary)
|
if (pg_cfg.primary != new_primary)
|
||||||
{
|
{
|
||||||
|
if (!new_config_pgs)
|
||||||
|
{
|
||||||
|
new_config_pgs = JSON.parse(JSON.stringify(this.state.config.pgs));
|
||||||
|
}
|
||||||
console.log(
|
console.log(
|
||||||
`Moving pool ${pool_id} (${pool_cfg.name || 'unnamed'}) PG ${pg_num}`+
|
`Moving pool ${pool_id} (${pool_cfg.name || 'unnamed'}) PG ${pg_num}`+
|
||||||
` primary OSD from ${pg_cfg.primary} to ${new_primary}`
|
` primary OSD from ${pg_cfg.primary} to ${new_primary}`
|
||||||
);
|
);
|
||||||
changed = true;
|
changed = true;
|
||||||
pg_cfg.primary = new_primary;
|
new_config_pgs.items[pool_id][pg_num].primary = new_primary;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (changed)
|
if (changed)
|
||||||
{
|
{
|
||||||
await this.save_pg_config();
|
await this.save_pg_config(new_config_pgs);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
async save_pg_config(etcd_request = { compare: [], success: [] })
|
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' },
|
||||||
);
|
);
|
||||||
etcd_request.success.push(
|
etcd_request.success.push(
|
||||||
{ requestPut: { key: b64(this.etcd_prefix+'/config/pgs'), value: b64(JSON.stringify(this.state.config.pgs)) } },
|
{ requestPut: { key: b64(this.etcd_prefix+'/config/pgs'), value: b64(JSON.stringify(new_config_pgs)) } },
|
||||||
);
|
);
|
||||||
const res = await this.etcd_call('/kv/txn', etcd_request, this.config.etcd_mon_timeout, 0);
|
const res = await this.etcd_call('/kv/txn', etcd_request, this.config.etcd_mon_timeout, 0);
|
||||||
if (!res.succeeded)
|
if (!res.succeeded)
|
||||||
@@ -1355,16 +1419,14 @@ class Mon
|
|||||||
// This is required for multiple change events to trigger at most 1 recheck in 1s
|
// This is required for multiple change events to trigger at most 1 recheck in 1s
|
||||||
schedule_recheck()
|
schedule_recheck()
|
||||||
{
|
{
|
||||||
if (this.recheck_timer)
|
if (!this.recheck_timer)
|
||||||
{
|
{
|
||||||
clearTimeout(this.recheck_timer);
|
this.recheck_timer = setTimeout(() =>
|
||||||
this.recheck_timer = null;
|
{
|
||||||
|
this.recheck_timer = null;
|
||||||
|
this.recheck_pgs().catch(this.die);
|
||||||
|
}, this.config.mon_change_timeout || 1000);
|
||||||
}
|
}
|
||||||
this.recheck_timer = setTimeout(() =>
|
|
||||||
{
|
|
||||||
this.recheck_timer = null;
|
|
||||||
this.recheck_pgs().catch(this.die);
|
|
||||||
}, this.config.mon_change_timeout || 1000);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
sum_op_stats(timestamp, prev_stats)
|
sum_op_stats(timestamp, prev_stats)
|
||||||
@@ -1431,8 +1493,24 @@ class Mon
|
|||||||
sum_object_counts()
|
sum_object_counts()
|
||||||
{
|
{
|
||||||
const object_counts = { object: 0n, clean: 0n, misplaced: 0n, degraded: 0n, incomplete: 0n };
|
const object_counts = { object: 0n, clean: 0n, misplaced: 0n, degraded: 0n, incomplete: 0n };
|
||||||
|
const object_bytes = { object: 0n, clean: 0n, misplaced: 0n, degraded: 0n, incomplete: 0n };
|
||||||
for (const pool_id in this.state.pg.stats)
|
for (const pool_id in this.state.pg.stats)
|
||||||
{
|
{
|
||||||
|
let object_size = 0;
|
||||||
|
for (const osd_num of this.state.pg.stats[pool_id].write_osd_set||[])
|
||||||
|
{
|
||||||
|
if (osd_num && this.state.osd.stats[osd_num] && this.state.osd.stats[osd_num].block_size)
|
||||||
|
{
|
||||||
|
object_size = this.state.osd.stats[osd_num].block_size;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (!object_size)
|
||||||
|
{
|
||||||
|
object_size = (this.state.config.pools[pool_id]||{}).block_size ||
|
||||||
|
this.config.block_size || 131072;
|
||||||
|
}
|
||||||
|
object_size = BigInt(object_size);
|
||||||
for (const pg_num in this.state.pg.stats[pool_id])
|
for (const pg_num in this.state.pg.stats[pool_id])
|
||||||
{
|
{
|
||||||
const st = this.state.pg.stats[pool_id][pg_num];
|
const st = this.state.pg.stats[pool_id][pg_num];
|
||||||
@@ -1443,12 +1521,13 @@ class Mon
|
|||||||
if (st[k+'_count'])
|
if (st[k+'_count'])
|
||||||
{
|
{
|
||||||
object_counts[k] += BigInt(st[k+'_count']);
|
object_counts[k] += BigInt(st[k+'_count']);
|
||||||
|
object_bytes[k] += BigInt(st[k+'_count']) * object_size;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return object_counts;
|
return { object_counts, object_bytes };
|
||||||
}
|
}
|
||||||
|
|
||||||
sum_inode_stats(prev_stats, timestamp, prev_timestamp)
|
sum_inode_stats(prev_stats, timestamp, prev_timestamp)
|
||||||
@@ -1561,7 +1640,7 @@ class Mon
|
|||||||
{
|
{
|
||||||
const txn = [];
|
const txn = [];
|
||||||
const timestamp = Date.now();
|
const timestamp = Date.now();
|
||||||
const object_counts = this.sum_object_counts();
|
const { object_counts, object_bytes } = this.sum_object_counts();
|
||||||
let stats = this.sum_op_stats(timestamp, this.prev_stats);
|
let stats = this.sum_op_stats(timestamp, this.prev_stats);
|
||||||
let inode_stats = this.sum_inode_stats(
|
let inode_stats = this.sum_inode_stats(
|
||||||
this.prev_stats ? this.prev_stats.inode_stats : null,
|
this.prev_stats ? this.prev_stats.inode_stats : null,
|
||||||
@@ -1569,6 +1648,7 @@ class Mon
|
|||||||
);
|
);
|
||||||
this.prev_stats = { timestamp, ...stats, inode_stats };
|
this.prev_stats = { timestamp, ...stats, inode_stats };
|
||||||
stats.object_counts = object_counts;
|
stats.object_counts = object_counts;
|
||||||
|
stats.object_bytes = object_bytes;
|
||||||
stats = this.serialize_bigints(stats);
|
stats = this.serialize_bigints(stats);
|
||||||
inode_stats = this.serialize_bigints(inode_stats);
|
inode_stats = this.serialize_bigints(inode_stats);
|
||||||
txn.push({ requestPut: { key: b64(this.etcd_prefix+'/stats'), value: b64(JSON.stringify(stats)) } });
|
txn.push({ requestPut: { key: b64(this.etcd_prefix+'/stats'), value: b64(JSON.stringify(stats)) } });
|
||||||
@@ -1656,6 +1736,7 @@ class Mon
|
|||||||
// Do not clear these to null
|
// Do not clear these to null
|
||||||
kv.value = kv.value || {};
|
kv.value = kv.value || {};
|
||||||
}
|
}
|
||||||
|
const old = cur[key_parts[key_parts.length-1]];
|
||||||
cur[key_parts[key_parts.length-1]] = kv.value;
|
cur[key_parts[key_parts.length-1]] = kv.value;
|
||||||
if (key === 'config/global')
|
if (key === 'config/global')
|
||||||
{
|
{
|
||||||
@@ -1680,7 +1761,12 @@ class Mon
|
|||||||
}
|
}
|
||||||
else if (key_parts[0] === 'osd' && key_parts[1] === 'stats')
|
else if (key_parts[0] === 'osd' && key_parts[1] === 'stats')
|
||||||
{
|
{
|
||||||
// Recheck PGs <osd_out_time> later
|
// Recheck OSD tree on OSD addition/deletion
|
||||||
|
if ((!old) != (!kv.value) || old && kv.value && old.size != kv.value.size)
|
||||||
|
{
|
||||||
|
this.schedule_recheck();
|
||||||
|
}
|
||||||
|
// Recheck PGs <osd_out_time> after last OSD statistics report
|
||||||
this.schedule_next_recheck_at(
|
this.schedule_next_recheck_at(
|
||||||
!this.state.osd.stats[key[2]] ? 0 : this.state.osd.stats[key[2]].time+this.config.osd_out_time
|
!this.state.osd.stats[key[2]] ? 0 : this.state.osd.stats[key[2]].time+this.config.osd_out_time
|
||||||
);
|
);
|
||||||
@@ -1768,6 +1854,7 @@ function POST(url, body, timeout)
|
|||||||
clearTimeout(timer_id);
|
clearTimeout(timer_id);
|
||||||
let res_body = '';
|
let res_body = '';
|
||||||
res.setEncoding('utf8');
|
res.setEncoding('utf8');
|
||||||
|
res.on('error', (error) => ok({ error }));
|
||||||
res.on('data', chunk => { res_body += chunk; });
|
res.on('data', chunk => { res_body += chunk; });
|
||||||
res.on('end', () =>
|
res.on('end', () =>
|
||||||
{
|
{
|
||||||
@@ -1787,6 +1874,8 @@ function POST(url, body, timeout)
|
|||||||
}
|
}
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
req.on('error', (error) => ok({ error }));
|
||||||
|
req.on('close', () => ok({ error: new Error('Connection closed prematurely') }));
|
||||||
req.write(body_text);
|
req.write(body_text);
|
||||||
req.end();
|
req.end();
|
||||||
});
|
});
|
||||||
|
@@ -36,7 +36,7 @@ const crush_tree = [
|
|||||||
] },
|
] },
|
||||||
];
|
];
|
||||||
|
|
||||||
const osd_tree = LPOptimizer.flatten_tree(crush_tree, {}, 1, 3);
|
const osd_tree = LPOptimizer.extract_tree_levels({ level: -Infinity, children: crush_tree }, [ 1, 3 ], {});
|
||||||
console.log(osd_tree);
|
console.log(osd_tree);
|
||||||
|
|
||||||
async function run()
|
async function run()
|
||||||
@@ -47,32 +47,32 @@ async function run()
|
|||||||
LPOptimizer.print_change_stats(res, false);
|
LPOptimizer.print_change_stats(res, false);
|
||||||
assert(res.space == 0);
|
assert(res.space == 0);
|
||||||
console.log('\nAdding 1st failure domain:');
|
console.log('\nAdding 1st failure domain:');
|
||||||
cur_tree['dom1'] = osd_tree['dom1'];
|
cur_tree['l1_1'] = osd_tree['l1_1'];
|
||||||
res = await LPOptimizer.optimize_change({ prev_pgs: res.int_pgs, osd_tree: cur_tree, pg_size: 3 });
|
res = await LPOptimizer.optimize_change({ prev_pgs: res.int_pgs, osd_tree: cur_tree, pg_size: 3 });
|
||||||
LPOptimizer.print_change_stats(res, false);
|
LPOptimizer.print_change_stats(res, false);
|
||||||
assert(res.space == 12 && res.total_space == 12);
|
assert(res.space == 12 && res.total_space == 12);
|
||||||
console.log('\nAdding 2nd failure domain:');
|
console.log('\nAdding 2nd failure domain:');
|
||||||
cur_tree['dom2'] = osd_tree['dom2'];
|
cur_tree['l1_2'] = osd_tree['l1_2'];
|
||||||
res = await LPOptimizer.optimize_change({ prev_pgs: res.int_pgs, osd_tree: cur_tree, pg_size: 3 });
|
res = await LPOptimizer.optimize_change({ prev_pgs: res.int_pgs, osd_tree: cur_tree, pg_size: 3 });
|
||||||
LPOptimizer.print_change_stats(res, false);
|
LPOptimizer.print_change_stats(res, false);
|
||||||
assert(res.space == 24 && res.total_space == 24);
|
assert(res.space == 24 && res.total_space == 24);
|
||||||
console.log('\nAdding 3rd failure domain:');
|
console.log('\nAdding 3rd failure domain:');
|
||||||
cur_tree['dom3'] = osd_tree['dom3'];
|
cur_tree['l1_3'] = osd_tree['l1_3'];
|
||||||
res = await LPOptimizer.optimize_change({ prev_pgs: res.int_pgs, osd_tree: cur_tree, pg_size: 3 });
|
res = await LPOptimizer.optimize_change({ prev_pgs: res.int_pgs, osd_tree: cur_tree, pg_size: 3 });
|
||||||
LPOptimizer.print_change_stats(res, false);
|
LPOptimizer.print_change_stats(res, false);
|
||||||
assert(res.space == 36 && res.total_space == 36);
|
assert(res.space == 36 && res.total_space == 36);
|
||||||
console.log('\nRemoving 3rd failure domain:');
|
console.log('\nRemoving 3rd failure domain:');
|
||||||
delete cur_tree['dom3'];
|
delete cur_tree['l1_3'];
|
||||||
res = await LPOptimizer.optimize_change({ prev_pgs: res.int_pgs, osd_tree: cur_tree, pg_size: 3 });
|
res = await LPOptimizer.optimize_change({ prev_pgs: res.int_pgs, osd_tree: cur_tree, pg_size: 3 });
|
||||||
LPOptimizer.print_change_stats(res, false);
|
LPOptimizer.print_change_stats(res, false);
|
||||||
assert(res.space == 24 && res.total_space == 24);
|
assert(res.space == 24 && res.total_space == 24);
|
||||||
console.log('\nRemoving 2nd failure domain:');
|
console.log('\nRemoving 2nd failure domain:');
|
||||||
delete cur_tree['dom2'];
|
delete cur_tree['l1_2'];
|
||||||
res = await LPOptimizer.optimize_change({ prev_pgs: res.int_pgs, osd_tree: cur_tree, pg_size: 3 });
|
res = await LPOptimizer.optimize_change({ prev_pgs: res.int_pgs, osd_tree: cur_tree, pg_size: 3 });
|
||||||
LPOptimizer.print_change_stats(res, false);
|
LPOptimizer.print_change_stats(res, false);
|
||||||
assert(res.space == 12 && res.total_space == 12);
|
assert(res.space == 12 && res.total_space == 12);
|
||||||
console.log('\nRemoving 1st failure domain:');
|
console.log('\nRemoving 1st failure domain:');
|
||||||
delete cur_tree['dom1'];
|
delete cur_tree['l1_1'];
|
||||||
res = await LPOptimizer.optimize_change({ prev_pgs: res.int_pgs, osd_tree: cur_tree, pg_size: 3 });
|
res = await LPOptimizer.optimize_change({ prev_pgs: res.int_pgs, osd_tree: cur_tree, pg_size: 3 });
|
||||||
LPOptimizer.print_change_stats(res, false);
|
LPOptimizer.print_change_stats(res, false);
|
||||||
assert(res.space == 0);
|
assert(res.space == 0);
|
||||||
|
@@ -108,7 +108,11 @@ async function run()
|
|||||||
LPOptimizer.print_change_stats(res, false);
|
LPOptimizer.print_change_stats(res, false);
|
||||||
|
|
||||||
console.log('\n256 PGs, size=3, failure domain=rack');
|
console.log('\n256 PGs, size=3, failure domain=rack');
|
||||||
res = await LPOptimizer.optimize_initial({ osd_tree: LPOptimizer.flatten_tree(crush_tree, {}, 1, 3), pg_size: 3, pg_count: 256 });
|
res = await LPOptimizer.optimize_initial({
|
||||||
|
osd_tree: LPOptimizer.extract_tree_levels({ level: -Infinity, children: crush_tree }, [ 1, 3 ], {}),
|
||||||
|
pg_size: 3,
|
||||||
|
pg_count: 256,
|
||||||
|
});
|
||||||
LPOptimizer.print_change_stats(res, false);
|
LPOptimizer.print_change_stats(res, false);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
56
mon/test-random-hier.js
Normal file
56
mon/test-random-hier.js
Normal file
@@ -0,0 +1,56 @@
|
|||||||
|
// Copyright (c) Vitaliy Filippov, 2019+
|
||||||
|
// License: VNPL-1.1 (see README.md for details)
|
||||||
|
|
||||||
|
const LPOptimizer = require('./lp-optimizer.js');
|
||||||
|
|
||||||
|
const osd_tree = {
|
||||||
|
100: { 110: { 111: 1, 112: 1 }, 120: { 121: 1, 122: 1 } },
|
||||||
|
200: { 210: { 211: 1, 212: 1 }, 220: { 221: 1, 222: 1 } },
|
||||||
|
300: { 310: { 311: 1, 312: 1 }, 320: { 321: 1, 322: 1 } },
|
||||||
|
400: { 410: { 411: 1, 412: 1 }, 420: { 421: 1, 422: 1 } },
|
||||||
|
500: { 510: { 511: 1, 512: 1 }, 520: { 521: 1, 522: 1 } },
|
||||||
|
};
|
||||||
|
|
||||||
|
const osd_tree2 = {
|
||||||
|
100: { 111: 1, 112: 1, 121: 1, 122: 1 },
|
||||||
|
200: { 211: 1, 212: 1, 221: 1, 222: 1 },
|
||||||
|
300: { 311: 1, 312: 1, 321: 1, 322: 1 },
|
||||||
|
400: { 411: 1, 412: 1, 421: 1, 422: 1 },
|
||||||
|
500: { 511: 1, 512: 1, 521: 1, 522: 1 },
|
||||||
|
};
|
||||||
|
|
||||||
|
const osd_tree3 = {
|
||||||
|
100: { 111: 1, 112: 1, 121: 1, 122: 1 },
|
||||||
|
200: { 211: 1, 212: 1, 221: 1, 222: 1 },
|
||||||
|
300: { 311: 1, 312: 1, 321: 1, 322: 1 },
|
||||||
|
400: { 411: 1, 412: 1, 421: 1, 422: 1 },
|
||||||
|
500: { 511: 1 },
|
||||||
|
};
|
||||||
|
|
||||||
|
async function run()
|
||||||
|
{
|
||||||
|
let r;
|
||||||
|
console.log(r = LPOptimizer.random_hier_combinations(osd_tree, [ 3, 2, 1 ], 10000, false, true));
|
||||||
|
console.log(r = LPOptimizer.random_hier_combinations(osd_tree2, [ 3, 2 ], 0, false, true));
|
||||||
|
// Will contain 'Z':
|
||||||
|
console.log(r = LPOptimizer.random_combinations(osd_tree2, 6, 0, true));
|
||||||
|
console.log(r = LPOptimizer.extract_tree_levels(
|
||||||
|
{ level: 'dc', children: [
|
||||||
|
{ level: 'rack', children: [
|
||||||
|
{ level: 'host', children: [
|
||||||
|
{ level: 'osd', id: 'OSD5', size: 10 },
|
||||||
|
] },
|
||||||
|
] },
|
||||||
|
{ level: 'osd', id: 'OSD10', size: 10 },
|
||||||
|
] },
|
||||||
|
[ 'rack', 'osd' ],
|
||||||
|
{ dc: 1, rack: 2, host: 3, osd: 4 }
|
||||||
|
));
|
||||||
|
if (JSON.stringify(r) != '{"rack1":{"OSD5":10},"rack2":{"OSD10":10}}')
|
||||||
|
throw new Error('extract_tree_levels failed');
|
||||||
|
// should not contain Z:
|
||||||
|
console.log(r = LPOptimizer.random_hier_combinations(osd_tree3, [ 3, 2 ], 0, false, true));
|
||||||
|
console.log('OK');
|
||||||
|
}
|
||||||
|
|
||||||
|
run().catch(console.error);
|
18
mon/vitastor-mon.service
Normal file
18
mon/vitastor-mon.service
Normal file
@@ -0,0 +1,18 @@
|
|||||||
|
[Unit]
|
||||||
|
Description=Vitastor monitor
|
||||||
|
After=network-online.target local-fs.target time-sync.target
|
||||||
|
Wants=network-online.target local-fs.target time-sync.target
|
||||||
|
|
||||||
|
[Service]
|
||||||
|
Restart=always
|
||||||
|
ExecStart=node /usr/lib/vitastor/mon/mon-main.js
|
||||||
|
WorkingDirectory=/
|
||||||
|
User=vitastor
|
||||||
|
PrivateTmp=false
|
||||||
|
TasksMax=infinity
|
||||||
|
Restart=always
|
||||||
|
StartLimitInterval=0
|
||||||
|
RestartSec=10
|
||||||
|
|
||||||
|
[Install]
|
||||||
|
WantedBy=multi-user.target
|
22
mon/vitastor-osd@.service
Normal file
22
mon/vitastor-osd@.service
Normal file
@@ -0,0 +1,22 @@
|
|||||||
|
[Unit]
|
||||||
|
Description=Vitastor object storage daemon osd.%i
|
||||||
|
After=network-online.target local-fs.target time-sync.target
|
||||||
|
Wants=network-online.target local-fs.target time-sync.target
|
||||||
|
PartOf=vitastor.target
|
||||||
|
|
||||||
|
[Service]
|
||||||
|
LimitNOFILE=1048576
|
||||||
|
LimitNPROC=1048576
|
||||||
|
LimitMEMLOCK=infinity
|
||||||
|
ExecStart=bash -c 'exec vitastor-disk exec-osd /dev/vitastor/osd%i-data >>/var/log/vitastor/osd%i.log 2>&1'
|
||||||
|
ExecStartPre=+vitastor-disk pre-exec /dev/vitastor/osd%i-data
|
||||||
|
WorkingDirectory=/
|
||||||
|
User=vitastor
|
||||||
|
PrivateTmp=false
|
||||||
|
TasksMax=infinity
|
||||||
|
Restart=always
|
||||||
|
StartLimitInterval=0
|
||||||
|
RestartSec=10
|
||||||
|
|
||||||
|
[Install]
|
||||||
|
WantedBy=vitastor.target
|
4
mon/vitastor.target
Normal file
4
mon/vitastor.target
Normal file
@@ -0,0 +1,4 @@
|
|||||||
|
[Unit]
|
||||||
|
Description=vitastor target
|
||||||
|
[Install]
|
||||||
|
WantedBy=multi-user.target
|
@@ -16,6 +16,11 @@ use PVE::Tools qw(run_command);
|
|||||||
|
|
||||||
use base qw(PVE::Storage::Plugin);
|
use base qw(PVE::Storage::Plugin);
|
||||||
|
|
||||||
|
if (@PVE::Storage::Plugin::SHARED_STORAGE)
|
||||||
|
{
|
||||||
|
push @PVE::Storage::Plugin::SHARED_STORAGE, 'vitastor';
|
||||||
|
}
|
||||||
|
|
||||||
sub api
|
sub api
|
||||||
{
|
{
|
||||||
# Trick it :)
|
# Trick it :)
|
||||||
@@ -133,9 +138,11 @@ sub properties
|
|||||||
sub options
|
sub options
|
||||||
{
|
{
|
||||||
return {
|
return {
|
||||||
|
shared => { optional => 1 },
|
||||||
|
content => { optional => 1 },
|
||||||
nodes => { optional => 1 },
|
nodes => { optional => 1 },
|
||||||
disable => { optional => 1 },
|
disable => { optional => 1 },
|
||||||
vitastor_etcd_address => { optional => 1},
|
vitastor_etcd_address => { optional => 1 },
|
||||||
vitastor_etcd_prefix => { optional => 1 },
|
vitastor_etcd_prefix => { optional => 1 },
|
||||||
vitastor_config_path => { optional => 1 },
|
vitastor_config_path => { optional => 1 },
|
||||||
vitastor_prefix => { optional => 1 },
|
vitastor_prefix => { optional => 1 },
|
@@ -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 = '0.7.0'
|
VERSION = '0.8.9'
|
||||||
|
|
||||||
LOG = logging.getLogger(__name__)
|
LOG = logging.getLogger(__name__)
|
||||||
|
|
||||||
@@ -464,7 +464,7 @@ class VitastorDriver(driver.CloneableImageVD,
|
|||||||
vol_name = utils.convert_str(volume.name)
|
vol_name = utils.convert_str(volume.name)
|
||||||
snap_name = utils.convert_str(snapshot.name)
|
snap_name = utils.convert_str(snapshot.name)
|
||||||
|
|
||||||
snap = self._get_image(vol_name+'@'+snap_name)
|
snap = self._get_image('volume-'+snapshot.volume_id+'@'+snap_name)
|
||||||
if not snap:
|
if not snap:
|
||||||
raise exception.SnapshotNotFound(snapshot_id = snap_name)
|
raise exception.SnapshotNotFound(snapshot_id = snap_name)
|
||||||
snap_inode_id = int(resp['responses'][0]['kvs'][0]['value']['id'])
|
snap_inode_id = int(resp['responses'][0]['kvs'][0]['value']['id'])
|
||||||
|
169
patches/pve-qemu-6.2-vitastor.patch
Normal file
169
patches/pve-qemu-6.2-vitastor.patch
Normal file
@@ -0,0 +1,169 @@
|
|||||||
|
Index: qemu/block/meson.build
|
||||||
|
===================================================================
|
||||||
|
--- qemu.orig/block/meson.build
|
||||||
|
+++ qemu/block/meson.build
|
||||||
|
@@ -91,6 +91,7 @@ foreach m : [
|
||||||
|
[libnfs, 'nfs', files('nfs.c')],
|
||||||
|
[libssh, 'ssh', files('ssh.c')],
|
||||||
|
[rbd, 'rbd', files('rbd.c')],
|
||||||
|
+ [vitastor, 'vitastor', files('vitastor.c')],
|
||||||
|
]
|
||||||
|
if m[0].found()
|
||||||
|
module_ss = ss.source_set()
|
||||||
|
Index: qemu/meson.build
|
||||||
|
===================================================================
|
||||||
|
--- qemu.orig/meson.build
|
||||||
|
+++ qemu/meson.build
|
||||||
|
@@ -838,6 +838,26 @@ if not get_option('rbd').auto() or have_
|
||||||
|
endif
|
||||||
|
endif
|
||||||
|
|
||||||
|
+vitastor = not_found
|
||||||
|
+if not get_option('vitastor').auto() or have_block
|
||||||
|
+ libvitastor_client = cc.find_library('vitastor_client', has_headers: ['vitastor_c.h'],
|
||||||
|
+ required: get_option('vitastor'), kwargs: static_kwargs)
|
||||||
|
+ if libvitastor_client.found()
|
||||||
|
+ if cc.links('''
|
||||||
|
+ #include <vitastor_c.h>
|
||||||
|
+ int main(void) {
|
||||||
|
+ vitastor_c_create_qemu(0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0);
|
||||||
|
+ return 0;
|
||||||
|
+ }''', dependencies: libvitastor_client)
|
||||||
|
+ vitastor = declare_dependency(dependencies: libvitastor_client)
|
||||||
|
+ elif get_option('vitastor').enabled()
|
||||||
|
+ error('could not link libvitastor_client')
|
||||||
|
+ else
|
||||||
|
+ warning('could not link libvitastor_client, disabling')
|
||||||
|
+ endif
|
||||||
|
+ endif
|
||||||
|
+endif
|
||||||
|
+
|
||||||
|
glusterfs = not_found
|
||||||
|
glusterfs_ftruncate_has_stat = false
|
||||||
|
glusterfs_iocb_has_stat = false
|
||||||
|
@@ -1459,6 +1479,7 @@ config_host_data.set('CONFIG_LINUX_AIO',
|
||||||
|
config_host_data.set('CONFIG_LINUX_IO_URING', linux_io_uring.found())
|
||||||
|
config_host_data.set('CONFIG_LIBPMEM', libpmem.found())
|
||||||
|
config_host_data.set('CONFIG_RBD', rbd.found())
|
||||||
|
+config_host_data.set('CONFIG_VITASTOR', vitastor.found())
|
||||||
|
config_host_data.set('CONFIG_SDL', sdl.found())
|
||||||
|
config_host_data.set('CONFIG_SDL_IMAGE', sdl_image.found())
|
||||||
|
config_host_data.set('CONFIG_SECCOMP', seccomp.found())
|
||||||
|
@@ -3424,6 +3445,7 @@ if spice_protocol.found()
|
||||||
|
summary_info += {' spice server support': spice}
|
||||||
|
endif
|
||||||
|
summary_info += {'rbd support': rbd}
|
||||||
|
+summary_info += {'vitastor support': vitastor}
|
||||||
|
summary_info += {'xfsctl support': config_host.has_key('CONFIG_XFS')}
|
||||||
|
summary_info += {'smartcard support': cacard}
|
||||||
|
summary_info += {'U2F support': u2f}
|
||||||
|
Index: qemu/meson_options.txt
|
||||||
|
===================================================================
|
||||||
|
--- qemu.orig/meson_options.txt
|
||||||
|
+++ qemu/meson_options.txt
|
||||||
|
@@ -121,6 +121,8 @@ option('lzo', type : 'feature', value :
|
||||||
|
description: 'lzo compression support')
|
||||||
|
option('rbd', type : 'feature', value : 'auto',
|
||||||
|
description: 'Ceph block device driver')
|
||||||
|
+option('vitastor', type : 'feature', value : 'auto',
|
||||||
|
+ description: 'Vitastor block device driver')
|
||||||
|
option('gtk', type : 'feature', value : 'auto',
|
||||||
|
description: 'GTK+ user interface')
|
||||||
|
option('sdl', type : 'feature', value : 'auto',
|
||||||
|
Index: qemu/qapi/block-core.json
|
||||||
|
===================================================================
|
||||||
|
--- qemu.orig/qapi/block-core.json
|
||||||
|
+++ qemu/qapi/block-core.json
|
||||||
|
@@ -3179,7 +3179,7 @@
|
||||||
|
'preallocate', 'qcow', 'qcow2', 'qed', 'quorum', 'raw', 'rbd',
|
||||||
|
{ 'name': 'replication', 'if': 'CONFIG_REPLICATION' },
|
||||||
|
'pbs',
|
||||||
|
- 'ssh', 'throttle', 'vdi', 'vhdx', 'vmdk', 'vpc', 'vvfat' ] }
|
||||||
|
+ 'ssh', 'throttle', 'vdi', 'vhdx', 'vitastor', 'vmdk', 'vpc', 'vvfat' ] }
|
||||||
|
|
||||||
|
##
|
||||||
|
# @BlockdevOptionsFile:
|
||||||
|
@@ -4125,6 +4125,28 @@
|
||||||
|
'*server': ['InetSocketAddressBase'] } }
|
||||||
|
|
||||||
|
##
|
||||||
|
+# @BlockdevOptionsVitastor:
|
||||||
|
+#
|
||||||
|
+# Driver specific block device options for vitastor
|
||||||
|
+#
|
||||||
|
+# @image: Image name
|
||||||
|
+# @inode: Inode number
|
||||||
|
+# @pool: Pool ID
|
||||||
|
+# @size: Desired image size in bytes
|
||||||
|
+# @config-path: Path to Vitastor configuration
|
||||||
|
+# @etcd-host: etcd connection address(es)
|
||||||
|
+# @etcd-prefix: etcd key/value prefix
|
||||||
|
+##
|
||||||
|
+{ 'struct': 'BlockdevOptionsVitastor',
|
||||||
|
+ 'data': { '*inode': 'uint64',
|
||||||
|
+ '*pool': 'uint64',
|
||||||
|
+ '*size': 'uint64',
|
||||||
|
+ '*image': 'str',
|
||||||
|
+ '*config-path': 'str',
|
||||||
|
+ '*etcd-host': 'str',
|
||||||
|
+ '*etcd-prefix': 'str' } }
|
||||||
|
+
|
||||||
|
+##
|
||||||
|
# @ReplicationMode:
|
||||||
|
#
|
||||||
|
# An enumeration of replication modes.
|
||||||
|
@@ -4520,6 +4542,7 @@
|
||||||
|
'throttle': 'BlockdevOptionsThrottle',
|
||||||
|
'vdi': 'BlockdevOptionsGenericFormat',
|
||||||
|
'vhdx': 'BlockdevOptionsGenericFormat',
|
||||||
|
+ 'vitastor': 'BlockdevOptionsVitastor',
|
||||||
|
'vmdk': 'BlockdevOptionsGenericCOWFormat',
|
||||||
|
'vpc': 'BlockdevOptionsGenericFormat',
|
||||||
|
'vvfat': 'BlockdevOptionsVVFAT'
|
||||||
|
@@ -4910,6 +4933,17 @@
|
||||||
|
'*encrypt' : 'RbdEncryptionCreateOptions' } }
|
||||||
|
|
||||||
|
##
|
||||||
|
+# @BlockdevCreateOptionsVitastor:
|
||||||
|
+#
|
||||||
|
+# Driver specific image creation options for Vitastor.
|
||||||
|
+#
|
||||||
|
+# @size: Size of the virtual disk in bytes
|
||||||
|
+##
|
||||||
|
+{ 'struct': 'BlockdevCreateOptionsVitastor',
|
||||||
|
+ 'data': { 'location': 'BlockdevOptionsVitastor',
|
||||||
|
+ 'size': 'size' } }
|
||||||
|
+
|
||||||
|
+##
|
||||||
|
# @BlockdevVmdkSubformat:
|
||||||
|
#
|
||||||
|
# Subformat options for VMDK images
|
||||||
|
@@ -5108,6 +5142,7 @@
|
||||||
|
'ssh': 'BlockdevCreateOptionsSsh',
|
||||||
|
'vdi': 'BlockdevCreateOptionsVdi',
|
||||||
|
'vhdx': 'BlockdevCreateOptionsVhdx',
|
||||||
|
+ 'vitastor': 'BlockdevCreateOptionsVitastor',
|
||||||
|
'vmdk': 'BlockdevCreateOptionsVmdk',
|
||||||
|
'vpc': 'BlockdevCreateOptionsVpc'
|
||||||
|
} }
|
||||||
|
Index: qemu/scripts/ci/org.centos/stream/8/x86_64/configure
|
||||||
|
===================================================================
|
||||||
|
--- qemu.orig/scripts/ci/org.centos/stream/8/x86_64/configure
|
||||||
|
+++ qemu/scripts/ci/org.centos/stream/8/x86_64/configure
|
||||||
|
@@ -31,7 +31,7 @@
|
||||||
|
--with-git=meson \
|
||||||
|
--with-git-submodules=update \
|
||||||
|
--target-list="x86_64-softmmu" \
|
||||||
|
---block-drv-rw-whitelist="qcow2,raw,file,host_device,nbd,iscsi,rbd,blkdebug,luks,null-co,nvme,copy-on-read,throttle,gluster" \
|
||||||
|
+--block-drv-rw-whitelist="qcow2,raw,file,host_device,nbd,iscsi,rbd,vitastor,blkdebug,luks,null-co,nvme,copy-on-read,throttle,gluster" \
|
||||||
|
--audio-drv-list="" \
|
||||||
|
--block-drv-ro-whitelist="vmdk,vhdx,vpc,https,ssh" \
|
||||||
|
--with-coroutine=ucontext \
|
||||||
|
@@ -183,6 +183,7 @@
|
||||||
|
--enable-opengl \
|
||||||
|
--enable-pie \
|
||||||
|
--enable-rbd \
|
||||||
|
+--enable-vitastor \
|
||||||
|
--enable-rdma \
|
||||||
|
--enable-seccomp \
|
||||||
|
--enable-snappy \
|
169
patches/pve-qemu-7.1-vitastor.patch
Normal file
169
patches/pve-qemu-7.1-vitastor.patch
Normal file
@@ -0,0 +1,169 @@
|
|||||||
|
Index: qemu/block/meson.build
|
||||||
|
===================================================================
|
||||||
|
--- qemu.orig/block/meson.build
|
||||||
|
+++ qemu/block/meson.build
|
||||||
|
@@ -111,6 +111,7 @@ foreach m : [
|
||||||
|
[libnfs, 'nfs', files('nfs.c')],
|
||||||
|
[libssh, 'ssh', files('ssh.c')],
|
||||||
|
[rbd, 'rbd', files('rbd.c')],
|
||||||
|
+ [vitastor, 'vitastor', files('vitastor.c')],
|
||||||
|
]
|
||||||
|
if m[0].found()
|
||||||
|
module_ss = ss.source_set()
|
||||||
|
Index: qemu/meson.build
|
||||||
|
===================================================================
|
||||||
|
--- qemu.orig/meson.build
|
||||||
|
+++ qemu/meson.build
|
||||||
|
@@ -967,6 +967,26 @@ if not get_option('rbd').auto() or have_
|
||||||
|
endif
|
||||||
|
endif
|
||||||
|
|
||||||
|
+vitastor = not_found
|
||||||
|
+if not get_option('vitastor').auto() or have_block
|
||||||
|
+ libvitastor_client = cc.find_library('vitastor_client', has_headers: ['vitastor_c.h'],
|
||||||
|
+ required: get_option('vitastor'), kwargs: static_kwargs)
|
||||||
|
+ if libvitastor_client.found()
|
||||||
|
+ if cc.links('''
|
||||||
|
+ #include <vitastor_c.h>
|
||||||
|
+ int main(void) {
|
||||||
|
+ vitastor_c_create_qemu(0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0);
|
||||||
|
+ return 0;
|
||||||
|
+ }''', dependencies: libvitastor_client)
|
||||||
|
+ vitastor = declare_dependency(dependencies: libvitastor_client)
|
||||||
|
+ elif get_option('vitastor').enabled()
|
||||||
|
+ error('could not link libvitastor_client')
|
||||||
|
+ else
|
||||||
|
+ warning('could not link libvitastor_client, disabling')
|
||||||
|
+ endif
|
||||||
|
+ endif
|
||||||
|
+endif
|
||||||
|
+
|
||||||
|
glusterfs = not_found
|
||||||
|
glusterfs_ftruncate_has_stat = false
|
||||||
|
glusterfs_iocb_has_stat = false
|
||||||
|
@@ -1802,6 +1822,7 @@ config_host_data.set('CONFIG_NUMA', numa
|
||||||
|
config_host_data.set('CONFIG_OPENGL', opengl.found())
|
||||||
|
config_host_data.set('CONFIG_PROFILER', get_option('profiler'))
|
||||||
|
config_host_data.set('CONFIG_RBD', rbd.found())
|
||||||
|
+config_host_data.set('CONFIG_VITASTOR', vitastor.found())
|
||||||
|
config_host_data.set('CONFIG_RDMA', rdma.found())
|
||||||
|
config_host_data.set('CONFIG_SDL', sdl.found())
|
||||||
|
config_host_data.set('CONFIG_SDL_IMAGE', sdl_image.found())
|
||||||
|
@@ -3965,6 +3986,7 @@ if spice_protocol.found()
|
||||||
|
summary_info += {' spice server support': spice}
|
||||||
|
endif
|
||||||
|
summary_info += {'rbd support': rbd}
|
||||||
|
+summary_info += {'vitastor support': vitastor}
|
||||||
|
summary_info += {'smartcard support': cacard}
|
||||||
|
summary_info += {'U2F support': u2f}
|
||||||
|
summary_info += {'libusb': libusb}
|
||||||
|
Index: qemu/meson_options.txt
|
||||||
|
===================================================================
|
||||||
|
--- qemu.orig/meson_options.txt
|
||||||
|
+++ qemu/meson_options.txt
|
||||||
|
@@ -167,6 +167,8 @@ option('lzo', type : 'feature', value :
|
||||||
|
description: 'lzo compression support')
|
||||||
|
option('rbd', type : 'feature', value : 'auto',
|
||||||
|
description: 'Ceph block device driver')
|
||||||
|
+option('vitastor', type : 'feature', value : 'auto',
|
||||||
|
+ description: 'Vitastor block device driver')
|
||||||
|
option('opengl', type : 'feature', value : 'auto',
|
||||||
|
description: 'OpenGL support')
|
||||||
|
option('rdma', type : 'feature', value : 'auto',
|
||||||
|
Index: qemu/qapi/block-core.json
|
||||||
|
===================================================================
|
||||||
|
--- qemu.orig/qapi/block-core.json
|
||||||
|
+++ qemu/qapi/block-core.json
|
||||||
|
@@ -3209,7 +3209,7 @@
|
||||||
|
'preallocate', 'qcow', 'qcow2', 'qed', 'quorum', 'raw', 'rbd',
|
||||||
|
{ 'name': 'replication', 'if': 'CONFIG_REPLICATION' },
|
||||||
|
'pbs',
|
||||||
|
- 'ssh', 'throttle', 'vdi', 'vhdx', 'vmdk', 'vpc', 'vvfat' ] }
|
||||||
|
+ 'ssh', 'throttle', 'vdi', 'vhdx', 'vitastor', 'vmdk', 'vpc', 'vvfat' ] }
|
||||||
|
|
||||||
|
##
|
||||||
|
# @BlockdevOptionsFile:
|
||||||
|
@@ -4149,6 +4149,28 @@
|
||||||
|
'*server': ['InetSocketAddressBase'] } }
|
||||||
|
|
||||||
|
##
|
||||||
|
+# @BlockdevOptionsVitastor:
|
||||||
|
+#
|
||||||
|
+# Driver specific block device options for vitastor
|
||||||
|
+#
|
||||||
|
+# @image: Image name
|
||||||
|
+# @inode: Inode number
|
||||||
|
+# @pool: Pool ID
|
||||||
|
+# @size: Desired image size in bytes
|
||||||
|
+# @config-path: Path to Vitastor configuration
|
||||||
|
+# @etcd-host: etcd connection address(es)
|
||||||
|
+# @etcd-prefix: etcd key/value prefix
|
||||||
|
+##
|
||||||
|
+{ 'struct': 'BlockdevOptionsVitastor',
|
||||||
|
+ 'data': { '*inode': 'uint64',
|
||||||
|
+ '*pool': 'uint64',
|
||||||
|
+ '*size': 'uint64',
|
||||||
|
+ '*image': 'str',
|
||||||
|
+ '*config-path': 'str',
|
||||||
|
+ '*etcd-host': 'str',
|
||||||
|
+ '*etcd-prefix': 'str' } }
|
||||||
|
+
|
||||||
|
+##
|
||||||
|
# @ReplicationMode:
|
||||||
|
#
|
||||||
|
# An enumeration of replication modes.
|
||||||
|
@@ -4593,6 +4615,7 @@
|
||||||
|
'throttle': 'BlockdevOptionsThrottle',
|
||||||
|
'vdi': 'BlockdevOptionsGenericFormat',
|
||||||
|
'vhdx': 'BlockdevOptionsGenericFormat',
|
||||||
|
+ 'vitastor': 'BlockdevOptionsVitastor',
|
||||||
|
'vmdk': 'BlockdevOptionsGenericCOWFormat',
|
||||||
|
'vpc': 'BlockdevOptionsGenericFormat',
|
||||||
|
'vvfat': 'BlockdevOptionsVVFAT'
|
||||||
|
@@ -4985,6 +5008,17 @@
|
||||||
|
'*encrypt' : 'RbdEncryptionCreateOptions' } }
|
||||||
|
|
||||||
|
##
|
||||||
|
+# @BlockdevCreateOptionsVitastor:
|
||||||
|
+#
|
||||||
|
+# Driver specific image creation options for Vitastor.
|
||||||
|
+#
|
||||||
|
+# @size: Size of the virtual disk in bytes
|
||||||
|
+##
|
||||||
|
+{ 'struct': 'BlockdevCreateOptionsVitastor',
|
||||||
|
+ 'data': { 'location': 'BlockdevOptionsVitastor',
|
||||||
|
+ 'size': 'size' } }
|
||||||
|
+
|
||||||
|
+##
|
||||||
|
# @BlockdevVmdkSubformat:
|
||||||
|
#
|
||||||
|
# Subformat options for VMDK images
|
||||||
|
@@ -5182,6 +5216,7 @@
|
||||||
|
'ssh': 'BlockdevCreateOptionsSsh',
|
||||||
|
'vdi': 'BlockdevCreateOptionsVdi',
|
||||||
|
'vhdx': 'BlockdevCreateOptionsVhdx',
|
||||||
|
+ 'vitastor': 'BlockdevCreateOptionsVitastor',
|
||||||
|
'vmdk': 'BlockdevCreateOptionsVmdk',
|
||||||
|
'vpc': 'BlockdevCreateOptionsVpc'
|
||||||
|
} }
|
||||||
|
Index: qemu/scripts/ci/org.centos/stream/8/x86_64/configure
|
||||||
|
===================================================================
|
||||||
|
--- qemu.orig/scripts/ci/org.centos/stream/8/x86_64/configure
|
||||||
|
+++ qemu/scripts/ci/org.centos/stream/8/x86_64/configure
|
||||||
|
@@ -31,7 +31,7 @@
|
||||||
|
--with-git=meson \
|
||||||
|
--with-git-submodules=update \
|
||||||
|
--target-list="x86_64-softmmu" \
|
||||||
|
---block-drv-rw-whitelist="qcow2,raw,file,host_device,nbd,iscsi,rbd,blkdebug,luks,null-co,nvme,copy-on-read,throttle,gluster" \
|
||||||
|
+--block-drv-rw-whitelist="qcow2,raw,file,host_device,nbd,iscsi,rbd,vitastor,blkdebug,luks,null-co,nvme,copy-on-read,throttle,gluster" \
|
||||||
|
--audio-drv-list="" \
|
||||||
|
--block-drv-ro-whitelist="vmdk,vhdx,vpc,https,ssh" \
|
||||||
|
--with-coroutine=ucontext \
|
||||||
|
@@ -179,6 +179,7 @@
|
||||||
|
--enable-opengl \
|
||||||
|
--enable-pie \
|
||||||
|
--enable-rbd \
|
||||||
|
+--enable-vitastor \
|
||||||
|
--enable-rdma \
|
||||||
|
--enable-seccomp \
|
||||||
|
--enable-snappy \
|
169
patches/pve-qemu-7.2-vitastor.patch
Normal file
169
patches/pve-qemu-7.2-vitastor.patch
Normal file
@@ -0,0 +1,169 @@
|
|||||||
|
Index: pve-qemu-kvm-7.2.0/block/meson.build
|
||||||
|
===================================================================
|
||||||
|
--- pve-qemu-kvm-7.2.0.orig/block/meson.build
|
||||||
|
+++ pve-qemu-kvm-7.2.0/block/meson.build
|
||||||
|
@@ -113,6 +113,7 @@ foreach m : [
|
||||||
|
[libnfs, 'nfs', files('nfs.c')],
|
||||||
|
[libssh, 'ssh', files('ssh.c')],
|
||||||
|
[rbd, 'rbd', files('rbd.c')],
|
||||||
|
+ [vitastor, 'vitastor', files('vitastor.c')],
|
||||||
|
]
|
||||||
|
if m[0].found()
|
||||||
|
module_ss = ss.source_set()
|
||||||
|
Index: pve-qemu-kvm-7.2.0/meson.build
|
||||||
|
===================================================================
|
||||||
|
--- pve-qemu-kvm-7.2.0.orig/meson.build
|
||||||
|
+++ pve-qemu-kvm-7.2.0/meson.build
|
||||||
|
@@ -1026,6 +1026,26 @@ if not get_option('rbd').auto() or have_
|
||||||
|
endif
|
||||||
|
endif
|
||||||
|
|
||||||
|
+vitastor = not_found
|
||||||
|
+if not get_option('vitastor').auto() or have_block
|
||||||
|
+ libvitastor_client = cc.find_library('vitastor_client', has_headers: ['vitastor_c.h'],
|
||||||
|
+ required: get_option('vitastor'), kwargs: static_kwargs)
|
||||||
|
+ if libvitastor_client.found()
|
||||||
|
+ if cc.links('''
|
||||||
|
+ #include <vitastor_c.h>
|
||||||
|
+ int main(void) {
|
||||||
|
+ vitastor_c_create_qemu(0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0);
|
||||||
|
+ return 0;
|
||||||
|
+ }''', dependencies: libvitastor_client)
|
||||||
|
+ vitastor = declare_dependency(dependencies: libvitastor_client)
|
||||||
|
+ elif get_option('vitastor').enabled()
|
||||||
|
+ error('could not link libvitastor_client')
|
||||||
|
+ else
|
||||||
|
+ warning('could not link libvitastor_client, disabling')
|
||||||
|
+ endif
|
||||||
|
+ endif
|
||||||
|
+endif
|
||||||
|
+
|
||||||
|
glusterfs = not_found
|
||||||
|
glusterfs_ftruncate_has_stat = false
|
||||||
|
glusterfs_iocb_has_stat = false
|
||||||
|
@@ -1865,6 +1885,7 @@ config_host_data.set('CONFIG_NUMA', numa
|
||||||
|
config_host_data.set('CONFIG_OPENGL', opengl.found())
|
||||||
|
config_host_data.set('CONFIG_PROFILER', get_option('profiler'))
|
||||||
|
config_host_data.set('CONFIG_RBD', rbd.found())
|
||||||
|
+config_host_data.set('CONFIG_VITASTOR', vitastor.found())
|
||||||
|
config_host_data.set('CONFIG_RDMA', rdma.found())
|
||||||
|
config_host_data.set('CONFIG_SDL', sdl.found())
|
||||||
|
config_host_data.set('CONFIG_SDL_IMAGE', sdl_image.found())
|
||||||
|
@@ -3957,6 +3978,7 @@ if spice_protocol.found()
|
||||||
|
summary_info += {' spice server support': spice}
|
||||||
|
endif
|
||||||
|
summary_info += {'rbd support': rbd}
|
||||||
|
+summary_info += {'vitastor support': vitastor}
|
||||||
|
summary_info += {'smartcard support': cacard}
|
||||||
|
summary_info += {'U2F support': u2f}
|
||||||
|
summary_info += {'libusb': libusb}
|
||||||
|
Index: pve-qemu-kvm-7.2.0/meson_options.txt
|
||||||
|
===================================================================
|
||||||
|
--- pve-qemu-kvm-7.2.0.orig/meson_options.txt
|
||||||
|
+++ pve-qemu-kvm-7.2.0/meson_options.txt
|
||||||
|
@@ -169,6 +169,8 @@ option('lzo', type : 'feature', value :
|
||||||
|
description: 'lzo compression support')
|
||||||
|
option('rbd', type : 'feature', value : 'auto',
|
||||||
|
description: 'Ceph block device driver')
|
||||||
|
+option('vitastor', type : 'feature', value : 'auto',
|
||||||
|
+ description: 'Vitastor block device driver')
|
||||||
|
option('opengl', type : 'feature', value : 'auto',
|
||||||
|
description: 'OpenGL support')
|
||||||
|
option('rdma', type : 'feature', value : 'auto',
|
||||||
|
Index: pve-qemu-kvm-7.2.0/qapi/block-core.json
|
||||||
|
===================================================================
|
||||||
|
--- pve-qemu-kvm-7.2.0.orig/qapi/block-core.json
|
||||||
|
+++ pve-qemu-kvm-7.2.0/qapi/block-core.json
|
||||||
|
@@ -3213,7 +3213,7 @@
|
||||||
|
'raw', 'rbd',
|
||||||
|
{ 'name': 'replication', 'if': 'CONFIG_REPLICATION' },
|
||||||
|
'pbs',
|
||||||
|
- 'ssh', 'throttle', 'vdi', 'vhdx',
|
||||||
|
+ 'ssh', 'throttle', 'vdi', 'vhdx', 'vitastor',
|
||||||
|
{ 'name': 'virtio-blk-vfio-pci', 'if': 'CONFIG_BLKIO' },
|
||||||
|
{ 'name': 'virtio-blk-vhost-user', 'if': 'CONFIG_BLKIO' },
|
||||||
|
{ 'name': 'virtio-blk-vhost-vdpa', 'if': 'CONFIG_BLKIO' },
|
||||||
|
@@ -4223,6 +4223,28 @@
|
||||||
|
'*server': ['InetSocketAddressBase'] } }
|
||||||
|
|
||||||
|
##
|
||||||
|
+# @BlockdevOptionsVitastor:
|
||||||
|
+#
|
||||||
|
+# Driver specific block device options for vitastor
|
||||||
|
+#
|
||||||
|
+# @image: Image name
|
||||||
|
+# @inode: Inode number
|
||||||
|
+# @pool: Pool ID
|
||||||
|
+# @size: Desired image size in bytes
|
||||||
|
+# @config-path: Path to Vitastor configuration
|
||||||
|
+# @etcd-host: etcd connection address(es)
|
||||||
|
+# @etcd-prefix: etcd key/value prefix
|
||||||
|
+##
|
||||||
|
+{ 'struct': 'BlockdevOptionsVitastor',
|
||||||
|
+ 'data': { '*inode': 'uint64',
|
||||||
|
+ '*pool': 'uint64',
|
||||||
|
+ '*size': 'uint64',
|
||||||
|
+ '*image': 'str',
|
||||||
|
+ '*config-path': 'str',
|
||||||
|
+ '*etcd-host': 'str',
|
||||||
|
+ '*etcd-prefix': 'str' } }
|
||||||
|
+
|
||||||
|
+##
|
||||||
|
# @ReplicationMode:
|
||||||
|
#
|
||||||
|
# An enumeration of replication modes.
|
||||||
|
@@ -4671,6 +4693,7 @@
|
||||||
|
'throttle': 'BlockdevOptionsThrottle',
|
||||||
|
'vdi': 'BlockdevOptionsGenericFormat',
|
||||||
|
'vhdx': 'BlockdevOptionsGenericFormat',
|
||||||
|
+ 'vitastor': 'BlockdevOptionsVitastor',
|
||||||
|
'virtio-blk-vfio-pci':
|
||||||
|
{ 'type': 'BlockdevOptionsVirtioBlkVfioPci',
|
||||||
|
'if': 'CONFIG_BLKIO' },
|
||||||
|
@@ -5072,6 +5095,17 @@
|
||||||
|
'*encrypt' : 'RbdEncryptionCreateOptions' } }
|
||||||
|
|
||||||
|
##
|
||||||
|
+# @BlockdevCreateOptionsVitastor:
|
||||||
|
+#
|
||||||
|
+# Driver specific image creation options for Vitastor.
|
||||||
|
+#
|
||||||
|
+# @size: Size of the virtual disk in bytes
|
||||||
|
+##
|
||||||
|
+{ 'struct': 'BlockdevCreateOptionsVitastor',
|
||||||
|
+ 'data': { 'location': 'BlockdevOptionsVitastor',
|
||||||
|
+ 'size': 'size' } }
|
||||||
|
+
|
||||||
|
+##
|
||||||
|
# @BlockdevVmdkSubformat:
|
||||||
|
#
|
||||||
|
# Subformat options for VMDK images
|
||||||
|
@@ -5269,6 +5303,7 @@
|
||||||
|
'ssh': 'BlockdevCreateOptionsSsh',
|
||||||
|
'vdi': 'BlockdevCreateOptionsVdi',
|
||||||
|
'vhdx': 'BlockdevCreateOptionsVhdx',
|
||||||
|
+ 'vitastor': 'BlockdevCreateOptionsVitastor',
|
||||||
|
'vmdk': 'BlockdevCreateOptionsVmdk',
|
||||||
|
'vpc': 'BlockdevCreateOptionsVpc'
|
||||||
|
} }
|
||||||
|
Index: pve-qemu-kvm-7.2.0/scripts/ci/org.centos/stream/8/x86_64/configure
|
||||||
|
===================================================================
|
||||||
|
--- pve-qemu-kvm-7.2.0.orig/scripts/ci/org.centos/stream/8/x86_64/configure
|
||||||
|
+++ pve-qemu-kvm-7.2.0/scripts/ci/org.centos/stream/8/x86_64/configure
|
||||||
|
@@ -31,7 +31,7 @@
|
||||||
|
--with-git=meson \
|
||||||
|
--with-git-submodules=update \
|
||||||
|
--target-list="x86_64-softmmu" \
|
||||||
|
---block-drv-rw-whitelist="qcow2,raw,file,host_device,nbd,iscsi,rbd,blkdebug,luks,null-co,nvme,copy-on-read,throttle,gluster" \
|
||||||
|
+--block-drv-rw-whitelist="qcow2,raw,file,host_device,nbd,iscsi,rbd,vitastor,blkdebug,luks,null-co,nvme,copy-on-read,throttle,gluster" \
|
||||||
|
--audio-drv-list="" \
|
||||||
|
--block-drv-ro-whitelist="vmdk,vhdx,vpc,https,ssh" \
|
||||||
|
--with-coroutine=ucontext \
|
||||||
|
@@ -179,6 +179,7 @@
|
||||||
|
--enable-opengl \
|
||||||
|
--enable-pie \
|
||||||
|
--enable-rbd \
|
||||||
|
+--enable-vitastor \
|
||||||
|
--enable-rdma \
|
||||||
|
--enable-seccomp \
|
||||||
|
--enable-snappy \
|
169
patches/qemu-6.2-vitastor.patch
Normal file
169
patches/qemu-6.2-vitastor.patch
Normal file
@@ -0,0 +1,169 @@
|
|||||||
|
diff --git a/block/meson.build b/block/meson.build
|
||||||
|
index deb73ca389..e269f599a1 100644
|
||||||
|
--- a/block/meson.build
|
||||||
|
+++ b/block/meson.build
|
||||||
|
@@ -78,6 +78,7 @@ foreach m : [
|
||||||
|
[libnfs, 'nfs', files('nfs.c')],
|
||||||
|
[libssh, 'ssh', files('ssh.c')],
|
||||||
|
[rbd, 'rbd', files('rbd.c')],
|
||||||
|
+ [vitastor, 'vitastor', files('vitastor.c')],
|
||||||
|
]
|
||||||
|
if m[0].found()
|
||||||
|
module_ss = ss.source_set()
|
||||||
|
diff --git a/meson.build b/meson.build
|
||||||
|
index 96de1a6ef9..2e3994777d 100644
|
||||||
|
--- a/meson.build
|
||||||
|
+++ b/meson.build
|
||||||
|
@@ -838,6 +838,26 @@ if not get_option('rbd').auto() or have_block
|
||||||
|
endif
|
||||||
|
endif
|
||||||
|
|
||||||
|
+vitastor = not_found
|
||||||
|
+if not get_option('vitastor').auto() or have_block
|
||||||
|
+ libvitastor_client = cc.find_library('vitastor_client', has_headers: ['vitastor_c.h'],
|
||||||
|
+ required: get_option('vitastor'), kwargs: static_kwargs)
|
||||||
|
+ if libvitastor_client.found()
|
||||||
|
+ if cc.links('''
|
||||||
|
+ #include <vitastor_c.h>
|
||||||
|
+ int main(void) {
|
||||||
|
+ vitastor_c_create_qemu(0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0);
|
||||||
|
+ return 0;
|
||||||
|
+ }''', dependencies: libvitastor_client)
|
||||||
|
+ vitastor = declare_dependency(dependencies: libvitastor_client)
|
||||||
|
+ elif get_option('vitastor').enabled()
|
||||||
|
+ error('could not link libvitastor_client')
|
||||||
|
+ else
|
||||||
|
+ warning('could not link libvitastor_client, disabling')
|
||||||
|
+ endif
|
||||||
|
+ endif
|
||||||
|
+endif
|
||||||
|
+
|
||||||
|
glusterfs = not_found
|
||||||
|
glusterfs_ftruncate_has_stat = false
|
||||||
|
glusterfs_iocb_has_stat = false
|
||||||
|
@@ -1455,6 +1475,7 @@ config_host_data.set('CONFIG_LINUX_AIO', libaio.found())
|
||||||
|
config_host_data.set('CONFIG_LINUX_IO_URING', linux_io_uring.found())
|
||||||
|
config_host_data.set('CONFIG_LIBPMEM', libpmem.found())
|
||||||
|
config_host_data.set('CONFIG_RBD', rbd.found())
|
||||||
|
+config_host_data.set('CONFIG_VITASTOR', vitastor.found())
|
||||||
|
config_host_data.set('CONFIG_SDL', sdl.found())
|
||||||
|
config_host_data.set('CONFIG_SDL_IMAGE', sdl_image.found())
|
||||||
|
config_host_data.set('CONFIG_SECCOMP', seccomp.found())
|
||||||
|
@@ -3412,6 +3433,7 @@ if spice_protocol.found()
|
||||||
|
summary_info += {' spice server support': spice}
|
||||||
|
endif
|
||||||
|
summary_info += {'rbd support': rbd}
|
||||||
|
+summary_info += {'vitastor support': vitastor}
|
||||||
|
summary_info += {'xfsctl support': config_host.has_key('CONFIG_XFS')}
|
||||||
|
summary_info += {'smartcard support': cacard}
|
||||||
|
summary_info += {'U2F support': u2f}
|
||||||
|
diff --git a/meson_options.txt b/meson_options.txt
|
||||||
|
index e392323732..5b56007475 100644
|
||||||
|
--- a/meson_options.txt
|
||||||
|
+++ b/meson_options.txt
|
||||||
|
@@ -121,6 +121,8 @@ option('lzo', type : 'feature', value : 'auto',
|
||||||
|
description: 'lzo compression support')
|
||||||
|
option('rbd', type : 'feature', value : 'auto',
|
||||||
|
description: 'Ceph block device driver')
|
||||||
|
+option('vitastor', type : 'feature', value : 'auto',
|
||||||
|
+ description: 'Vitastor block device driver')
|
||||||
|
option('gtk', type : 'feature', value : 'auto',
|
||||||
|
description: 'GTK+ user interface')
|
||||||
|
option('sdl', type : 'feature', value : 'auto',
|
||||||
|
diff --git a/qapi/block-core.json b/qapi/block-core.json
|
||||||
|
index 1d3dd9cb48..88453405e5 100644
|
||||||
|
--- a/qapi/block-core.json
|
||||||
|
+++ b/qapi/block-core.json
|
||||||
|
@@ -2930,7 +2930,7 @@
|
||||||
|
'luks', 'nbd', 'nfs', 'null-aio', 'null-co', 'nvme', 'parallels',
|
||||||
|
'preallocate', 'qcow', 'qcow2', 'qed', 'quorum', 'raw', 'rbd',
|
||||||
|
{ 'name': 'replication', 'if': 'CONFIG_REPLICATION' },
|
||||||
|
- 'ssh', 'throttle', 'vdi', 'vhdx', 'vmdk', 'vpc', 'vvfat' ] }
|
||||||
|
+ 'ssh', 'throttle', 'vdi', 'vhdx', 'vitastor', 'vmdk', 'vpc', 'vvfat' ] }
|
||||||
|
|
||||||
|
##
|
||||||
|
# @BlockdevOptionsFile:
|
||||||
|
@@ -3864,6 +3864,28 @@
|
||||||
|
'*key-secret': 'str',
|
||||||
|
'*server': ['InetSocketAddressBase'] } }
|
||||||
|
|
||||||
|
+##
|
||||||
|
+# @BlockdevOptionsVitastor:
|
||||||
|
+#
|
||||||
|
+# Driver specific block device options for vitastor
|
||||||
|
+#
|
||||||
|
+# @image: Image name
|
||||||
|
+# @inode: Inode number
|
||||||
|
+# @pool: Pool ID
|
||||||
|
+# @size: Desired image size in bytes
|
||||||
|
+# @config-path: Path to Vitastor configuration
|
||||||
|
+# @etcd-host: etcd connection address(es)
|
||||||
|
+# @etcd-prefix: etcd key/value prefix
|
||||||
|
+##
|
||||||
|
+{ 'struct': 'BlockdevOptionsVitastor',
|
||||||
|
+ 'data': { '*inode': 'uint64',
|
||||||
|
+ '*pool': 'uint64',
|
||||||
|
+ '*size': 'uint64',
|
||||||
|
+ '*image': 'str',
|
||||||
|
+ '*config-path': 'str',
|
||||||
|
+ '*etcd-host': 'str',
|
||||||
|
+ '*etcd-prefix': 'str' } }
|
||||||
|
+
|
||||||
|
##
|
||||||
|
# @ReplicationMode:
|
||||||
|
#
|
||||||
|
@@ -4259,6 +4281,7 @@
|
||||||
|
'throttle': 'BlockdevOptionsThrottle',
|
||||||
|
'vdi': 'BlockdevOptionsGenericFormat',
|
||||||
|
'vhdx': 'BlockdevOptionsGenericFormat',
|
||||||
|
+ 'vitastor': 'BlockdevOptionsVitastor',
|
||||||
|
'vmdk': 'BlockdevOptionsGenericCOWFormat',
|
||||||
|
'vpc': 'BlockdevOptionsGenericFormat',
|
||||||
|
'vvfat': 'BlockdevOptionsVVFAT'
|
||||||
|
@@ -4647,6 +4670,17 @@
|
||||||
|
'*cluster-size' : 'size',
|
||||||
|
'*encrypt' : 'RbdEncryptionCreateOptions' } }
|
||||||
|
|
||||||
|
+##
|
||||||
|
+# @BlockdevCreateOptionsVitastor:
|
||||||
|
+#
|
||||||
|
+# Driver specific image creation options for Vitastor.
|
||||||
|
+#
|
||||||
|
+# @size: Size of the virtual disk in bytes
|
||||||
|
+##
|
||||||
|
+{ 'struct': 'BlockdevCreateOptionsVitastor',
|
||||||
|
+ 'data': { 'location': 'BlockdevOptionsVitastor',
|
||||||
|
+ 'size': 'size' } }
|
||||||
|
+
|
||||||
|
##
|
||||||
|
# @BlockdevVmdkSubformat:
|
||||||
|
#
|
||||||
|
@@ -4846,6 +4880,7 @@
|
||||||
|
'ssh': 'BlockdevCreateOptionsSsh',
|
||||||
|
'vdi': 'BlockdevCreateOptionsVdi',
|
||||||
|
'vhdx': 'BlockdevCreateOptionsVhdx',
|
||||||
|
+ 'vitastor': 'BlockdevCreateOptionsVitastor',
|
||||||
|
'vmdk': 'BlockdevCreateOptionsVmdk',
|
||||||
|
'vpc': 'BlockdevCreateOptionsVpc'
|
||||||
|
} }
|
||||||
|
diff --git a/scripts/meson-buildoptions.sh b/scripts/meson-buildoptions.sh
|
||||||
|
index 7a17ff4218..cdddbf32aa 100644
|
||||||
|
--- a/scripts/meson-buildoptions.sh
|
||||||
|
+++ b/scripts/meson-buildoptions.sh
|
||||||
|
@@ -69,6 +69,7 @@ meson_options_help() {
|
||||||
|
printf "%s\n" ' oss OSS sound support'
|
||||||
|
printf "%s\n" ' pa PulseAudio sound support'
|
||||||
|
printf "%s\n" ' rbd Ceph block device driver'
|
||||||
|
+ printf "%s\n" ' vitastor Vitastor block device driver'
|
||||||
|
printf "%s\n" ' sdl SDL user interface'
|
||||||
|
printf "%s\n" ' sdl-image SDL Image support for icons'
|
||||||
|
printf "%s\n" ' seccomp seccomp support'
|
||||||
|
@@ -210,6 +211,8 @@ _meson_option_parse() {
|
||||||
|
--disable-pa) printf "%s" -Dpa=disabled ;;
|
||||||
|
--enable-rbd) printf "%s" -Drbd=enabled ;;
|
||||||
|
--disable-rbd) printf "%s" -Drbd=disabled ;;
|
||||||
|
+ --enable-vitastor) printf "%s" -Dvitastor=enabled ;;
|
||||||
|
+ --disable-vitastor) printf "%s" -Dvitastor=disabled ;;
|
||||||
|
--enable-sdl) printf "%s" -Dsdl=enabled ;;
|
||||||
|
--disable-sdl) printf "%s" -Dsdl=disabled ;;
|
||||||
|
--enable-sdl-image) printf "%s" -Dsdl_image=enabled ;;
|
190
patches/qemu-7.0-vitastor.patch
Normal file
190
patches/qemu-7.0-vitastor.patch
Normal file
@@ -0,0 +1,190 @@
|
|||||||
|
diff --git a/block/meson.build b/block/meson.build
|
||||||
|
index 0b2a60c99b..d923713804 100644
|
||||||
|
--- a/block/meson.build
|
||||||
|
+++ b/block/meson.build
|
||||||
|
@@ -98,6 +98,7 @@ foreach m : [
|
||||||
|
[libnfs, 'nfs', files('nfs.c')],
|
||||||
|
[libssh, 'ssh', files('ssh.c')],
|
||||||
|
[rbd, 'rbd', files('rbd.c')],
|
||||||
|
+ [vitastor, 'vitastor', files('vitastor.c')],
|
||||||
|
]
|
||||||
|
if m[0].found()
|
||||||
|
module_ss = ss.source_set()
|
||||||
|
diff --git a/meson.build b/meson.build
|
||||||
|
index 861de93c4f..272f72af11 100644
|
||||||
|
--- a/meson.build
|
||||||
|
+++ b/meson.build
|
||||||
|
@@ -884,6 +884,26 @@ if not get_option('rbd').auto() or have_block
|
||||||
|
endif
|
||||||
|
endif
|
||||||
|
|
||||||
|
+vitastor = not_found
|
||||||
|
+if not get_option('vitastor').auto() or have_block
|
||||||
|
+ libvitastor_client = cc.find_library('vitastor_client', has_headers: ['vitastor_c.h'],
|
||||||
|
+ required: get_option('vitastor'), kwargs: static_kwargs)
|
||||||
|
+ if libvitastor_client.found()
|
||||||
|
+ if cc.links('''
|
||||||
|
+ #include <vitastor_c.h>
|
||||||
|
+ int main(void) {
|
||||||
|
+ vitastor_c_create_qemu(0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0);
|
||||||
|
+ return 0;
|
||||||
|
+ }''', dependencies: libvitastor_client)
|
||||||
|
+ vitastor = declare_dependency(dependencies: libvitastor_client)
|
||||||
|
+ elif get_option('vitastor').enabled()
|
||||||
|
+ error('could not link libvitastor_client')
|
||||||
|
+ else
|
||||||
|
+ warning('could not link libvitastor_client, disabling')
|
||||||
|
+ endif
|
||||||
|
+ endif
|
||||||
|
+endif
|
||||||
|
+
|
||||||
|
glusterfs = not_found
|
||||||
|
glusterfs_ftruncate_has_stat = false
|
||||||
|
glusterfs_iocb_has_stat = false
|
||||||
|
@@ -1546,6 +1566,7 @@ config_host_data.set('CONFIG_LIBPMEM', libpmem.found())
|
||||||
|
config_host_data.set('CONFIG_NUMA', numa.found())
|
||||||
|
config_host_data.set('CONFIG_PROFILER', get_option('profiler'))
|
||||||
|
config_host_data.set('CONFIG_RBD', rbd.found())
|
||||||
|
+config_host_data.set('CONFIG_VITASTOR', vitastor.found())
|
||||||
|
config_host_data.set('CONFIG_SDL', sdl.found())
|
||||||
|
config_host_data.set('CONFIG_SDL_IMAGE', sdl_image.found())
|
||||||
|
config_host_data.set('CONFIG_SECCOMP', seccomp.found())
|
||||||
|
@@ -3709,6 +3730,7 @@ if spice_protocol.found()
|
||||||
|
summary_info += {' spice server support': spice}
|
||||||
|
endif
|
||||||
|
summary_info += {'rbd support': rbd}
|
||||||
|
+summary_info += {'vitastor support': vitastor}
|
||||||
|
summary_info += {'smartcard support': cacard}
|
||||||
|
summary_info += {'U2F support': u2f}
|
||||||
|
summary_info += {'libusb': libusb}
|
||||||
|
diff --git a/meson_options.txt b/meson_options.txt
|
||||||
|
index 52b11cead4..d8d0868174 100644
|
||||||
|
--- a/meson_options.txt
|
||||||
|
+++ b/meson_options.txt
|
||||||
|
@@ -149,6 +149,8 @@ option('lzo', type : 'feature', value : 'auto',
|
||||||
|
description: 'lzo compression support')
|
||||||
|
option('rbd', type : 'feature', value : 'auto',
|
||||||
|
description: 'Ceph block device driver')
|
||||||
|
+option('vitastor', type : 'feature', value : 'auto',
|
||||||
|
+ description: 'Vitastor block device driver')
|
||||||
|
option('gtk', type : 'feature', value : 'auto',
|
||||||
|
description: 'GTK+ user interface')
|
||||||
|
option('sdl', type : 'feature', value : 'auto',
|
||||||
|
diff --git a/qapi/block-core.json b/qapi/block-core.json
|
||||||
|
index beeb91952a..1c98dc0e12 100644
|
||||||
|
--- a/qapi/block-core.json
|
||||||
|
+++ b/qapi/block-core.json
|
||||||
|
@@ -2929,7 +2929,7 @@
|
||||||
|
'luks', 'nbd', 'nfs', 'null-aio', 'null-co', 'nvme', 'parallels',
|
||||||
|
'preallocate', 'qcow', 'qcow2', 'qed', 'quorum', 'raw', 'rbd',
|
||||||
|
{ 'name': 'replication', 'if': 'CONFIG_REPLICATION' },
|
||||||
|
- 'ssh', 'throttle', 'vdi', 'vhdx', 'vmdk', 'vpc', 'vvfat' ] }
|
||||||
|
+ 'ssh', 'throttle', 'vdi', 'vhdx', 'vitastor', 'vmdk', 'vpc', 'vvfat' ] }
|
||||||
|
|
||||||
|
##
|
||||||
|
# @BlockdevOptionsFile:
|
||||||
|
@@ -3863,6 +3863,28 @@
|
||||||
|
'*key-secret': 'str',
|
||||||
|
'*server': ['InetSocketAddressBase'] } }
|
||||||
|
|
||||||
|
+##
|
||||||
|
+# @BlockdevOptionsVitastor:
|
||||||
|
+#
|
||||||
|
+# Driver specific block device options for vitastor
|
||||||
|
+#
|
||||||
|
+# @image: Image name
|
||||||
|
+# @inode: Inode number
|
||||||
|
+# @pool: Pool ID
|
||||||
|
+# @size: Desired image size in bytes
|
||||||
|
+# @config-path: Path to Vitastor configuration
|
||||||
|
+# @etcd-host: etcd connection address(es)
|
||||||
|
+# @etcd-prefix: etcd key/value prefix
|
||||||
|
+##
|
||||||
|
+{ 'struct': 'BlockdevOptionsVitastor',
|
||||||
|
+ 'data': { '*inode': 'uint64',
|
||||||
|
+ '*pool': 'uint64',
|
||||||
|
+ '*size': 'uint64',
|
||||||
|
+ '*image': 'str',
|
||||||
|
+ '*config-path': 'str',
|
||||||
|
+ '*etcd-host': 'str',
|
||||||
|
+ '*etcd-prefix': 'str' } }
|
||||||
|
+
|
||||||
|
##
|
||||||
|
# @ReplicationMode:
|
||||||
|
#
|
||||||
|
@@ -4277,6 +4299,7 @@
|
||||||
|
'throttle': 'BlockdevOptionsThrottle',
|
||||||
|
'vdi': 'BlockdevOptionsGenericFormat',
|
||||||
|
'vhdx': 'BlockdevOptionsGenericFormat',
|
||||||
|
+ 'vitastor': 'BlockdevOptionsVitastor',
|
||||||
|
'vmdk': 'BlockdevOptionsGenericCOWFormat',
|
||||||
|
'vpc': 'BlockdevOptionsGenericFormat',
|
||||||
|
'vvfat': 'BlockdevOptionsVVFAT'
|
||||||
|
@@ -4665,6 +4688,17 @@
|
||||||
|
'*cluster-size' : 'size',
|
||||||
|
'*encrypt' : 'RbdEncryptionCreateOptions' } }
|
||||||
|
|
||||||
|
+##
|
||||||
|
+# @BlockdevCreateOptionsVitastor:
|
||||||
|
+#
|
||||||
|
+# Driver specific image creation options for Vitastor.
|
||||||
|
+#
|
||||||
|
+# @size: Size of the virtual disk in bytes
|
||||||
|
+##
|
||||||
|
+{ 'struct': 'BlockdevCreateOptionsVitastor',
|
||||||
|
+ 'data': { 'location': 'BlockdevOptionsVitastor',
|
||||||
|
+ 'size': 'size' } }
|
||||||
|
+
|
||||||
|
##
|
||||||
|
# @BlockdevVmdkSubformat:
|
||||||
|
#
|
||||||
|
@@ -4864,6 +4898,7 @@
|
||||||
|
'ssh': 'BlockdevCreateOptionsSsh',
|
||||||
|
'vdi': 'BlockdevCreateOptionsVdi',
|
||||||
|
'vhdx': 'BlockdevCreateOptionsVhdx',
|
||||||
|
+ 'vitastor': 'BlockdevCreateOptionsVitastor',
|
||||||
|
'vmdk': 'BlockdevCreateOptionsVmdk',
|
||||||
|
'vpc': 'BlockdevCreateOptionsVpc'
|
||||||
|
} }
|
||||||
|
diff --git a/scripts/ci/org.centos/stream/8/x86_64/configure b/scripts/ci/org.centos/stream/8/x86_64/configure
|
||||||
|
index 9850dd4444..72b1287520 100755
|
||||||
|
--- a/scripts/ci/org.centos/stream/8/x86_64/configure
|
||||||
|
+++ b/scripts/ci/org.centos/stream/8/x86_64/configure
|
||||||
|
@@ -31,7 +31,7 @@
|
||||||
|
--with-git=meson \
|
||||||
|
--with-git-submodules=update \
|
||||||
|
--target-list="x86_64-softmmu" \
|
||||||
|
---block-drv-rw-whitelist="qcow2,raw,file,host_device,nbd,iscsi,rbd,blkdebug,luks,null-co,nvme,copy-on-read,throttle,gluster" \
|
||||||
|
+--block-drv-rw-whitelist="qcow2,raw,file,host_device,nbd,iscsi,rbd,vitastor,blkdebug,luks,null-co,nvme,copy-on-read,throttle,gluster" \
|
||||||
|
--audio-drv-list="" \
|
||||||
|
--block-drv-ro-whitelist="vmdk,vhdx,vpc,https,ssh" \
|
||||||
|
--with-coroutine=ucontext \
|
||||||
|
@@ -181,6 +181,7 @@
|
||||||
|
--enable-opengl \
|
||||||
|
--enable-pie \
|
||||||
|
--enable-rbd \
|
||||||
|
+--enable-vitastor \
|
||||||
|
--enable-rdma \
|
||||||
|
--enable-seccomp \
|
||||||
|
--enable-snappy \
|
||||||
|
diff --git a/scripts/meson-buildoptions.sh b/scripts/meson-buildoptions.sh
|
||||||
|
index 1e26f4571e..370898d48c 100644
|
||||||
|
--- a/scripts/meson-buildoptions.sh
|
||||||
|
+++ b/scripts/meson-buildoptions.sh
|
||||||
|
@@ -98,6 +98,7 @@ meson_options_help() {
|
||||||
|
printf "%s\n" ' qed qed image format support'
|
||||||
|
printf "%s\n" ' qga-vss build QGA VSS support (broken with MinGW)'
|
||||||
|
printf "%s\n" ' rbd Ceph block device driver'
|
||||||
|
+ printf "%s\n" ' vitastor Vitastor block device driver'
|
||||||
|
printf "%s\n" ' replication replication support'
|
||||||
|
printf "%s\n" ' sdl SDL user interface'
|
||||||
|
printf "%s\n" ' sdl-image SDL Image support for icons'
|
||||||
|
@@ -289,6 +290,8 @@ _meson_option_parse() {
|
||||||
|
--disable-qom-cast-debug) printf "%s" -Dqom_cast_debug=false ;;
|
||||||
|
--enable-rbd) printf "%s" -Drbd=enabled ;;
|
||||||
|
--disable-rbd) printf "%s" -Drbd=disabled ;;
|
||||||
|
+ --enable-vitastor) printf "%s" -Dvitastor=enabled ;;
|
||||||
|
+ --disable-vitastor) printf "%s" -Dvitastor=disabled ;;
|
||||||
|
--enable-replication) printf "%s" -Dreplication=enabled ;;
|
||||||
|
--disable-replication) printf "%s" -Dreplication=disabled ;;
|
||||||
|
--enable-rng-none) printf "%s" -Drng_none=true ;;
|
190
patches/qemu-7.1-vitastor.patch
Normal file
190
patches/qemu-7.1-vitastor.patch
Normal file
@@ -0,0 +1,190 @@
|
|||||||
|
diff --git a/block/meson.build b/block/meson.build
|
||||||
|
index 60bc305597..89a042216f 100644
|
||||||
|
--- a/block/meson.build
|
||||||
|
+++ b/block/meson.build
|
||||||
|
@@ -98,6 +98,7 @@ foreach m : [
|
||||||
|
[libnfs, 'nfs', files('nfs.c')],
|
||||||
|
[libssh, 'ssh', files('ssh.c')],
|
||||||
|
[rbd, 'rbd', files('rbd.c')],
|
||||||
|
+ [vitastor, 'vitastor', files('vitastor.c')],
|
||||||
|
]
|
||||||
|
if m[0].found()
|
||||||
|
module_ss = ss.source_set()
|
||||||
|
diff --git a/meson.build b/meson.build
|
||||||
|
index 20fddbd707..600db4e2fb 100644
|
||||||
|
--- a/meson.build
|
||||||
|
+++ b/meson.build
|
||||||
|
@@ -967,6 +967,26 @@ if not get_option('rbd').auto() or have_block
|
||||||
|
endif
|
||||||
|
endif
|
||||||
|
|
||||||
|
+vitastor = not_found
|
||||||
|
+if not get_option('vitastor').auto() or have_block
|
||||||
|
+ libvitastor_client = cc.find_library('vitastor_client', has_headers: ['vitastor_c.h'],
|
||||||
|
+ required: get_option('vitastor'), kwargs: static_kwargs)
|
||||||
|
+ if libvitastor_client.found()
|
||||||
|
+ if cc.links('''
|
||||||
|
+ #include <vitastor_c.h>
|
||||||
|
+ int main(void) {
|
||||||
|
+ vitastor_c_create_qemu(0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0);
|
||||||
|
+ return 0;
|
||||||
|
+ }''', dependencies: libvitastor_client)
|
||||||
|
+ vitastor = declare_dependency(dependencies: libvitastor_client)
|
||||||
|
+ elif get_option('vitastor').enabled()
|
||||||
|
+ error('could not link libvitastor_client')
|
||||||
|
+ else
|
||||||
|
+ warning('could not link libvitastor_client, disabling')
|
||||||
|
+ endif
|
||||||
|
+ endif
|
||||||
|
+endif
|
||||||
|
+
|
||||||
|
glusterfs = not_found
|
||||||
|
glusterfs_ftruncate_has_stat = false
|
||||||
|
glusterfs_iocb_has_stat = false
|
||||||
|
@@ -1799,6 +1819,7 @@ config_host_data.set('CONFIG_NUMA', numa.found())
|
||||||
|
config_host_data.set('CONFIG_OPENGL', opengl.found())
|
||||||
|
config_host_data.set('CONFIG_PROFILER', get_option('profiler'))
|
||||||
|
config_host_data.set('CONFIG_RBD', rbd.found())
|
||||||
|
+config_host_data.set('CONFIG_VITASTOR', vitastor.found())
|
||||||
|
config_host_data.set('CONFIG_RDMA', rdma.found())
|
||||||
|
config_host_data.set('CONFIG_SDL', sdl.found())
|
||||||
|
config_host_data.set('CONFIG_SDL_IMAGE', sdl_image.found())
|
||||||
|
@@ -3954,6 +3975,7 @@ if spice_protocol.found()
|
||||||
|
summary_info += {' spice server support': spice}
|
||||||
|
endif
|
||||||
|
summary_info += {'rbd support': rbd}
|
||||||
|
+summary_info += {'vitastor support': vitastor}
|
||||||
|
summary_info += {'smartcard support': cacard}
|
||||||
|
summary_info += {'U2F support': u2f}
|
||||||
|
summary_info += {'libusb': libusb}
|
||||||
|
diff --git a/meson_options.txt b/meson_options.txt
|
||||||
|
index e58e158396..9747b38fd0 100644
|
||||||
|
--- a/meson_options.txt
|
||||||
|
+++ b/meson_options.txt
|
||||||
|
@@ -167,6 +167,8 @@ option('lzo', type : 'feature', value : 'auto',
|
||||||
|
description: 'lzo compression support')
|
||||||
|
option('rbd', type : 'feature', value : 'auto',
|
||||||
|
description: 'Ceph block device driver')
|
||||||
|
+option('vitastor', type : 'feature', value : 'auto',
|
||||||
|
+ description: 'Vitastor block device driver')
|
||||||
|
option('opengl', type : 'feature', value : 'auto',
|
||||||
|
description: 'OpenGL support')
|
||||||
|
option('rdma', type : 'feature', value : 'auto',
|
||||||
|
diff --git a/qapi/block-core.json b/qapi/block-core.json
|
||||||
|
index 2173e7734a..5a4900b322 100644
|
||||||
|
--- a/qapi/block-core.json
|
||||||
|
+++ b/qapi/block-core.json
|
||||||
|
@@ -2955,7 +2955,7 @@
|
||||||
|
'luks', 'nbd', 'nfs', 'null-aio', 'null-co', 'nvme', 'parallels',
|
||||||
|
'preallocate', 'qcow', 'qcow2', 'qed', 'quorum', 'raw', 'rbd',
|
||||||
|
{ 'name': 'replication', 'if': 'CONFIG_REPLICATION' },
|
||||||
|
- 'ssh', 'throttle', 'vdi', 'vhdx', 'vmdk', 'vpc', 'vvfat' ] }
|
||||||
|
+ 'ssh', 'throttle', 'vdi', 'vhdx', 'vitastor', 'vmdk', 'vpc', 'vvfat' ] }
|
||||||
|
|
||||||
|
##
|
||||||
|
# @BlockdevOptionsFile:
|
||||||
|
@@ -3883,6 +3883,28 @@
|
||||||
|
'*key-secret': 'str',
|
||||||
|
'*server': ['InetSocketAddressBase'] } }
|
||||||
|
|
||||||
|
+##
|
||||||
|
+# @BlockdevOptionsVitastor:
|
||||||
|
+#
|
||||||
|
+# Driver specific block device options for vitastor
|
||||||
|
+#
|
||||||
|
+# @image: Image name
|
||||||
|
+# @inode: Inode number
|
||||||
|
+# @pool: Pool ID
|
||||||
|
+# @size: Desired image size in bytes
|
||||||
|
+# @config-path: Path to Vitastor configuration
|
||||||
|
+# @etcd-host: etcd connection address(es)
|
||||||
|
+# @etcd-prefix: etcd key/value prefix
|
||||||
|
+##
|
||||||
|
+{ 'struct': 'BlockdevOptionsVitastor',
|
||||||
|
+ 'data': { '*inode': 'uint64',
|
||||||
|
+ '*pool': 'uint64',
|
||||||
|
+ '*size': 'uint64',
|
||||||
|
+ '*image': 'str',
|
||||||
|
+ '*config-path': 'str',
|
||||||
|
+ '*etcd-host': 'str',
|
||||||
|
+ '*etcd-prefix': 'str' } }
|
||||||
|
+
|
||||||
|
##
|
||||||
|
# @ReplicationMode:
|
||||||
|
#
|
||||||
|
@@ -4327,6 +4349,7 @@
|
||||||
|
'throttle': 'BlockdevOptionsThrottle',
|
||||||
|
'vdi': 'BlockdevOptionsGenericFormat',
|
||||||
|
'vhdx': 'BlockdevOptionsGenericFormat',
|
||||||
|
+ 'vitastor': 'BlockdevOptionsVitastor',
|
||||||
|
'vmdk': 'BlockdevOptionsGenericCOWFormat',
|
||||||
|
'vpc': 'BlockdevOptionsGenericFormat',
|
||||||
|
'vvfat': 'BlockdevOptionsVVFAT'
|
||||||
|
@@ -4717,6 +4740,17 @@
|
||||||
|
'*cluster-size' : 'size',
|
||||||
|
'*encrypt' : 'RbdEncryptionCreateOptions' } }
|
||||||
|
|
||||||
|
+##
|
||||||
|
+# @BlockdevCreateOptionsVitastor:
|
||||||
|
+#
|
||||||
|
+# Driver specific image creation options for Vitastor.
|
||||||
|
+#
|
||||||
|
+# @size: Size of the virtual disk in bytes
|
||||||
|
+##
|
||||||
|
+{ 'struct': 'BlockdevCreateOptionsVitastor',
|
||||||
|
+ 'data': { 'location': 'BlockdevOptionsVitastor',
|
||||||
|
+ 'size': 'size' } }
|
||||||
|
+
|
||||||
|
##
|
||||||
|
# @BlockdevVmdkSubformat:
|
||||||
|
#
|
||||||
|
@@ -4915,6 +4949,7 @@
|
||||||
|
'ssh': 'BlockdevCreateOptionsSsh',
|
||||||
|
'vdi': 'BlockdevCreateOptionsVdi',
|
||||||
|
'vhdx': 'BlockdevCreateOptionsVhdx',
|
||||||
|
+ 'vitastor': 'BlockdevCreateOptionsVitastor',
|
||||||
|
'vmdk': 'BlockdevCreateOptionsVmdk',
|
||||||
|
'vpc': 'BlockdevCreateOptionsVpc'
|
||||||
|
} }
|
||||||
|
diff --git a/scripts/ci/org.centos/stream/8/x86_64/configure b/scripts/ci/org.centos/stream/8/x86_64/configure
|
||||||
|
index a7f92aff90..53dc55be2e 100755
|
||||||
|
--- a/scripts/ci/org.centos/stream/8/x86_64/configure
|
||||||
|
+++ b/scripts/ci/org.centos/stream/8/x86_64/configure
|
||||||
|
@@ -31,7 +31,7 @@
|
||||||
|
--with-git=meson \
|
||||||
|
--with-git-submodules=update \
|
||||||
|
--target-list="x86_64-softmmu" \
|
||||||
|
---block-drv-rw-whitelist="qcow2,raw,file,host_device,nbd,iscsi,rbd,blkdebug,luks,null-co,nvme,copy-on-read,throttle,gluster" \
|
||||||
|
+--block-drv-rw-whitelist="qcow2,raw,file,host_device,nbd,iscsi,rbd,vitastor,blkdebug,luks,null-co,nvme,copy-on-read,throttle,gluster" \
|
||||||
|
--audio-drv-list="" \
|
||||||
|
--block-drv-ro-whitelist="vmdk,vhdx,vpc,https,ssh" \
|
||||||
|
--with-coroutine=ucontext \
|
||||||
|
@@ -179,6 +179,7 @@
|
||||||
|
--enable-opengl \
|
||||||
|
--enable-pie \
|
||||||
|
--enable-rbd \
|
||||||
|
+--enable-vitastor \
|
||||||
|
--enable-rdma \
|
||||||
|
--enable-seccomp \
|
||||||
|
--enable-snappy \
|
||||||
|
diff --git a/scripts/meson-buildoptions.sh b/scripts/meson-buildoptions.sh
|
||||||
|
index 359b04e0e6..f5b85ba78c 100644
|
||||||
|
--- a/scripts/meson-buildoptions.sh
|
||||||
|
+++ b/scripts/meson-buildoptions.sh
|
||||||
|
@@ -135,6 +135,7 @@ meson_options_help() {
|
||||||
|
printf "%s\n" ' qed qed image format support'
|
||||||
|
printf "%s\n" ' qga-vss build QGA VSS support (broken with MinGW)'
|
||||||
|
printf "%s\n" ' rbd Ceph block device driver'
|
||||||
|
+ printf "%s\n" ' vitastor Vitastor block device driver'
|
||||||
|
printf "%s\n" ' rdma Enable RDMA-based migration'
|
||||||
|
printf "%s\n" ' replication replication support'
|
||||||
|
printf "%s\n" ' sdl SDL user interface'
|
||||||
|
@@ -370,6 +371,8 @@ _meson_option_parse() {
|
||||||
|
--disable-qom-cast-debug) printf "%s" -Dqom_cast_debug=false ;;
|
||||||
|
--enable-rbd) printf "%s" -Drbd=enabled ;;
|
||||||
|
--disable-rbd) printf "%s" -Drbd=disabled ;;
|
||||||
|
+ --enable-vitastor) printf "%s" -Dvitastor=enabled ;;
|
||||||
|
+ --disable-vitastor) printf "%s" -Dvitastor=disabled ;;
|
||||||
|
--enable-rdma) printf "%s" -Drdma=enabled ;;
|
||||||
|
--disable-rdma) printf "%s" -Drdma=disabled ;;
|
||||||
|
--enable-replication) printf "%s" -Dreplication=enabled ;;
|
190
patches/qemu-7.2-vitastor.patch
Normal file
190
patches/qemu-7.2-vitastor.patch
Normal file
@@ -0,0 +1,190 @@
|
|||||||
|
diff --git a/block/meson.build b/block/meson.build
|
||||||
|
index b7c68b83a3..95d8a6f15d 100644
|
||||||
|
--- a/block/meson.build
|
||||||
|
+++ b/block/meson.build
|
||||||
|
@@ -100,6 +100,7 @@ foreach m : [
|
||||||
|
[libnfs, 'nfs', files('nfs.c')],
|
||||||
|
[libssh, 'ssh', files('ssh.c')],
|
||||||
|
[rbd, 'rbd', files('rbd.c')],
|
||||||
|
+ [vitastor, 'vitastor', files('vitastor.c')],
|
||||||
|
]
|
||||||
|
if m[0].found()
|
||||||
|
module_ss = ss.source_set()
|
||||||
|
diff --git a/meson.build b/meson.build
|
||||||
|
index 5c6b5a1c75..f31f73612e 100644
|
||||||
|
--- a/meson.build
|
||||||
|
+++ b/meson.build
|
||||||
|
@@ -1026,6 +1026,26 @@ if not get_option('rbd').auto() or have_block
|
||||||
|
endif
|
||||||
|
endif
|
||||||
|
|
||||||
|
+vitastor = not_found
|
||||||
|
+if not get_option('vitastor').auto() or have_block
|
||||||
|
+ libvitastor_client = cc.find_library('vitastor_client', has_headers: ['vitastor_c.h'],
|
||||||
|
+ required: get_option('vitastor'), kwargs: static_kwargs)
|
||||||
|
+ if libvitastor_client.found()
|
||||||
|
+ if cc.links('''
|
||||||
|
+ #include <vitastor_c.h>
|
||||||
|
+ int main(void) {
|
||||||
|
+ vitastor_c_create_qemu(0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0);
|
||||||
|
+ return 0;
|
||||||
|
+ }''', dependencies: libvitastor_client)
|
||||||
|
+ vitastor = declare_dependency(dependencies: libvitastor_client)
|
||||||
|
+ elif get_option('vitastor').enabled()
|
||||||
|
+ error('could not link libvitastor_client')
|
||||||
|
+ else
|
||||||
|
+ warning('could not link libvitastor_client, disabling')
|
||||||
|
+ endif
|
||||||
|
+ endif
|
||||||
|
+endif
|
||||||
|
+
|
||||||
|
glusterfs = not_found
|
||||||
|
glusterfs_ftruncate_has_stat = false
|
||||||
|
glusterfs_iocb_has_stat = false
|
||||||
|
@@ -1861,6 +1881,7 @@ config_host_data.set('CONFIG_NUMA', numa.found())
|
||||||
|
config_host_data.set('CONFIG_OPENGL', opengl.found())
|
||||||
|
config_host_data.set('CONFIG_PROFILER', get_option('profiler'))
|
||||||
|
config_host_data.set('CONFIG_RBD', rbd.found())
|
||||||
|
+config_host_data.set('CONFIG_VITASTOR', vitastor.found())
|
||||||
|
config_host_data.set('CONFIG_RDMA', rdma.found())
|
||||||
|
config_host_data.set('CONFIG_SDL', sdl.found())
|
||||||
|
config_host_data.set('CONFIG_SDL_IMAGE', sdl_image.found())
|
||||||
|
@@ -3945,6 +3966,7 @@ if spice_protocol.found()
|
||||||
|
summary_info += {' spice server support': spice}
|
||||||
|
endif
|
||||||
|
summary_info += {'rbd support': rbd}
|
||||||
|
+summary_info += {'vitastor support': vitastor}
|
||||||
|
summary_info += {'smartcard support': cacard}
|
||||||
|
summary_info += {'U2F support': u2f}
|
||||||
|
summary_info += {'libusb': libusb}
|
||||||
|
diff --git a/meson_options.txt b/meson_options.txt
|
||||||
|
index 4b749ca549..6b37bd6b77 100644
|
||||||
|
--- a/meson_options.txt
|
||||||
|
+++ b/meson_options.txt
|
||||||
|
@@ -169,6 +169,8 @@ option('lzo', type : 'feature', value : 'auto',
|
||||||
|
description: 'lzo compression support')
|
||||||
|
option('rbd', type : 'feature', value : 'auto',
|
||||||
|
description: 'Ceph block device driver')
|
||||||
|
+option('vitastor', type : 'feature', value : 'auto',
|
||||||
|
+ description: 'Vitastor block device driver')
|
||||||
|
option('opengl', type : 'feature', value : 'auto',
|
||||||
|
description: 'OpenGL support')
|
||||||
|
option('rdma', type : 'feature', value : 'auto',
|
||||||
|
diff --git a/qapi/block-core.json b/qapi/block-core.json
|
||||||
|
index 95ac4fa634..7a240827e4 100644
|
||||||
|
--- a/qapi/block-core.json
|
||||||
|
+++ b/qapi/block-core.json
|
||||||
|
@@ -2959,7 +2959,7 @@
|
||||||
|
'parallels', 'preallocate', 'qcow', 'qcow2', 'qed', 'quorum',
|
||||||
|
'raw', 'rbd',
|
||||||
|
{ 'name': 'replication', 'if': 'CONFIG_REPLICATION' },
|
||||||
|
- 'ssh', 'throttle', 'vdi', 'vhdx',
|
||||||
|
+ 'ssh', 'throttle', 'vdi', 'vhdx', 'vitastor',
|
||||||
|
{ 'name': 'virtio-blk-vfio-pci', 'if': 'CONFIG_BLKIO' },
|
||||||
|
{ 'name': 'virtio-blk-vhost-user', 'if': 'CONFIG_BLKIO' },
|
||||||
|
{ 'name': 'virtio-blk-vhost-vdpa', 'if': 'CONFIG_BLKIO' },
|
||||||
|
@@ -3957,6 +3957,28 @@
|
||||||
|
'*key-secret': 'str',
|
||||||
|
'*server': ['InetSocketAddressBase'] } }
|
||||||
|
|
||||||
|
+##
|
||||||
|
+# @BlockdevOptionsVitastor:
|
||||||
|
+#
|
||||||
|
+# Driver specific block device options for vitastor
|
||||||
|
+#
|
||||||
|
+# @image: Image name
|
||||||
|
+# @inode: Inode number
|
||||||
|
+# @pool: Pool ID
|
||||||
|
+# @size: Desired image size in bytes
|
||||||
|
+# @config-path: Path to Vitastor configuration
|
||||||
|
+# @etcd-host: etcd connection address(es)
|
||||||
|
+# @etcd-prefix: etcd key/value prefix
|
||||||
|
+##
|
||||||
|
+{ 'struct': 'BlockdevOptionsVitastor',
|
||||||
|
+ 'data': { '*inode': 'uint64',
|
||||||
|
+ '*pool': 'uint64',
|
||||||
|
+ '*size': 'uint64',
|
||||||
|
+ '*image': 'str',
|
||||||
|
+ '*config-path': 'str',
|
||||||
|
+ '*etcd-host': 'str',
|
||||||
|
+ '*etcd-prefix': 'str' } }
|
||||||
|
+
|
||||||
|
##
|
||||||
|
# @ReplicationMode:
|
||||||
|
#
|
||||||
|
@@ -4405,6 +4427,7 @@
|
||||||
|
'throttle': 'BlockdevOptionsThrottle',
|
||||||
|
'vdi': 'BlockdevOptionsGenericFormat',
|
||||||
|
'vhdx': 'BlockdevOptionsGenericFormat',
|
||||||
|
+ 'vitastor': 'BlockdevOptionsVitastor',
|
||||||
|
'virtio-blk-vfio-pci':
|
||||||
|
{ 'type': 'BlockdevOptionsVirtioBlkVfioPci',
|
||||||
|
'if': 'CONFIG_BLKIO' },
|
||||||
|
@@ -4804,6 +4827,17 @@
|
||||||
|
'*cluster-size' : 'size',
|
||||||
|
'*encrypt' : 'RbdEncryptionCreateOptions' } }
|
||||||
|
|
||||||
|
+##
|
||||||
|
+# @BlockdevCreateOptionsVitastor:
|
||||||
|
+#
|
||||||
|
+# Driver specific image creation options for Vitastor.
|
||||||
|
+#
|
||||||
|
+# @size: Size of the virtual disk in bytes
|
||||||
|
+##
|
||||||
|
+{ 'struct': 'BlockdevCreateOptionsVitastor',
|
||||||
|
+ 'data': { 'location': 'BlockdevOptionsVitastor',
|
||||||
|
+ 'size': 'size' } }
|
||||||
|
+
|
||||||
|
##
|
||||||
|
# @BlockdevVmdkSubformat:
|
||||||
|
#
|
||||||
|
@@ -5002,6 +5036,7 @@
|
||||||
|
'ssh': 'BlockdevCreateOptionsSsh',
|
||||||
|
'vdi': 'BlockdevCreateOptionsVdi',
|
||||||
|
'vhdx': 'BlockdevCreateOptionsVhdx',
|
||||||
|
+ 'vitastor': 'BlockdevCreateOptionsVitastor',
|
||||||
|
'vmdk': 'BlockdevCreateOptionsVmdk',
|
||||||
|
'vpc': 'BlockdevCreateOptionsVpc'
|
||||||
|
} }
|
||||||
|
diff --git a/scripts/ci/org.centos/stream/8/x86_64/configure b/scripts/ci/org.centos/stream/8/x86_64/configure
|
||||||
|
index a7f92aff90..53dc55be2e 100755
|
||||||
|
--- a/scripts/ci/org.centos/stream/8/x86_64/configure
|
||||||
|
+++ b/scripts/ci/org.centos/stream/8/x86_64/configure
|
||||||
|
@@ -31,7 +31,7 @@
|
||||||
|
--with-git=meson \
|
||||||
|
--with-git-submodules=update \
|
||||||
|
--target-list="x86_64-softmmu" \
|
||||||
|
---block-drv-rw-whitelist="qcow2,raw,file,host_device,nbd,iscsi,rbd,blkdebug,luks,null-co,nvme,copy-on-read,throttle,gluster" \
|
||||||
|
+--block-drv-rw-whitelist="qcow2,raw,file,host_device,nbd,iscsi,rbd,vitastor,blkdebug,luks,null-co,nvme,copy-on-read,throttle,gluster" \
|
||||||
|
--audio-drv-list="" \
|
||||||
|
--block-drv-ro-whitelist="vmdk,vhdx,vpc,https,ssh" \
|
||||||
|
--with-coroutine=ucontext \
|
||||||
|
@@ -179,6 +179,7 @@
|
||||||
|
--enable-opengl \
|
||||||
|
--enable-pie \
|
||||||
|
--enable-rbd \
|
||||||
|
+--enable-vitastor \
|
||||||
|
--enable-rdma \
|
||||||
|
--enable-seccomp \
|
||||||
|
--enable-snappy \
|
||||||
|
diff --git a/scripts/meson-buildoptions.sh b/scripts/meson-buildoptions.sh
|
||||||
|
index aa6e30ea91..c45d21c40f 100644
|
||||||
|
--- a/scripts/meson-buildoptions.sh
|
||||||
|
+++ b/scripts/meson-buildoptions.sh
|
||||||
|
@@ -135,6 +135,7 @@ meson_options_help() {
|
||||||
|
printf "%s\n" ' qed qed image format support'
|
||||||
|
printf "%s\n" ' qga-vss build QGA VSS support (broken with MinGW)'
|
||||||
|
printf "%s\n" ' rbd Ceph block device driver'
|
||||||
|
+ printf "%s\n" ' vitastor Vitastor block device driver'
|
||||||
|
printf "%s\n" ' rdma Enable RDMA-based migration'
|
||||||
|
printf "%s\n" ' replication replication support'
|
||||||
|
printf "%s\n" ' sdl SDL user interface'
|
||||||
|
@@ -376,6 +377,8 @@ _meson_option_parse() {
|
||||||
|
--disable-qom-cast-debug) printf "%s" -Dqom_cast_debug=false ;;
|
||||||
|
--enable-rbd) printf "%s" -Drbd=enabled ;;
|
||||||
|
--disable-rbd) printf "%s" -Drbd=disabled ;;
|
||||||
|
+ --enable-vitastor) printf "%s" -Dvitastor=enabled ;;
|
||||||
|
+ --disable-vitastor) printf "%s" -Dvitastor=disabled ;;
|
||||||
|
--enable-rdma) printf "%s" -Drdma=enabled ;;
|
||||||
|
--disable-rdma) printf "%s" -Drdma=disabled ;;
|
||||||
|
--enable-replication) printf "%s" -Dreplication=enabled ;;
|
190
patches/qemu-8.0-vitastor.patch
Normal file
190
patches/qemu-8.0-vitastor.patch
Normal file
@@ -0,0 +1,190 @@
|
|||||||
|
diff --git a/block/meson.build b/block/meson.build
|
||||||
|
index 382bec0e7d..af6207dbce 100644
|
||||||
|
--- a/block/meson.build
|
||||||
|
+++ b/block/meson.build
|
||||||
|
@@ -101,6 +101,7 @@ foreach m : [
|
||||||
|
[libnfs, 'nfs', files('nfs.c')],
|
||||||
|
[libssh, 'ssh', files('ssh.c')],
|
||||||
|
[rbd, 'rbd', files('rbd.c')],
|
||||||
|
+ [vitastor, 'vitastor', files('vitastor.c')],
|
||||||
|
]
|
||||||
|
if m[0].found()
|
||||||
|
module_ss = ss.source_set()
|
||||||
|
diff --git a/meson.build b/meson.build
|
||||||
|
index c44d05a13f..ebedb42843 100644
|
||||||
|
--- a/meson.build
|
||||||
|
+++ b/meson.build
|
||||||
|
@@ -1028,6 +1028,26 @@ if not get_option('rbd').auto() or have_block
|
||||||
|
endif
|
||||||
|
endif
|
||||||
|
|
||||||
|
+vitastor = not_found
|
||||||
|
+if not get_option('vitastor').auto() or have_block
|
||||||
|
+ libvitastor_client = cc.find_library('vitastor_client', has_headers: ['vitastor_c.h'],
|
||||||
|
+ required: get_option('vitastor'), kwargs: static_kwargs)
|
||||||
|
+ if libvitastor_client.found()
|
||||||
|
+ if cc.links('''
|
||||||
|
+ #include <vitastor_c.h>
|
||||||
|
+ int main(void) {
|
||||||
|
+ vitastor_c_create_qemu(0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0);
|
||||||
|
+ return 0;
|
||||||
|
+ }''', dependencies: libvitastor_client)
|
||||||
|
+ vitastor = declare_dependency(dependencies: libvitastor_client)
|
||||||
|
+ elif get_option('vitastor').enabled()
|
||||||
|
+ error('could not link libvitastor_client')
|
||||||
|
+ else
|
||||||
|
+ warning('could not link libvitastor_client, disabling')
|
||||||
|
+ endif
|
||||||
|
+ endif
|
||||||
|
+endif
|
||||||
|
+
|
||||||
|
glusterfs = not_found
|
||||||
|
glusterfs_ftruncate_has_stat = false
|
||||||
|
glusterfs_iocb_has_stat = false
|
||||||
|
@@ -1878,6 +1898,7 @@ endif
|
||||||
|
config_host_data.set('CONFIG_OPENGL', opengl.found())
|
||||||
|
config_host_data.set('CONFIG_PROFILER', get_option('profiler'))
|
||||||
|
config_host_data.set('CONFIG_RBD', rbd.found())
|
||||||
|
+config_host_data.set('CONFIG_VITASTOR', vitastor.found())
|
||||||
|
config_host_data.set('CONFIG_RDMA', rdma.found())
|
||||||
|
config_host_data.set('CONFIG_SDL', sdl.found())
|
||||||
|
config_host_data.set('CONFIG_SDL_IMAGE', sdl_image.found())
|
||||||
|
@@ -4002,6 +4023,7 @@ if spice_protocol.found()
|
||||||
|
summary_info += {' spice server support': spice}
|
||||||
|
endif
|
||||||
|
summary_info += {'rbd support': rbd}
|
||||||
|
+summary_info += {'vitastor support': vitastor}
|
||||||
|
summary_info += {'smartcard support': cacard}
|
||||||
|
summary_info += {'U2F support': u2f}
|
||||||
|
summary_info += {'libusb': libusb}
|
||||||
|
diff --git a/meson_options.txt b/meson_options.txt
|
||||||
|
index fc9447d267..c4ac55c283 100644
|
||||||
|
--- a/meson_options.txt
|
||||||
|
+++ b/meson_options.txt
|
||||||
|
@@ -173,6 +173,8 @@ option('lzo', type : 'feature', value : 'auto',
|
||||||
|
description: 'lzo compression support')
|
||||||
|
option('rbd', type : 'feature', value : 'auto',
|
||||||
|
description: 'Ceph block device driver')
|
||||||
|
+option('vitastor', type : 'feature', value : 'auto',
|
||||||
|
+ description: 'Vitastor block device driver')
|
||||||
|
option('opengl', type : 'feature', value : 'auto',
|
||||||
|
description: 'OpenGL support')
|
||||||
|
option('rdma', type : 'feature', value : 'auto',
|
||||||
|
diff --git a/qapi/block-core.json b/qapi/block-core.json
|
||||||
|
index c05ad0c07e..f5eb701604 100644
|
||||||
|
--- a/qapi/block-core.json
|
||||||
|
+++ b/qapi/block-core.json
|
||||||
|
@@ -3054,7 +3054,7 @@
|
||||||
|
'parallels', 'preallocate', 'qcow', 'qcow2', 'qed', 'quorum',
|
||||||
|
'raw', 'rbd',
|
||||||
|
{ 'name': 'replication', 'if': 'CONFIG_REPLICATION' },
|
||||||
|
- 'ssh', 'throttle', 'vdi', 'vhdx',
|
||||||
|
+ 'ssh', 'throttle', 'vdi', 'vhdx', 'vitastor',
|
||||||
|
{ 'name': 'virtio-blk-vfio-pci', 'if': 'CONFIG_BLKIO' },
|
||||||
|
{ 'name': 'virtio-blk-vhost-user', 'if': 'CONFIG_BLKIO' },
|
||||||
|
{ 'name': 'virtio-blk-vhost-vdpa', 'if': 'CONFIG_BLKIO' },
|
||||||
|
@@ -4073,6 +4073,28 @@
|
||||||
|
'*key-secret': 'str',
|
||||||
|
'*server': ['InetSocketAddressBase'] } }
|
||||||
|
|
||||||
|
+##
|
||||||
|
+# @BlockdevOptionsVitastor:
|
||||||
|
+#
|
||||||
|
+# Driver specific block device options for vitastor
|
||||||
|
+#
|
||||||
|
+# @image: Image name
|
||||||
|
+# @inode: Inode number
|
||||||
|
+# @pool: Pool ID
|
||||||
|
+# @size: Desired image size in bytes
|
||||||
|
+# @config-path: Path to Vitastor configuration
|
||||||
|
+# @etcd-host: etcd connection address(es)
|
||||||
|
+# @etcd-prefix: etcd key/value prefix
|
||||||
|
+##
|
||||||
|
+{ 'struct': 'BlockdevOptionsVitastor',
|
||||||
|
+ 'data': { '*inode': 'uint64',
|
||||||
|
+ '*pool': 'uint64',
|
||||||
|
+ '*size': 'uint64',
|
||||||
|
+ '*image': 'str',
|
||||||
|
+ '*config-path': 'str',
|
||||||
|
+ '*etcd-host': 'str',
|
||||||
|
+ '*etcd-prefix': 'str' } }
|
||||||
|
+
|
||||||
|
##
|
||||||
|
# @ReplicationMode:
|
||||||
|
#
|
||||||
|
@@ -4521,6 +4543,7 @@
|
||||||
|
'throttle': 'BlockdevOptionsThrottle',
|
||||||
|
'vdi': 'BlockdevOptionsGenericFormat',
|
||||||
|
'vhdx': 'BlockdevOptionsGenericFormat',
|
||||||
|
+ 'vitastor': 'BlockdevOptionsVitastor',
|
||||||
|
'virtio-blk-vfio-pci':
|
||||||
|
{ 'type': 'BlockdevOptionsVirtioBlkVfioPci',
|
||||||
|
'if': 'CONFIG_BLKIO' },
|
||||||
|
@@ -4920,6 +4943,17 @@
|
||||||
|
'*cluster-size' : 'size',
|
||||||
|
'*encrypt' : 'RbdEncryptionCreateOptions' } }
|
||||||
|
|
||||||
|
+##
|
||||||
|
+# @BlockdevCreateOptionsVitastor:
|
||||||
|
+#
|
||||||
|
+# Driver specific image creation options for Vitastor.
|
||||||
|
+#
|
||||||
|
+# @size: Size of the virtual disk in bytes
|
||||||
|
+##
|
||||||
|
+{ 'struct': 'BlockdevCreateOptionsVitastor',
|
||||||
|
+ 'data': { 'location': 'BlockdevOptionsVitastor',
|
||||||
|
+ 'size': 'size' } }
|
||||||
|
+
|
||||||
|
##
|
||||||
|
# @BlockdevVmdkSubformat:
|
||||||
|
#
|
||||||
|
@@ -5118,6 +5152,7 @@
|
||||||
|
'ssh': 'BlockdevCreateOptionsSsh',
|
||||||
|
'vdi': 'BlockdevCreateOptionsVdi',
|
||||||
|
'vhdx': 'BlockdevCreateOptionsVhdx',
|
||||||
|
+ 'vitastor': 'BlockdevCreateOptionsVitastor',
|
||||||
|
'vmdk': 'BlockdevCreateOptionsVmdk',
|
||||||
|
'vpc': 'BlockdevCreateOptionsVpc'
|
||||||
|
} }
|
||||||
|
diff --git a/scripts/ci/org.centos/stream/8/x86_64/configure b/scripts/ci/org.centos/stream/8/x86_64/configure
|
||||||
|
index 6e8983f39c..1b0b9fcf3e 100755
|
||||||
|
--- a/scripts/ci/org.centos/stream/8/x86_64/configure
|
||||||
|
+++ b/scripts/ci/org.centos/stream/8/x86_64/configure
|
||||||
|
@@ -32,7 +32,7 @@
|
||||||
|
--with-git=meson \
|
||||||
|
--with-git-submodules=update \
|
||||||
|
--target-list="x86_64-softmmu" \
|
||||||
|
---block-drv-rw-whitelist="qcow2,raw,file,host_device,nbd,iscsi,rbd,blkdebug,luks,null-co,nvme,copy-on-read,throttle,gluster" \
|
||||||
|
+--block-drv-rw-whitelist="qcow2,raw,file,host_device,nbd,iscsi,rbd,vitastor,blkdebug,luks,null-co,nvme,copy-on-read,throttle,gluster" \
|
||||||
|
--audio-drv-list="" \
|
||||||
|
--block-drv-ro-whitelist="vmdk,vhdx,vpc,https,ssh" \
|
||||||
|
--with-coroutine=ucontext \
|
||||||
|
@@ -179,6 +179,7 @@
|
||||||
|
--enable-opengl \
|
||||||
|
--enable-pie \
|
||||||
|
--enable-rbd \
|
||||||
|
+--enable-vitastor \
|
||||||
|
--enable-rdma \
|
||||||
|
--enable-seccomp \
|
||||||
|
--enable-snappy \
|
||||||
|
diff --git a/scripts/meson-buildoptions.sh b/scripts/meson-buildoptions.sh
|
||||||
|
index 009fab1515..95914e6ebc 100644
|
||||||
|
--- a/scripts/meson-buildoptions.sh
|
||||||
|
+++ b/scripts/meson-buildoptions.sh
|
||||||
|
@@ -142,6 +142,7 @@ meson_options_help() {
|
||||||
|
printf "%s\n" ' qed qed image format support'
|
||||||
|
printf "%s\n" ' qga-vss build QGA VSS support (broken with MinGW)'
|
||||||
|
printf "%s\n" ' rbd Ceph block device driver'
|
||||||
|
+ printf "%s\n" ' vitastor Vitastor block device driver'
|
||||||
|
printf "%s\n" ' rdma Enable RDMA-based migration'
|
||||||
|
printf "%s\n" ' replication replication support'
|
||||||
|
printf "%s\n" ' sdl SDL user interface'
|
||||||
|
@@ -388,6 +389,8 @@ _meson_option_parse() {
|
||||||
|
--disable-qom-cast-debug) printf "%s" -Dqom_cast_debug=false ;;
|
||||||
|
--enable-rbd) printf "%s" -Drbd=enabled ;;
|
||||||
|
--disable-rbd) printf "%s" -Drbd=disabled ;;
|
||||||
|
+ --enable-vitastor) printf "%s" -Dvitastor=enabled ;;
|
||||||
|
+ --disable-vitastor) printf "%s" -Dvitastor=disabled ;;
|
||||||
|
--enable-rdma) printf "%s" -Drdma=enabled ;;
|
||||||
|
--disable-rdma) printf "%s" -Drdma=disabled ;;
|
||||||
|
--enable-replication) printf "%s" -Dreplication=enabled ;;
|
@@ -9,7 +9,7 @@ for i in "$DIR"/qemu-*-vitastor.patch "$DIR"/pve-qemu-*-vitastor.patch; do
|
|||||||
echo '===================================================================' >> $i
|
echo '===================================================================' >> $i
|
||||||
echo '--- /dev/null' >> $i
|
echo '--- /dev/null' >> $i
|
||||||
echo '+++ a/block/vitastor.c' >> $i
|
echo '+++ a/block/vitastor.c' >> $i
|
||||||
echo '@@ -0,0 +1,'$(wc -l "$DIR"/../src/qemu_driver.c)' @@' >> $i
|
echo '@@ -0,0 +1,'$(wc -l "$DIR"/../src/qemu_driver.c | cut -d ' ' -f 1)' @@' >> $i
|
||||||
cat "$DIR"/../src/qemu_driver.c | sed 's/^/+/' >> $i
|
cat "$DIR"/../src/qemu_driver.c | sed 's/^/+/' >> $i
|
||||||
fi
|
fi
|
||||||
done
|
done
|
||||||
|
@@ -7,13 +7,12 @@ set -e
|
|||||||
VITASTOR=$(dirname $0)
|
VITASTOR=$(dirname $0)
|
||||||
VITASTOR=$(realpath "$VITASTOR/..")
|
VITASTOR=$(realpath "$VITASTOR/..")
|
||||||
|
|
||||||
if [ -d /opt/rh/gcc-toolset-9 ]; then
|
EL=$(rpm --eval '%dist')
|
||||||
|
if [ "$EL" = ".el8" ]; then
|
||||||
# CentOS 8
|
# CentOS 8
|
||||||
EL=8
|
|
||||||
. /opt/rh/gcc-toolset-9/enable
|
. /opt/rh/gcc-toolset-9/enable
|
||||||
else
|
elif [ "$EL" = ".el7" ]; then
|
||||||
# CentOS 7
|
# CentOS 7
|
||||||
EL=7
|
|
||||||
. /opt/rh/devtoolset-9/enable
|
. /opt/rh/devtoolset-9/enable
|
||||||
fi
|
fi
|
||||||
cd ~/rpmbuild/SPECS
|
cd ~/rpmbuild/SPECS
|
||||||
@@ -25,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-0.7.0/#' --exclude 'rpm/*.rpm' -czf $VITASTOR/../vitastor-0.7.0$(rpm --eval '%dist').tar.gz *
|
tar --transform 's#^#vitastor-0.8.9/#' --exclude 'rpm/*.rpm' -czf $VITASTOR/../vitastor-0.8.9$(rpm --eval '%dist').tar.gz *
|
||||||
|
@@ -58,7 +58,7 @@
|
|||||||
+BuildRequires: gperftools-devel
|
+BuildRequires: gperftools-devel
|
||||||
+BuildRequires: libusbx-devel >= 1.0.21
|
+BuildRequires: libusbx-devel >= 1.0.21
|
||||||
%if %{have_usbredir}
|
%if %{have_usbredir}
|
||||||
BuildRequires: usbredir-devel >= 0.7.1
|
BuildRequires: usbredir-devel >= 0.8.2
|
||||||
%endif
|
%endif
|
||||||
@@ -856,12 +861,13 @@ BuildRequires: virglrenderer-devel
|
@@ -856,12 +861,13 @@ BuildRequires: virglrenderer-devel
|
||||||
# For smartcard NSS support
|
# For smartcard NSS support
|
||||||
|
93
rpm/qemu-kvm-7.0-el9.spec.patch
Normal file
93
rpm/qemu-kvm-7.0-el9.spec.patch
Normal file
@@ -0,0 +1,93 @@
|
|||||||
|
--- qemu-kvm.spec.orig 2023-02-28 08:04:06.000000000 +0000
|
||||||
|
+++ qemu-kvm.spec 2023-04-27 22:29:18.094878829 +0000
|
||||||
|
@@ -100,8 +100,6 @@
|
||||||
|
%endif
|
||||||
|
|
||||||
|
%global target_list %{kvm_target}-softmmu
|
||||||
|
-%global block_drivers_rw_list qcow2,raw,file,host_device,nbd,iscsi,rbd,blkdebug,luks,null-co,nvme,copy-on-read,throttle,compress
|
||||||
|
-%global block_drivers_ro_list vdi,vmdk,vhdx,vpc,https
|
||||||
|
%define qemudocdir %{_docdir}/%{name}
|
||||||
|
%global firmwaredirs "%{_datadir}/qemu-firmware:%{_datadir}/ipxe/qemu:%{_datadir}/seavgabios:%{_datadir}/seabios"
|
||||||
|
|
||||||
|
@@ -129,6 +127,7 @@ Requires: %{name}-device-usb-host = %{ep
|
||||||
|
Requires: %{name}-device-usb-redirect = %{epoch}:%{version}-%{release} \
|
||||||
|
%endif \
|
||||||
|
Requires: %{name}-block-rbd = %{epoch}:%{version}-%{release} \
|
||||||
|
+Requires: %{name}-block-vitastor = %{epoch}:%{version}-%{release}\
|
||||||
|
Requires: %{name}-audio-pa = %{epoch}:%{version}-%{release}
|
||||||
|
|
||||||
|
# Since SPICE is removed from RHEL-9, the following Obsoletes:
|
||||||
|
@@ -151,7 +150,7 @@ Obsoletes: %{name}-block-ssh <= %{epoch}
|
||||||
|
Summary: QEMU is a machine emulator and virtualizer
|
||||||
|
Name: qemu-kvm
|
||||||
|
Version: 7.0.0
|
||||||
|
-Release: 13%{?rcrel}%{?dist}%{?cc_suffix}.2
|
||||||
|
+Release: 13.vitastor%{?rcrel}%{?dist}%{?cc_suffix}
|
||||||
|
# Epoch because we pushed a qemu-1.0 package. AIUI this can't ever be dropped
|
||||||
|
# Epoch 15 used for RHEL 8
|
||||||
|
# Epoch 17 used for RHEL 9 (due to release versioning offset in RHEL 8.5)
|
||||||
|
@@ -174,6 +173,7 @@ Source28: 95-kvm-memlock.conf
|
||||||
|
Source30: kvm-s390x.conf
|
||||||
|
Source31: kvm-x86.conf
|
||||||
|
Source36: README.tests
|
||||||
|
+Source37: qemu-vitastor.c
|
||||||
|
|
||||||
|
|
||||||
|
Patch0004: 0004-Initial-redhat-build.patch
|
||||||
|
@@ -498,6 +498,7 @@ Patch171: kvm-i386-do-kvm_put_msr_featur
|
||||||
|
Patch172: kvm-target-i386-kvm-fix-kvmclock_current_nsec-Assertion-.patch
|
||||||
|
# For bz#2168221 - while live-migrating many instances concurrently, libvirt sometimes return internal error: migration was active, but no RAM info was set [rhel-9.1.0.z]
|
||||||
|
Patch173: kvm-migration-Read-state-once.patch
|
||||||
|
+Patch174: qemu-7.0-vitastor.patch
|
||||||
|
|
||||||
|
# Source-git patches
|
||||||
|
|
||||||
|
@@ -531,6 +532,7 @@ BuildRequires: libcurl-devel
|
||||||
|
%if %{have_block_rbd}
|
||||||
|
BuildRequires: librbd-devel
|
||||||
|
%endif
|
||||||
|
+BuildRequires: vitastor-client-devel
|
||||||
|
# We need both because the 'stap' binary is probed for by configure
|
||||||
|
BuildRequires: systemtap
|
||||||
|
BuildRequires: systemtap-sdt-devel
|
||||||
|
@@ -718,6 +720,14 @@ using the rbd protocol.
|
||||||
|
%endif
|
||||||
|
|
||||||
|
|
||||||
|
+%package block-vitastor
|
||||||
|
+Summary: QEMU Vitastor block driver
|
||||||
|
+Requires: %{name}-common%{?_isa} = %{epoch}:%{version}-%{release}
|
||||||
|
+
|
||||||
|
+%description block-vitastor
|
||||||
|
+This package provides the additional Vitastor block driver for QEMU.
|
||||||
|
+
|
||||||
|
+
|
||||||
|
%package audio-pa
|
||||||
|
Summary: QEMU PulseAudio audio driver
|
||||||
|
Requires: %{name}-common%{?_isa} = %{epoch}:%{version}-%{release}
|
||||||
|
@@ -811,6 +821,7 @@ This package provides usbredir support.
|
||||||
|
%prep
|
||||||
|
%setup -q -n qemu-%{version}%{?rcstr}
|
||||||
|
%autopatch -p1
|
||||||
|
+cp %{SOURCE37} ./block/vitastor.c
|
||||||
|
|
||||||
|
%global qemu_kvm_build qemu_kvm_build
|
||||||
|
mkdir -p %{qemu_kvm_build}
|
||||||
|
@@ -1032,6 +1043,7 @@ run_configure \
|
||||||
|
%if %{have_block_rbd}
|
||||||
|
--enable-rbd \
|
||||||
|
%endif
|
||||||
|
+ --enable-vitastor \
|
||||||
|
%if %{have_librdma}
|
||||||
|
--enable-rdma \
|
||||||
|
%endif
|
||||||
|
@@ -1511,6 +1523,9 @@ useradd -r -u 107 -g qemu -G kvm -d / -s
|
||||||
|
%files block-rbd
|
||||||
|
%{_libdir}/%{name}/block-rbd.so
|
||||||
|
%endif
|
||||||
|
+%files block-vitastor
|
||||||
|
+%{_libdir}/%{name}/block-vitastor.so
|
||||||
|
+
|
||||||
|
%files audio-pa
|
||||||
|
%{_libdir}/%{name}/audio-pa.so
|
||||||
|
|
@@ -9,7 +9,8 @@ WORKDIR /root
|
|||||||
RUN rm -f /etc/yum.repos.d/CentOS-Media.repo
|
RUN rm -f /etc/yum.repos.d/CentOS-Media.repo
|
||||||
RUN yum -y --enablerepo=extras install centos-release-scl epel-release yum-utils rpm-build
|
RUN yum -y --enablerepo=extras install centos-release-scl epel-release yum-utils rpm-build
|
||||||
RUN yum -y install https://vitastor.io/rpms/centos/7/vitastor-release-1.0-1.el7.noarch.rpm
|
RUN yum -y install https://vitastor.io/rpms/centos/7/vitastor-release-1.0-1.el7.noarch.rpm
|
||||||
RUN yum -y install devtoolset-9-gcc-c++ devtoolset-9-libatomic-devel gcc make cmake gperftools-devel fio rh-nodejs12 jerasure-devel gf-complete-devel rdma-core-devel
|
RUN yum -y install devtoolset-9-gcc-c++ devtoolset-9-libatomic-devel gcc make cmake gperftools-devel \
|
||||||
|
fio rh-nodejs12 jerasure-devel libisa-l-devel gf-complete-devel rdma-core-devel
|
||||||
RUN yumdownloader --disablerepo=centos-sclo-rh --source fio
|
RUN yumdownloader --disablerepo=centos-sclo-rh --source fio
|
||||||
RUN rpm --nomd5 -i fio*.src.rpm
|
RUN rpm --nomd5 -i fio*.src.rpm
|
||||||
RUN rm -f /etc/yum.repos.d/CentOS-Media.repo
|
RUN rm -f /etc/yum.repos.d/CentOS-Media.repo
|
||||||
@@ -34,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-0.7.0.el7.tar.gz ~/rpmbuild/SOURCES; \
|
cp /root/vitastor-0.8.9.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; \
|
||||||
|
@@ -1,11 +1,11 @@
|
|||||||
Name: vitastor
|
Name: vitastor
|
||||||
Version: 0.7.0
|
Version: 0.8.9
|
||||||
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-0.7.0.el7.tar.gz
|
Source0: vitastor-0.8.9.el7.tar.gz
|
||||||
|
|
||||||
BuildRequires: liburing-devel >= 0.6
|
BuildRequires: liburing-devel >= 0.6
|
||||||
BuildRequires: gperftools-devel
|
BuildRequires: gperftools-devel
|
||||||
@@ -13,6 +13,7 @@ BuildRequires: devtoolset-9-gcc-c++
|
|||||||
BuildRequires: rh-nodejs12
|
BuildRequires: rh-nodejs12
|
||||||
BuildRequires: rh-nodejs12-npm
|
BuildRequires: rh-nodejs12-npm
|
||||||
BuildRequires: jerasure-devel
|
BuildRequires: jerasure-devel
|
||||||
|
BuildRequires: libisa-l-devel
|
||||||
BuildRequires: gf-complete-devel
|
BuildRequires: gf-complete-devel
|
||||||
BuildRequires: libibverbs-devel
|
BuildRequires: libibverbs-devel
|
||||||
BuildRequires: cmake
|
BuildRequires: cmake
|
||||||
@@ -32,8 +33,12 @@ size with configurable redundancy (replication or erasure codes/XOR).
|
|||||||
%package -n vitastor-osd
|
%package -n vitastor-osd
|
||||||
Summary: Vitastor - OSD
|
Summary: Vitastor - OSD
|
||||||
Requires: libJerasure2
|
Requires: libJerasure2
|
||||||
|
Requires: libisa-l
|
||||||
Requires: liburing >= 0.6
|
Requires: liburing >= 0.6
|
||||||
|
Requires: liburing < 2
|
||||||
Requires: vitastor-client = %{version}-%{release}
|
Requires: vitastor-client = %{version}-%{release}
|
||||||
|
Requires: util-linux
|
||||||
|
Requires: parted
|
||||||
|
|
||||||
|
|
||||||
%description -n vitastor-osd
|
%description -n vitastor-osd
|
||||||
@@ -55,6 +60,7 @@ scheduling cluster-level operations.
|
|||||||
%package -n vitastor-client
|
%package -n vitastor-client
|
||||||
Summary: Vitastor - client
|
Summary: Vitastor - client
|
||||||
Requires: liburing >= 0.6
|
Requires: liburing >= 0.6
|
||||||
|
Requires: liburing < 2
|
||||||
|
|
||||||
|
|
||||||
%description -n vitastor-client
|
%description -n vitastor-client
|
||||||
@@ -100,8 +106,11 @@ cd mon
|
|||||||
npm install
|
npm install
|
||||||
cd ..
|
cd ..
|
||||||
mkdir -p %buildroot/usr/lib/vitastor
|
mkdir -p %buildroot/usr/lib/vitastor
|
||||||
cp mon/make-osd.sh %buildroot/usr/lib/vitastor
|
|
||||||
cp -r mon %buildroot/usr/lib/vitastor
|
cp -r mon %buildroot/usr/lib/vitastor
|
||||||
|
mkdir -p %buildroot/lib/systemd/system
|
||||||
|
cp mon/vitastor.target mon/vitastor-mon.service mon/vitastor-osd@.service %buildroot/lib/systemd/system
|
||||||
|
mkdir -p %buildroot/lib/udev/rules.d
|
||||||
|
cp mon/90-vitastor.rules %buildroot/lib/udev/rules.d
|
||||||
|
|
||||||
|
|
||||||
%files
|
%files
|
||||||
@@ -110,11 +119,29 @@ cp -r mon %buildroot/usr/lib/vitastor
|
|||||||
|
|
||||||
%files -n vitastor-osd
|
%files -n vitastor-osd
|
||||||
%_bindir/vitastor-osd
|
%_bindir/vitastor-osd
|
||||||
|
%_bindir/vitastor-disk
|
||||||
%_bindir/vitastor-dump-journal
|
%_bindir/vitastor-dump-journal
|
||||||
|
/lib/systemd/system/vitastor-osd@.service
|
||||||
|
/lib/systemd/system/vitastor.target
|
||||||
|
/lib/udev/rules.d/90-vitastor.rules
|
||||||
|
|
||||||
|
|
||||||
|
%pre -n vitastor-osd
|
||||||
|
groupadd -r -f vitastor 2>/dev/null ||:
|
||||||
|
useradd -r -g vitastor -s /sbin/nologin -c "Vitastor daemons" -M -d /nonexistent vitastor 2>/dev/null ||:
|
||||||
|
install -o vitastor -g vitastor -d /var/log/vitastor
|
||||||
|
mkdir -p /etc/vitastor
|
||||||
|
|
||||||
|
|
||||||
%files -n vitastor-mon
|
%files -n vitastor-mon
|
||||||
/usr/lib/vitastor/mon
|
/usr/lib/vitastor/mon
|
||||||
|
/lib/systemd/system/vitastor-mon.service
|
||||||
|
|
||||||
|
|
||||||
|
%pre -n vitastor-mon
|
||||||
|
groupadd -r -f vitastor 2>/dev/null ||:
|
||||||
|
useradd -r -g vitastor -s /sbin/nologin -c "Vitastor daemons" -M -d /nonexistent vitastor 2>/dev/null ||:
|
||||||
|
mkdir -p /etc/vitastor
|
||||||
|
|
||||||
|
|
||||||
%files -n vitastor-client
|
%files -n vitastor-client
|
||||||
@@ -125,7 +152,6 @@ cp -r mon %buildroot/usr/lib/vitastor
|
|||||||
%_bindir/vita
|
%_bindir/vita
|
||||||
%_libdir/libvitastor_blk.so*
|
%_libdir/libvitastor_blk.so*
|
||||||
%_libdir/libvitastor_client.so*
|
%_libdir/libvitastor_client.so*
|
||||||
/usr/lib/vitastor/make-osd.sh
|
|
||||||
|
|
||||||
|
|
||||||
%files -n vitastor-client-devel
|
%files -n vitastor-client-devel
|
||||||
|
@@ -6,10 +6,12 @@ FROM centos:8
|
|||||||
WORKDIR /root
|
WORKDIR /root
|
||||||
|
|
||||||
RUN rm -f /etc/yum.repos.d/CentOS-Media.repo
|
RUN rm -f /etc/yum.repos.d/CentOS-Media.repo
|
||||||
|
RUN sed -i 's/^mirrorlist=/#mirrorlist=/; s!#baseurl=http://mirror.centos.org/!baseurl=http://vault.centos.org/!' /etc/yum.repos.d/*.repo
|
||||||
RUN dnf -y install centos-release-advanced-virtualization epel-release dnf-plugins-core
|
RUN dnf -y install centos-release-advanced-virtualization epel-release dnf-plugins-core
|
||||||
|
RUN sed -i 's/^mirrorlist=/#mirrorlist=/; s!#baseurl=.*!baseurl=http://vault.centos.org/centos/8.4.2105/virt/$basearch/$avdir/!; s!^baseurl=.*Source/.*!baseurl=http://vault.centos.org/centos/8.4.2105/virt/Source/advanced-virtualization/!' /etc/yum.repos.d/CentOS-Advanced-Virtualization.repo
|
||||||
RUN yum -y install https://vitastor.io/rpms/centos/8/vitastor-release-1.0-1.el8.noarch.rpm
|
RUN yum -y install https://vitastor.io/rpms/centos/8/vitastor-release-1.0-1.el8.noarch.rpm
|
||||||
RUN dnf -y install gcc-toolset-9 gcc-toolset-9-gcc-c++ gperftools-devel \
|
RUN dnf -y install gcc-toolset-9 gcc-toolset-9-gcc-c++ gperftools-devel \
|
||||||
fio nodejs rpm-build jerasure-devel gf-complete-devel libibverbs-devel libarchive cmake
|
fio nodejs rpm-build jerasure-devel libisa-l-devel gf-complete-devel libibverbs-devel libarchive cmake
|
||||||
RUN dnf download --source fio
|
RUN dnf download --source fio
|
||||||
RUN rpm --nomd5 -i fio*.src.rpm
|
RUN rpm --nomd5 -i fio*.src.rpm
|
||||||
RUN cd ~/rpmbuild/SPECS && dnf builddep -y --enablerepo=powertools --spec fio.spec
|
RUN cd ~/rpmbuild/SPECS && dnf builddep -y --enablerepo=powertools --spec fio.spec
|
||||||
@@ -33,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-0.7.0.el8.tar.gz ~/rpmbuild/SOURCES; \
|
cp /root/vitastor-0.8.9.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; \
|
||||||
|
@@ -1,17 +1,18 @@
|
|||||||
Name: vitastor
|
Name: vitastor
|
||||||
Version: 0.7.0
|
Version: 0.8.9
|
||||||
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-0.7.0.el8.tar.gz
|
Source0: vitastor-0.8.9.el8.tar.gz
|
||||||
|
|
||||||
BuildRequires: liburing-devel >= 0.6
|
BuildRequires: liburing-devel >= 0.6
|
||||||
BuildRequires: gperftools-devel
|
BuildRequires: gperftools-devel
|
||||||
BuildRequires: gcc-toolset-9-gcc-c++
|
BuildRequires: gcc-toolset-9-gcc-c++
|
||||||
BuildRequires: nodejs >= 10
|
BuildRequires: nodejs >= 10
|
||||||
BuildRequires: jerasure-devel
|
BuildRequires: jerasure-devel
|
||||||
|
BuildRequires: libisa-l-devel
|
||||||
BuildRequires: gf-complete-devel
|
BuildRequires: gf-complete-devel
|
||||||
BuildRequires: libibverbs-devel
|
BuildRequires: libibverbs-devel
|
||||||
BuildRequires: cmake
|
BuildRequires: cmake
|
||||||
@@ -31,8 +32,12 @@ size with configurable redundancy (replication or erasure codes/XOR).
|
|||||||
%package -n vitastor-osd
|
%package -n vitastor-osd
|
||||||
Summary: Vitastor - OSD
|
Summary: Vitastor - OSD
|
||||||
Requires: libJerasure2
|
Requires: libJerasure2
|
||||||
|
Requires: libisa-l
|
||||||
Requires: liburing >= 0.6
|
Requires: liburing >= 0.6
|
||||||
|
Requires: liburing < 2
|
||||||
Requires: vitastor-client = %{version}-%{release}
|
Requires: vitastor-client = %{version}-%{release}
|
||||||
|
Requires: util-linux
|
||||||
|
Requires: parted
|
||||||
|
|
||||||
|
|
||||||
%description -n vitastor-osd
|
%description -n vitastor-osd
|
||||||
@@ -53,6 +58,7 @@ scheduling cluster-level operations.
|
|||||||
%package -n vitastor-client
|
%package -n vitastor-client
|
||||||
Summary: Vitastor - client
|
Summary: Vitastor - client
|
||||||
Requires: liburing >= 0.6
|
Requires: liburing >= 0.6
|
||||||
|
Requires: liburing < 2
|
||||||
|
|
||||||
|
|
||||||
%description -n vitastor-client
|
%description -n vitastor-client
|
||||||
@@ -97,8 +103,11 @@ cd mon
|
|||||||
npm install
|
npm install
|
||||||
cd ..
|
cd ..
|
||||||
mkdir -p %buildroot/usr/lib/vitastor
|
mkdir -p %buildroot/usr/lib/vitastor
|
||||||
cp mon/make-osd.sh %buildroot/usr/lib/vitastor
|
|
||||||
cp -r mon %buildroot/usr/lib/vitastor
|
cp -r mon %buildroot/usr/lib/vitastor
|
||||||
|
mkdir -p %buildroot/lib/systemd/system
|
||||||
|
cp mon/vitastor.target mon/vitastor-mon.service mon/vitastor-osd@.service %buildroot/lib/systemd/system
|
||||||
|
mkdir -p %buildroot/lib/udev/rules.d
|
||||||
|
cp mon/90-vitastor.rules %buildroot/lib/udev/rules.d
|
||||||
|
|
||||||
|
|
||||||
%files
|
%files
|
||||||
@@ -107,11 +116,29 @@ cp -r mon %buildroot/usr/lib/vitastor
|
|||||||
|
|
||||||
%files -n vitastor-osd
|
%files -n vitastor-osd
|
||||||
%_bindir/vitastor-osd
|
%_bindir/vitastor-osd
|
||||||
|
%_bindir/vitastor-disk
|
||||||
%_bindir/vitastor-dump-journal
|
%_bindir/vitastor-dump-journal
|
||||||
|
/lib/systemd/system/vitastor-osd@.service
|
||||||
|
/lib/systemd/system/vitastor.target
|
||||||
|
/lib/udev/rules.d/90-vitastor.rules
|
||||||
|
|
||||||
|
|
||||||
|
%pre -n vitastor-osd
|
||||||
|
groupadd -r -f vitastor 2>/dev/null ||:
|
||||||
|
useradd -r -g vitastor -s /sbin/nologin -c "Vitastor daemons" -M -d /nonexistent vitastor 2>/dev/null ||:
|
||||||
|
install -o vitastor -g vitastor -d /var/log/vitastor
|
||||||
|
mkdir -p /etc/vitastor
|
||||||
|
|
||||||
|
|
||||||
%files -n vitastor-mon
|
%files -n vitastor-mon
|
||||||
/usr/lib/vitastor/mon
|
/usr/lib/vitastor/mon
|
||||||
|
/lib/systemd/system/vitastor-mon.service
|
||||||
|
|
||||||
|
|
||||||
|
%pre -n vitastor-mon
|
||||||
|
groupadd -r -f vitastor 2>/dev/null ||:
|
||||||
|
useradd -r -g vitastor -s /sbin/nologin -c "Vitastor daemons" -M -d /nonexistent vitastor 2>/dev/null ||:
|
||||||
|
mkdir -p /etc/vitastor
|
||||||
|
|
||||||
|
|
||||||
%files -n vitastor-client
|
%files -n vitastor-client
|
||||||
@@ -122,7 +149,6 @@ cp -r mon %buildroot/usr/lib/vitastor
|
|||||||
%_bindir/vita
|
%_bindir/vita
|
||||||
%_libdir/libvitastor_blk.so*
|
%_libdir/libvitastor_blk.so*
|
||||||
%_libdir/libvitastor_client.so*
|
%_libdir/libvitastor_client.so*
|
||||||
/usr/lib/vitastor/make-osd.sh
|
|
||||||
|
|
||||||
|
|
||||||
%files -n vitastor-client-devel
|
%files -n vitastor-client-devel
|
||||||
|
28
rpm/vitastor-el9.Dockerfile
Normal file
28
rpm/vitastor-el9.Dockerfile
Normal file
@@ -0,0 +1,28 @@
|
|||||||
|
# Build packages for AlmaLinux 9 inside a container
|
||||||
|
# cd ..; podman build -t vitastor-el9 -v `pwd`/packages:/root/packages -f rpm/vitastor-el9.Dockerfile .
|
||||||
|
|
||||||
|
FROM almalinux:9
|
||||||
|
|
||||||
|
WORKDIR /root
|
||||||
|
|
||||||
|
RUN sed -i 's/enabled=0/enabled=1/' /etc/yum.repos.d/*.repo
|
||||||
|
RUN dnf -y install epel-release dnf-plugins-core
|
||||||
|
RUN dnf -y install https://vitastor.io/rpms/centos/9/vitastor-release-1.0-1.el9.noarch.rpm
|
||||||
|
RUN dnf -y install gcc-c++ gperftools-devel fio nodejs rpm-build jerasure-devel libisa-l-devel gf-complete-devel rdma-core-devel libarchive liburing-devel cmake
|
||||||
|
RUN dnf download --source fio
|
||||||
|
RUN rpm --nomd5 -i fio*.src.rpm
|
||||||
|
RUN cd ~/rpmbuild/SPECS && dnf builddep -y --spec fio.spec
|
||||||
|
|
||||||
|
ADD . /root/vitastor
|
||||||
|
|
||||||
|
RUN set -e; \
|
||||||
|
cd /root/vitastor/rpm; \
|
||||||
|
sh build-tarball.sh; \
|
||||||
|
cp /root/vitastor-0.8.9.el9.tar.gz ~/rpmbuild/SOURCES; \
|
||||||
|
cp vitastor-el9.spec ~/rpmbuild/SPECS/vitastor.spec; \
|
||||||
|
cd ~/rpmbuild/SPECS/; \
|
||||||
|
rpmbuild -ba vitastor.spec; \
|
||||||
|
mkdir -p /root/packages/vitastor-el9; \
|
||||||
|
rm -rf /root/packages/vitastor-el9/*; \
|
||||||
|
cp ~/rpmbuild/RPMS/*/vitastor* /root/packages/vitastor-el9/; \
|
||||||
|
cp ~/rpmbuild/SRPMS/vitastor* /root/packages/vitastor-el9/
|
158
rpm/vitastor-el9.spec
Normal file
158
rpm/vitastor-el9.spec
Normal file
@@ -0,0 +1,158 @@
|
|||||||
|
Name: vitastor
|
||||||
|
Version: 0.8.9
|
||||||
|
Release: 1%{?dist}
|
||||||
|
Summary: Vitastor, a fast software-defined clustered block storage
|
||||||
|
|
||||||
|
License: Vitastor Network Public License 1.1
|
||||||
|
URL: https://vitastor.io/
|
||||||
|
Source0: vitastor-0.8.9.el9.tar.gz
|
||||||
|
|
||||||
|
BuildRequires: liburing-devel >= 0.6
|
||||||
|
BuildRequires: gperftools-devel
|
||||||
|
BuildRequires: gcc-c++
|
||||||
|
BuildRequires: nodejs >= 10
|
||||||
|
BuildRequires: jerasure-devel
|
||||||
|
BuildRequires: libisa-l-devel
|
||||||
|
BuildRequires: gf-complete-devel
|
||||||
|
BuildRequires: rdma-core-devel
|
||||||
|
BuildRequires: cmake
|
||||||
|
Requires: vitastor-osd = %{version}-%{release}
|
||||||
|
Requires: vitastor-mon = %{version}-%{release}
|
||||||
|
Requires: vitastor-client = %{version}-%{release}
|
||||||
|
Requires: vitastor-client-devel = %{version}-%{release}
|
||||||
|
Requires: vitastor-fio = %{version}-%{release}
|
||||||
|
|
||||||
|
%description
|
||||||
|
Vitastor is a small, simple and fast clustered block storage (storage for VM drives),
|
||||||
|
architecturally similar to Ceph which means strong consistency, primary-replication,
|
||||||
|
symmetric clustering and automatic data distribution over any number of drives of any
|
||||||
|
size with configurable redundancy (replication or erasure codes/XOR).
|
||||||
|
|
||||||
|
|
||||||
|
%package -n vitastor-osd
|
||||||
|
Summary: Vitastor - OSD
|
||||||
|
Requires: vitastor-client = %{version}-%{release}
|
||||||
|
Requires: util-linux
|
||||||
|
Requires: parted
|
||||||
|
|
||||||
|
|
||||||
|
%description -n vitastor-osd
|
||||||
|
Vitastor object storage daemon, i.e. server program that stores data.
|
||||||
|
|
||||||
|
|
||||||
|
%package -n vitastor-mon
|
||||||
|
Summary: Vitastor - monitor
|
||||||
|
Requires: nodejs >= 10
|
||||||
|
Requires: lpsolve
|
||||||
|
|
||||||
|
|
||||||
|
%description -n vitastor-mon
|
||||||
|
Vitastor monitor, i.e. server program responsible for watching cluster state and
|
||||||
|
scheduling cluster-level operations.
|
||||||
|
|
||||||
|
|
||||||
|
%package -n vitastor-client
|
||||||
|
Summary: Vitastor - client
|
||||||
|
|
||||||
|
|
||||||
|
%description -n vitastor-client
|
||||||
|
Vitastor client library and command-line interface.
|
||||||
|
|
||||||
|
|
||||||
|
%package -n vitastor-client-devel
|
||||||
|
Summary: Vitastor - development files
|
||||||
|
Group: Development/Libraries
|
||||||
|
Requires: vitastor-client = %{version}-%{release}
|
||||||
|
|
||||||
|
|
||||||
|
%description -n vitastor-client-devel
|
||||||
|
Vitastor library headers for development.
|
||||||
|
|
||||||
|
|
||||||
|
%package -n vitastor-fio
|
||||||
|
Summary: Vitastor - fio drivers
|
||||||
|
Group: Development/Libraries
|
||||||
|
Requires: vitastor-client = %{version}-%{release}
|
||||||
|
Requires: fio = 3.27-7.el9
|
||||||
|
|
||||||
|
|
||||||
|
%description -n vitastor-fio
|
||||||
|
Vitastor fio drivers for benchmarking.
|
||||||
|
|
||||||
|
|
||||||
|
%prep
|
||||||
|
%setup -q
|
||||||
|
|
||||||
|
|
||||||
|
%build
|
||||||
|
%cmake
|
||||||
|
%cmake_build
|
||||||
|
|
||||||
|
|
||||||
|
%install
|
||||||
|
rm -rf $RPM_BUILD_ROOT
|
||||||
|
%cmake_install
|
||||||
|
cd mon
|
||||||
|
npm install
|
||||||
|
cd ..
|
||||||
|
mkdir -p %buildroot/usr/lib/vitastor
|
||||||
|
cp -r mon %buildroot/usr/lib/vitastor
|
||||||
|
mkdir -p %buildroot/lib/systemd/system
|
||||||
|
cp mon/vitastor.target mon/vitastor-mon.service mon/vitastor-osd@.service %buildroot/lib/systemd/system
|
||||||
|
mkdir -p %buildroot/lib/udev/rules.d
|
||||||
|
cp mon/90-vitastor.rules %buildroot/lib/udev/rules.d
|
||||||
|
|
||||||
|
|
||||||
|
%files
|
||||||
|
%doc GPL-2.0.txt VNPL-1.1.txt README.md README-ru.md
|
||||||
|
|
||||||
|
|
||||||
|
%files -n vitastor-osd
|
||||||
|
%_bindir/vitastor-osd
|
||||||
|
%_bindir/vitastor-disk
|
||||||
|
%_bindir/vitastor-dump-journal
|
||||||
|
/lib/systemd/system/vitastor-osd@.service
|
||||||
|
/lib/systemd/system/vitastor.target
|
||||||
|
/lib/udev/rules.d/90-vitastor.rules
|
||||||
|
|
||||||
|
|
||||||
|
%pre -n vitastor-osd
|
||||||
|
groupadd -r -f vitastor 2>/dev/null ||:
|
||||||
|
useradd -r -g vitastor -s /sbin/nologin -c "Vitastor daemons" -M -d /nonexistent vitastor 2>/dev/null ||:
|
||||||
|
install -o vitastor -g vitastor -d /var/log/vitastor
|
||||||
|
mkdir -p /etc/vitastor
|
||||||
|
|
||||||
|
|
||||||
|
%files -n vitastor-mon
|
||||||
|
/usr/lib/vitastor/mon
|
||||||
|
/lib/systemd/system/vitastor-mon.service
|
||||||
|
|
||||||
|
|
||||||
|
%pre -n vitastor-mon
|
||||||
|
groupadd -r -f vitastor 2>/dev/null ||:
|
||||||
|
useradd -r -g vitastor -s /sbin/nologin -c "Vitastor daemons" -M -d /nonexistent vitastor 2>/dev/null ||:
|
||||||
|
mkdir -p /etc/vitastor
|
||||||
|
|
||||||
|
|
||||||
|
%files -n vitastor-client
|
||||||
|
%_bindir/vitastor-nbd
|
||||||
|
%_bindir/vitastor-nfs
|
||||||
|
%_bindir/vitastor-cli
|
||||||
|
%_bindir/vitastor-rm
|
||||||
|
%_bindir/vita
|
||||||
|
%_libdir/libvitastor_blk.so*
|
||||||
|
%_libdir/libvitastor_client.so*
|
||||||
|
|
||||||
|
|
||||||
|
%files -n vitastor-client-devel
|
||||||
|
%_includedir/vitastor_c.h
|
||||||
|
%_libdir/pkgconfig
|
||||||
|
|
||||||
|
|
||||||
|
%files -n vitastor-fio
|
||||||
|
%_libdir/libfio_vitastor.so
|
||||||
|
%_libdir/libfio_vitastor_blk.so
|
||||||
|
%_libdir/libfio_vitastor_sec.so
|
||||||
|
|
||||||
|
|
||||||
|
%changelog
|
@@ -1,8 +1,9 @@
|
|||||||
cmake_minimum_required(VERSION 2.8)
|
cmake_minimum_required(VERSION 2.8.12)
|
||||||
|
|
||||||
project(vitastor)
|
project(vitastor)
|
||||||
|
|
||||||
include(GNUInstallDirs)
|
include(GNUInstallDirs)
|
||||||
|
include(CTest)
|
||||||
|
|
||||||
set(WITH_QEMU false CACHE BOOL "Build QEMU driver inside Vitastor source tree")
|
set(WITH_QEMU false CACHE BOOL "Build QEMU driver inside Vitastor source tree")
|
||||||
set(WITH_FIO true CACHE BOOL "Build FIO driver")
|
set(WITH_FIO true CACHE BOOL "Build FIO driver")
|
||||||
@@ -15,7 +16,7 @@ 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="0.7.0")
|
add_definitions(-DVERSION="0.8.9")
|
||||||
add_definitions(-Wall -Wno-sign-compare -Wno-comment -Wno-parentheses -Wno-pointer-arith -fdiagnostics-color=always -I ${CMAKE_SOURCE_DIR}/src)
|
add_definitions(-Wall -Wno-sign-compare -Wno-comment -Wno-parentheses -Wno-pointer-arith -fdiagnostics-color=always -I ${CMAKE_SOURCE_DIR}/src)
|
||||||
if (${WITH_ASAN})
|
if (${WITH_ASAN})
|
||||||
add_definitions(-fsanitize=address -fno-omit-frame-pointer)
|
add_definitions(-fsanitize=address -fno-omit-frame-pointer)
|
||||||
@@ -50,6 +51,18 @@ pkg_check_modules(IBVERBS libibverbs)
|
|||||||
if (IBVERBS_LIBRARIES)
|
if (IBVERBS_LIBRARIES)
|
||||||
add_definitions(-DWITH_RDMA)
|
add_definitions(-DWITH_RDMA)
|
||||||
endif (IBVERBS_LIBRARIES)
|
endif (IBVERBS_LIBRARIES)
|
||||||
|
pkg_check_modules(ISAL libisal)
|
||||||
|
if (ISAL_LIBRARIES)
|
||||||
|
add_definitions(-DWITH_ISAL)
|
||||||
|
endif (ISAL_LIBRARIES)
|
||||||
|
|
||||||
|
add_custom_target(build_tests)
|
||||||
|
add_custom_target(test
|
||||||
|
COMMAND
|
||||||
|
echo leak:tcmalloc > ${CMAKE_CURRENT_BINARY_DIR}/lsan-suppress.txt &&
|
||||||
|
env LSAN_OPTIONS=suppressions=${CMAKE_CURRENT_BINARY_DIR}/lsan-suppress.txt ${CMAKE_CTEST_COMMAND}
|
||||||
|
)
|
||||||
|
add_dependencies(test build_tests)
|
||||||
|
|
||||||
include_directories(
|
include_directories(
|
||||||
../
|
../
|
||||||
@@ -60,7 +73,7 @@ include_directories(
|
|||||||
|
|
||||||
# libvitastor_blk.so
|
# libvitastor_blk.so
|
||||||
add_library(vitastor_blk SHARED
|
add_library(vitastor_blk SHARED
|
||||||
allocator.cpp blockstore.cpp blockstore_impl.cpp blockstore_init.cpp blockstore_open.cpp blockstore_journal.cpp blockstore_read.cpp
|
allocator.cpp blockstore.cpp blockstore_impl.cpp blockstore_disk.cpp blockstore_init.cpp blockstore_open.cpp blockstore_journal.cpp blockstore_read.cpp
|
||||||
blockstore_write.cpp blockstore_sync.cpp blockstore_stable.cpp blockstore_rollback.cpp blockstore_flush.cpp crc32c.c ringloop.cpp
|
blockstore_write.cpp blockstore_sync.cpp blockstore_stable.cpp blockstore_rollback.cpp blockstore_flush.cpp crc32c.c ringloop.cpp
|
||||||
)
|
)
|
||||||
target_link_libraries(vitastor_blk
|
target_link_libraries(vitastor_blk
|
||||||
@@ -90,7 +103,7 @@ endif (IBVERBS_LIBRARIES)
|
|||||||
add_library(vitastor_common STATIC
|
add_library(vitastor_common STATIC
|
||||||
epoll_manager.cpp etcd_state_client.cpp messenger.cpp addr_util.cpp
|
epoll_manager.cpp etcd_state_client.cpp messenger.cpp addr_util.cpp
|
||||||
msgr_stop.cpp msgr_op.cpp msgr_send.cpp msgr_receive.cpp ringloop.cpp ../json11/json11.cpp
|
msgr_stop.cpp msgr_op.cpp msgr_send.cpp msgr_receive.cpp ringloop.cpp ../json11/json11.cpp
|
||||||
http_client.cpp osd_ops.cpp pg_states.cpp timerfd_manager.cpp base64.cpp ${MSGR_RDMA}
|
http_client.cpp osd_ops.cpp pg_states.cpp timerfd_manager.cpp str_util.cpp ${MSGR_RDMA}
|
||||||
)
|
)
|
||||||
target_compile_options(vitastor_common PUBLIC -fPIC)
|
target_compile_options(vitastor_common PUBLIC -fPIC)
|
||||||
|
|
||||||
@@ -104,6 +117,7 @@ target_link_libraries(vitastor-osd
|
|||||||
vitastor_common
|
vitastor_common
|
||||||
vitastor_blk
|
vitastor_blk
|
||||||
Jerasure
|
Jerasure
|
||||||
|
${ISAL_LIBRARIES}
|
||||||
${IBVERBS_LIBRARIES}
|
${IBVERBS_LIBRARIES}
|
||||||
)
|
)
|
||||||
|
|
||||||
@@ -126,7 +140,6 @@ add_library(vitastor_client SHARED
|
|||||||
vitastor_c.cpp
|
vitastor_c.cpp
|
||||||
cli_common.cpp
|
cli_common.cpp
|
||||||
cli_alloc_osd.cpp
|
cli_alloc_osd.cpp
|
||||||
cli_simple_offsets.cpp
|
|
||||||
cli_status.cpp
|
cli_status.cpp
|
||||||
cli_df.cpp
|
cli_df.cpp
|
||||||
cli_ls.cpp
|
cli_ls.cpp
|
||||||
@@ -136,11 +149,11 @@ add_library(vitastor_client SHARED
|
|||||||
cli_merge.cpp
|
cli_merge.cpp
|
||||||
cli_rm_data.cpp
|
cli_rm_data.cpp
|
||||||
cli_rm.cpp
|
cli_rm.cpp
|
||||||
|
cli_rm_osd.cpp
|
||||||
)
|
)
|
||||||
set_target_properties(vitastor_client PROPERTIES PUBLIC_HEADER "vitastor_c.h")
|
set_target_properties(vitastor_client PROPERTIES PUBLIC_HEADER "vitastor_c.h")
|
||||||
target_link_libraries(vitastor_client
|
target_link_libraries(vitastor_client
|
||||||
vitastor_common
|
vitastor_common
|
||||||
tcmalloc_minimal
|
|
||||||
${LIBURING_LIBRARIES}
|
${LIBURING_LIBRARIES}
|
||||||
${IBVERBS_LIBRARIES}
|
${IBVERBS_LIBRARIES}
|
||||||
)
|
)
|
||||||
@@ -188,9 +201,15 @@ target_link_libraries(vitastor-cli
|
|||||||
)
|
)
|
||||||
configure_file(vitastor.pc.in vitastor.pc @ONLY)
|
configure_file(vitastor.pc.in vitastor.pc @ONLY)
|
||||||
|
|
||||||
# vitastor-dump-journal
|
# vitastor-disk
|
||||||
add_executable(vitastor-dump-journal
|
add_executable(vitastor-disk
|
||||||
dump_journal.cpp crc32c.c
|
disk_tool.cpp disk_simple_offsets.cpp
|
||||||
|
disk_tool_journal.cpp disk_tool_meta.cpp disk_tool_prepare.cpp disk_tool_resize.cpp disk_tool_udev.cpp disk_tool_utils.cpp disk_tool_upgrade.cpp
|
||||||
|
crc32c.c str_util.cpp ../json11/json11.cpp rw_blocking.cpp allocator.cpp ringloop.cpp blockstore_disk.cpp
|
||||||
|
)
|
||||||
|
target_link_libraries(vitastor-disk
|
||||||
|
tcmalloc_minimal
|
||||||
|
${LIBURING_LIBRARIES}
|
||||||
)
|
)
|
||||||
|
|
||||||
if (${WITH_QEMU})
|
if (${WITH_QEMU})
|
||||||
@@ -224,8 +243,18 @@ add_executable(osd_test osd_test.cpp rw_blocking.cpp addr_util.cpp)
|
|||||||
target_link_libraries(osd_test tcmalloc_minimal)
|
target_link_libraries(osd_test tcmalloc_minimal)
|
||||||
|
|
||||||
# osd_rmw_test
|
# osd_rmw_test
|
||||||
add_executable(osd_rmw_test osd_rmw_test.cpp allocator.cpp)
|
add_executable(osd_rmw_test EXCLUDE_FROM_ALL osd_rmw_test.cpp allocator.cpp)
|
||||||
target_link_libraries(osd_rmw_test Jerasure tcmalloc_minimal)
|
target_link_libraries(osd_rmw_test Jerasure ${ISAL_LIBRARIES} tcmalloc_minimal)
|
||||||
|
add_dependencies(build_tests osd_rmw_test)
|
||||||
|
add_test(NAME osd_rmw_test COMMAND osd_rmw_test)
|
||||||
|
|
||||||
|
if (ISAL_LIBRARIES)
|
||||||
|
add_executable(osd_rmw_test_je EXCLUDE_FROM_ALL osd_rmw_test.cpp allocator.cpp)
|
||||||
|
target_compile_definitions(osd_rmw_test_je PUBLIC -DNO_ISAL)
|
||||||
|
target_link_libraries(osd_rmw_test_je Jerasure tcmalloc_minimal)
|
||||||
|
add_dependencies(build_tests osd_rmw_test_je)
|
||||||
|
add_test(NAME osd_rmw_test_jerasure COMMAND osd_rmw_test_je)
|
||||||
|
endif (ISAL_LIBRARIES)
|
||||||
|
|
||||||
# stub_uring_osd
|
# stub_uring_osd
|
||||||
add_executable(stub_uring_osd
|
add_executable(stub_uring_osd
|
||||||
@@ -239,11 +268,15 @@ target_link_libraries(stub_uring_osd
|
|||||||
)
|
)
|
||||||
|
|
||||||
# osd_peering_pg_test
|
# osd_peering_pg_test
|
||||||
add_executable(osd_peering_pg_test osd_peering_pg_test.cpp osd_peering_pg.cpp)
|
add_executable(osd_peering_pg_test EXCLUDE_FROM_ALL osd_peering_pg_test.cpp osd_peering_pg.cpp)
|
||||||
target_link_libraries(osd_peering_pg_test tcmalloc_minimal)
|
target_link_libraries(osd_peering_pg_test tcmalloc_minimal)
|
||||||
|
add_dependencies(build_tests osd_peering_pg_test)
|
||||||
|
add_test(NAME osd_peering_pg_test COMMAND osd_peering_pg_test)
|
||||||
|
|
||||||
# test_allocator
|
# test_allocator
|
||||||
add_executable(test_allocator test_allocator.cpp allocator.cpp)
|
add_executable(test_allocator EXCLUDE_FROM_ALL test_allocator.cpp allocator.cpp)
|
||||||
|
add_dependencies(build_tests test_allocator)
|
||||||
|
add_test(NAME test_allocator COMMAND test_allocator)
|
||||||
|
|
||||||
# test_cas
|
# test_cas
|
||||||
add_executable(test_cas
|
add_executable(test_cas
|
||||||
@@ -253,14 +286,25 @@ target_link_libraries(test_cas
|
|||||||
vitastor_client
|
vitastor_client
|
||||||
)
|
)
|
||||||
|
|
||||||
|
# test_crc32
|
||||||
|
add_executable(test_crc32
|
||||||
|
test_crc32.cpp
|
||||||
|
)
|
||||||
|
target_link_libraries(test_crc32
|
||||||
|
vitastor_blk
|
||||||
|
)
|
||||||
|
|
||||||
# test_cluster_client
|
# test_cluster_client
|
||||||
add_executable(test_cluster_client
|
add_executable(test_cluster_client
|
||||||
|
EXCLUDE_FROM_ALL
|
||||||
test_cluster_client.cpp
|
test_cluster_client.cpp
|
||||||
pg_states.cpp osd_ops.cpp cluster_client.cpp cluster_client_list.cpp msgr_op.cpp mock/messenger.cpp msgr_stop.cpp
|
pg_states.cpp osd_ops.cpp cluster_client.cpp cluster_client_list.cpp msgr_op.cpp mock/messenger.cpp msgr_stop.cpp
|
||||||
etcd_state_client.cpp timerfd_manager.cpp ../json11/json11.cpp
|
etcd_state_client.cpp timerfd_manager.cpp ../json11/json11.cpp
|
||||||
)
|
)
|
||||||
target_compile_definitions(test_cluster_client PUBLIC -D__MOCK__)
|
target_compile_definitions(test_cluster_client PUBLIC -D__MOCK__)
|
||||||
target_include_directories(test_cluster_client PUBLIC ${CMAKE_SOURCE_DIR}/src/mock)
|
target_include_directories(test_cluster_client PUBLIC ${CMAKE_SOURCE_DIR}/src/mock)
|
||||||
|
add_dependencies(build_tests test_cluster_client)
|
||||||
|
add_test(NAME test_cluster_client COMMAND test_cluster_client)
|
||||||
|
|
||||||
## test_blockstore, test_shit
|
## test_blockstore, test_shit
|
||||||
#add_executable(test_blockstore test_blockstore.cpp)
|
#add_executable(test_blockstore test_blockstore.cpp)
|
||||||
@@ -270,7 +314,8 @@ target_include_directories(test_cluster_client PUBLIC ${CMAKE_SOURCE_DIR}/src/mo
|
|||||||
|
|
||||||
### Install
|
### Install
|
||||||
|
|
||||||
install(TARGETS vitastor-osd vitastor-dump-journal vitastor-nbd vitastor-nfs vitastor-cli RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR})
|
install(TARGETS vitastor-osd vitastor-disk vitastor-nbd vitastor-nfs vitastor-cli RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR})
|
||||||
|
install_symlink(vitastor-disk ${CMAKE_INSTALL_PREFIX}/${CMAKE_INSTALL_BINDIR}/vitastor-dump-journal)
|
||||||
install_symlink(vitastor-cli ${CMAKE_INSTALL_PREFIX}/${CMAKE_INSTALL_BINDIR}/vitastor-rm)
|
install_symlink(vitastor-cli ${CMAKE_INSTALL_PREFIX}/${CMAKE_INSTALL_BINDIR}/vitastor-rm)
|
||||||
install_symlink(vitastor-cli ${CMAKE_INSTALL_PREFIX}/${CMAKE_INSTALL_BINDIR}/vita)
|
install_symlink(vitastor-cli ${CMAKE_INSTALL_PREFIX}/${CMAKE_INSTALL_BINDIR}/vita)
|
||||||
install(
|
install(
|
||||||
|
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user