Compare commits
1 Commits
Author | SHA1 | Date |
---|---|---|
Vitaliy Filippov | c853d18b49 |
|
@ -22,7 +22,7 @@ RUN apt-get update
|
||||||
RUN apt-get -y install etcd qemu-system-x86 qemu-block-extra qemu-utils fio libasan5 \
|
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
|
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 build-dep fio qemu=`dpkg -s qemu-system-x86|grep ^Version:|awk '{print $2}'`
|
||||||
RUN apt-get update && apt-get -y install jq lp-solve sudo nfs-common fdisk parted
|
RUN apt-get -y install jq lp-solve sudo nfs-common
|
||||||
RUN apt-get --download-only source fio qemu=`dpkg -s qemu-system-x86|grep ^Version:|awk '{print $2}'`
|
RUN apt-get --download-only source fio qemu=`dpkg -s qemu-system-x86|grep ^Version:|awk '{print $2}'`
|
||||||
|
|
||||||
RUN set -ex; \
|
RUN set -ex; \
|
||||||
|
|
|
@ -288,24 +288,6 @@ jobs:
|
||||||
echo ""
|
echo ""
|
||||||
done
|
done
|
||||||
|
|
||||||
test_create_halfhost:
|
|
||||||
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_halfhost.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:
|
test_failure_domain:
|
||||||
runs-on: ubuntu-latest
|
runs-on: ubuntu-latest
|
||||||
needs: build
|
needs: build
|
||||||
|
@ -846,60 +828,6 @@ jobs:
|
||||||
echo ""
|
echo ""
|
||||||
done
|
done
|
||||||
|
|
||||||
test_resize:
|
|
||||||
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_resize.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_resize_auto:
|
|
||||||
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_resize_auto.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_pool2:
|
|
||||||
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_pool2.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_osd_tags:
|
test_osd_tags:
|
||||||
runs-on: ubuntu-latest
|
runs-on: ubuntu-latest
|
||||||
needs: build
|
needs: build
|
||||||
|
|
|
@ -2,6 +2,6 @@ cmake_minimum_required(VERSION 2.8.12)
|
||||||
|
|
||||||
project(vitastor)
|
project(vitastor)
|
||||||
|
|
||||||
set(VITASTOR_VERSION "1.9.3")
|
set(VITASTOR_VERSION "1.8.0")
|
||||||
|
|
||||||
add_subdirectory(src)
|
add_subdirectory(src)
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
# Vitastor
|
## Vitastor
|
||||||
|
|
||||||
[Read English version](README.md)
|
[Read English version](README.md)
|
||||||
|
|
||||||
|
@ -22,7 +22,7 @@ TCP и RDMA и на хорошем железе может достигать з
|
||||||
Vitastor поддерживает QEMU-драйвер, протоколы NBD и NFS, драйверы OpenStack, OpenNebula, Proxmox, Kubernetes.
|
Vitastor поддерживает QEMU-драйвер, протоколы NBD и NFS, драйверы OpenStack, OpenNebula, Proxmox, Kubernetes.
|
||||||
Другие драйверы могут также быть легко реализованы.
|
Другие драйверы могут также быть легко реализованы.
|
||||||
|
|
||||||
Подробности смотрите в документации по ссылкам. Можете начать отсюда: [Быстрый старт](docs/intro/quickstart.ru.md).
|
Подробности смотрите в документации по ссылкам ниже.
|
||||||
|
|
||||||
## Презентации и записи докладов
|
## Презентации и записи докладов
|
||||||
|
|
||||||
|
@ -51,7 +51,7 @@ Vitastor поддерживает QEMU-драйвер, протоколы NBD и
|
||||||
- Параметры
|
- Параметры
|
||||||
- [Общие](docs/config/common.ru.md)
|
- [Общие](docs/config/common.ru.md)
|
||||||
- [Сетевые](docs/config/network.ru.md)
|
- [Сетевые](docs/config/network.ru.md)
|
||||||
- [Клиентский код](docs/config/client.ru.md)
|
- [Клиентский код](docs/config/client.en.md)
|
||||||
- [Глобальные дисковые параметры](docs/config/layout-cluster.ru.md)
|
- [Глобальные дисковые параметры](docs/config/layout-cluster.ru.md)
|
||||||
- [Дисковые параметры OSD](docs/config/layout-osd.ru.md)
|
- [Дисковые параметры OSD](docs/config/layout-osd.ru.md)
|
||||||
- [Прочие параметры OSD](docs/config/osd.ru.md)
|
- [Прочие параметры OSD](docs/config/osd.ru.md)
|
||||||
|
|
|
@ -22,7 +22,7 @@ or internal systems of public clouds.
|
||||||
Vitastor supports QEMU, NBD, NFS protocols, OpenStack, OpenNebula, Proxmox, Kubernetes drivers.
|
Vitastor supports QEMU, NBD, NFS protocols, OpenStack, OpenNebula, Proxmox, Kubernetes drivers.
|
||||||
More drivers may be created easily.
|
More drivers may be created easily.
|
||||||
|
|
||||||
Read more details in the documentation. You can start from here: [Quick Start](docs/intro/quickstart.en.md).
|
Read more details below in the documentation.
|
||||||
|
|
||||||
## Talks and presentations
|
## Talks and presentations
|
||||||
|
|
||||||
|
|
|
@ -1 +1 @@
|
||||||
Subproject commit 8de8b467acbca50cfd8835c20e0e379110f3b32b
|
Subproject commit 45e6d1f13196a0824e2089a586c53b9de0283f17
|
|
@ -1,4 +1,4 @@
|
||||||
VITASTOR_VERSION ?= v1.9.3
|
VITASTOR_VERSION ?= v1.8.0
|
||||||
|
|
||||||
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:v1.9.3
|
image: vitalif/vitastor-csi:v1.8.0
|
||||||
args:
|
args:
|
||||||
- "--node=$(NODE_ID)"
|
- "--node=$(NODE_ID)"
|
||||||
- "--endpoint=$(CSI_ENDPOINT)"
|
- "--endpoint=$(CSI_ENDPOINT)"
|
||||||
|
|
|
@ -121,7 +121,7 @@ spec:
|
||||||
privileged: true
|
privileged: true
|
||||||
capabilities:
|
capabilities:
|
||||||
add: ["SYS_ADMIN"]
|
add: ["SYS_ADMIN"]
|
||||||
image: vitalif/vitastor-csi:v1.9.3
|
image: vitalif/vitastor-csi:v1.8.0
|
||||||
args:
|
args:
|
||||||
- "--node=$(NODE_ID)"
|
- "--node=$(NODE_ID)"
|
||||||
- "--endpoint=$(CSI_ENDPOINT)"
|
- "--endpoint=$(CSI_ENDPOINT)"
|
||||||
|
|
|
@ -3,10 +3,10 @@ module vitastor.io/csi
|
||||||
go 1.15
|
go 1.15
|
||||||
|
|
||||||
require (
|
require (
|
||||||
github.com/container-storage-interface/spec v1.8.0
|
github.com/container-storage-interface/spec v1.4.0
|
||||||
github.com/golang/glog v0.0.0-20160126235308-23def4e6c14b
|
github.com/golang/glog v0.0.0-20160126235308-23def4e6c14b
|
||||||
github.com/kubernetes-csi/csi-lib-utils v0.9.1
|
github.com/kubernetes-csi/csi-lib-utils v0.9.1
|
||||||
golang.org/x/net v0.7.0
|
golang.org/x/net v0.0.0-20201202161906-c7110b5ffcbb
|
||||||
golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1 // indirect
|
golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1 // indirect
|
||||||
google.golang.org/grpc v1.33.1
|
google.golang.org/grpc v1.33.1
|
||||||
google.golang.org/protobuf v1.24.0
|
google.golang.org/protobuf v1.24.0
|
||||||
|
|
31
csi/go.sum
31
csi/go.sum
|
@ -41,8 +41,8 @@ github.com/chzyer/logex v1.1.10/go.mod h1:+Ywpsq7O8HXn0nuIou7OrIPyXbp3wmkHB+jjWR
|
||||||
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=
|
||||||
github.com/chzyer/test v0.0.0-20180213035817-a1ea475d72b1/go.mod h1:Q3SI9o4m/ZMnBNeIyt5eFwwo7qiLfzFZmjNmxjkiQlU=
|
github.com/chzyer/test v0.0.0-20180213035817-a1ea475d72b1/go.mod h1:Q3SI9o4m/ZMnBNeIyt5eFwwo7qiLfzFZmjNmxjkiQlU=
|
||||||
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.8.0 h1:D0vhF3PLIZwlwZEf2eNbpujGCNwspwTYf2idJRJx4xI=
|
github.com/container-storage-interface/spec v1.4.0 h1:ozAshSKxpJnYUfmkpZCTYyF/4MYeYlhdXbAvPvfGmkg=
|
||||||
github.com/container-storage-interface/spec v1.8.0/go.mod h1:ROLik+GhPslwwWRNFF1KasPzroNARibH2rfz1rkg4H0=
|
github.com/container-storage-interface/spec v1.4.0/go.mod h1:6URME8mwIBbpVyZV93Ce5St17xBiQJQY67NDsuohiy4=
|
||||||
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=
|
||||||
|
@ -182,7 +182,6 @@ 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/yuin/goldmark v1.4.13/go.mod h1:6yULJ656Px+3vBD8DxQVa3kxgyrAnzto9xy5taEt/CY=
|
|
||||||
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=
|
||||||
|
@ -196,7 +195,6 @@ golang.org/x/crypto v0.0.0-20190605123033-f99c8df09eb5/go.mod h1:yigFU9vqHzYiE8U
|
||||||
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/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
|
golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
|
||||||
golang.org/x/crypto v0.0.0-20210921155107-089bfa567519/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc=
|
|
||||||
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=
|
||||||
golang.org/x/exp v0.0.0-20190510132918-efd6b22b2522/go.mod h1:ZjyILWgesfNpC6sMxTJOJm9Kp84zZh5NQWvqDGG3Qr8=
|
golang.org/x/exp v0.0.0-20190510132918-efd6b22b2522/go.mod h1:ZjyILWgesfNpC6sMxTJOJm9Kp84zZh5NQWvqDGG3Qr8=
|
||||||
|
@ -215,7 +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.6.0-dev.0.20220419223038-86c51ed26bb4/go.mod h1:jJ57K6gSWd91VN4djpZkiMVwK6gcyfeH4XE8wZrZaV4=
|
|
||||||
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=
|
||||||
|
@ -231,10 +228,8 @@ golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLL
|
||||||
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-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/go.mod h1:/O7V0waA8r7cgGh81Ro3o1hOxt32SMVPicZroKQ2sZA=
|
golang.org/x/net v0.0.0-20200707034311-ab3426394381/go.mod h1:/O7V0waA8r7cgGh81Ro3o1hOxt32SMVPicZroKQ2sZA=
|
||||||
golang.org/x/net v0.0.0-20210226172049-e18ecbb05110/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg=
|
golang.org/x/net v0.0.0-20201202161906-c7110b5ffcbb h1:eBmm0M9fYhWpKZLjQUUKka/LtIxf46G4fxeEz5KJr9U=
|
||||||
golang.org/x/net v0.0.0-20220722155237-a158d28d115b/go.mod h1:XRhObCWvk6IyKnWLug+ECip1KBveYUHfp+8e9klMJ9c=
|
golang.org/x/net v0.0.0-20201202161906-c7110b5ffcbb/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU=
|
||||||
golang.org/x/net v0.7.0 h1:rJrUqqhjsgNp7KqAIc25s9pZnjU7TUcSY7HcVZjdn1g=
|
|
||||||
golang.org/x/net v0.7.0/go.mod h1:2Tu9+aMcznHK/AK1HMvgo6xiTLG5rD5rZLDS+rp2Bjs=
|
|
||||||
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=
|
||||||
|
@ -245,7 +240,6 @@ golang.org/x/sync v0.0.0-20181221193216-37e7f081c4d4/go.mod h1:RxMgew5VJxzue5/jJ
|
||||||
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-20220722155255-886fb9371eb4/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=
|
||||||
|
@ -265,22 +259,13 @@ golang.org/x/sys v0.0.0-20200302150141-5c8b2ff67527/go.mod h1:h1NjWce9XRLGQEsW7w
|
||||||
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/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
golang.org/x/sys v0.0.0-20200622214017-ed371f2e16b4/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||||
golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
golang.org/x/sys v0.0.0-20200930185726-fdedc70b468f h1:+Nyd8tzPX9R7BWHguqsrbFdRx3WQ/1ib8I44HXV5yTA=
|
||||||
golang.org/x/sys v0.0.0-20210615035016-665e8c7367d1/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
golang.org/x/sys v0.0.0-20200930185726-fdedc70b468f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||||
golang.org/x/sys v0.0.0-20220520151302-bc2c85ada10a/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
|
||||||
golang.org/x/sys v0.0.0-20220722155257-8c9f86f7a55f/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
|
||||||
golang.org/x/sys v0.5.0 h1:MUK/U/4lj1t1oPg0HfuXDN/Z1wv31ZJ/YcPiGccS4DU=
|
|
||||||
golang.org/x/sys v0.5.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
|
||||||
golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo=
|
|
||||||
golang.org/x/term v0.0.0-20210927222741-03fcf44c2211/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8=
|
|
||||||
golang.org/x/term v0.5.0/go.mod h1:jMB1sMXY+tzblOD4FWmEbocvup2/aLOaQEp7JmGp78k=
|
|
||||||
golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
|
golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
|
||||||
golang.org/x/text v0.3.1-0.20180807135948-17ff2d5776d2/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
|
golang.org/x/text v0.3.1-0.20180807135948-17ff2d5776d2/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
|
||||||
golang.org/x/text v0.3.2/go.mod h1:bEr9sfX3Q8Zfm5fL9x+3itogRgK3+ptLWKqgva+5dAk=
|
golang.org/x/text v0.3.2/go.mod h1:bEr9sfX3Q8Zfm5fL9x+3itogRgK3+ptLWKqgva+5dAk=
|
||||||
|
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/text v0.3.7/go.mod h1:u+2+/6zg+i71rQMx5EYifcz6MCKuco9NR6JIITiCfzQ=
|
|
||||||
golang.org/x/text v0.7.0 h1:4BRB4x83lYWy72KwLD/qYDuTu7q9PjSagHvijDw7cLo=
|
|
||||||
golang.org/x/text v0.7.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8=
|
|
||||||
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/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
|
golang.org/x/time v0.0.0-20191024005414-555d28b269f0/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
|
||||||
|
@ -301,10 +286,8 @@ 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.1.12/go.mod h1:hNGJHUnrk76NpqgfD5Aqm5Crs+Hm0VOH/i9J2+nxYbc=
|
|
||||||
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/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
|
golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
|
||||||
|
|
|
@ -5,7 +5,7 @@ package vitastor
|
||||||
|
|
||||||
const (
|
const (
|
||||||
vitastorCSIDriverName = "csi.vitastor.io"
|
vitastorCSIDriverName = "csi.vitastor.io"
|
||||||
vitastorCSIDriverVersion = "1.9.3"
|
vitastorCSIDriverVersion = "1.8.0"
|
||||||
)
|
)
|
||||||
|
|
||||||
// Config struct fills the parameters of request or user input
|
// Config struct fills the parameters of request or user input
|
||||||
|
|
|
@ -8,9 +8,11 @@ import (
|
||||||
"encoding/json"
|
"encoding/json"
|
||||||
"fmt"
|
"fmt"
|
||||||
"strings"
|
"strings"
|
||||||
|
"bytes"
|
||||||
"strconv"
|
"strconv"
|
||||||
"time"
|
"time"
|
||||||
"os"
|
"os"
|
||||||
|
"os/exec"
|
||||||
"io/ioutil"
|
"io/ioutil"
|
||||||
|
|
||||||
"github.com/kubernetes-csi/csi-lib-utils/protosanitizer"
|
"github.com/kubernetes-csi/csi-lib-utils/protosanitizer"
|
||||||
|
@ -112,6 +114,22 @@ func GetConnectionParams(params map[string]string) (map[string]string, error)
|
||||||
return ctxVars, nil
|
return ctxVars, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func system(program string, args ...string) ([]byte, []byte, error)
|
||||||
|
{
|
||||||
|
klog.Infof("Running "+program+" "+strings.Join(args, " "))
|
||||||
|
c := exec.Command(program, args...)
|
||||||
|
var stdout, stderr bytes.Buffer
|
||||||
|
c.Stdout, c.Stderr = &stdout, &stderr
|
||||||
|
err := c.Run()
|
||||||
|
if (err != nil)
|
||||||
|
{
|
||||||
|
stdoutStr, stderrStr := string(stdout.Bytes()), string(stderr.Bytes())
|
||||||
|
klog.Errorf(program+" "+strings.Join(args, " ")+" failed: %s, status %s\n", stdoutStr+stderrStr, err)
|
||||||
|
return nil, nil, status.Error(codes.Internal, stdoutStr+stderrStr+" (status "+err.Error()+")")
|
||||||
|
}
|
||||||
|
return stdout.Bytes(), stderr.Bytes(), nil
|
||||||
|
}
|
||||||
|
|
||||||
func invokeCLI(ctxVars map[string]string, args []string) ([]byte, error)
|
func invokeCLI(ctxVars map[string]string, args []string) ([]byte, error)
|
||||||
{
|
{
|
||||||
if (ctxVars["configPath"] != "")
|
if (ctxVars["configPath"] != "")
|
||||||
|
@ -140,12 +158,6 @@ func (cs *ControllerServer) CreateVolume(ctx context.Context, req *csi.CreateVol
|
||||||
return nil, status.Error(codes.InvalidArgument, "volume capabilities is a required field")
|
return nil, status.Error(codes.InvalidArgument, "volume capabilities is a required field")
|
||||||
}
|
}
|
||||||
|
|
||||||
err := cs.checkCaps(volumeCapabilities)
|
|
||||||
if (err != nil)
|
|
||||||
{
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
|
|
||||||
etcdVolumePrefix := req.Parameters["etcdVolumePrefix"]
|
etcdVolumePrefix := req.Parameters["etcdVolumePrefix"]
|
||||||
poolId, _ := strconv.ParseUint(req.Parameters["poolId"], 10, 64)
|
poolId, _ := strconv.ParseUint(req.Parameters["poolId"], 10, 64)
|
||||||
if (poolId == 0)
|
if (poolId == 0)
|
||||||
|
@ -289,44 +301,13 @@ func (cs *ControllerServer) ValidateVolumeCapabilities(ctx context.Context, req
|
||||||
return nil, status.Error(codes.InvalidArgument, "volumeCapabilities is nil")
|
return nil, status.Error(codes.InvalidArgument, "volumeCapabilities is nil")
|
||||||
}
|
}
|
||||||
|
|
||||||
err := cs.checkCaps(volumeCapabilities)
|
|
||||||
if (err != nil)
|
|
||||||
{
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
|
|
||||||
return &csi.ValidateVolumeCapabilitiesResponse{
|
|
||||||
Confirmed: &csi.ValidateVolumeCapabilitiesResponse_Confirmed{
|
|
||||||
VolumeCapabilities: req.VolumeCapabilities,
|
|
||||||
},
|
|
||||||
}, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func (cs *ControllerServer) checkCaps(volumeCapabilities []*csi.VolumeCapability) error
|
|
||||||
{
|
|
||||||
var volumeCapabilityAccessModes []*csi.VolumeCapability_AccessMode
|
var volumeCapabilityAccessModes []*csi.VolumeCapability_AccessMode
|
||||||
for _, mode := range []csi.VolumeCapability_AccessMode_Mode{
|
for _, mode := range []csi.VolumeCapability_AccessMode_Mode{
|
||||||
csi.VolumeCapability_AccessMode_SINGLE_NODE_WRITER,
|
csi.VolumeCapability_AccessMode_SINGLE_NODE_WRITER,
|
||||||
csi.VolumeCapability_AccessMode_SINGLE_NODE_READER_ONLY,
|
|
||||||
csi.VolumeCapability_AccessMode_MULTI_NODE_READER_ONLY,
|
|
||||||
csi.VolumeCapability_AccessMode_SINGLE_NODE_SINGLE_WRITER,
|
|
||||||
csi.VolumeCapability_AccessMode_SINGLE_NODE_MULTI_WRITER,
|
|
||||||
} {
|
|
||||||
volumeCapabilityAccessModes = append(volumeCapabilityAccessModes, &csi.VolumeCapability_AccessMode{Mode: mode})
|
|
||||||
}
|
|
||||||
for _, capability := range volumeCapabilities
|
|
||||||
{
|
|
||||||
if (capability.GetBlock() != nil)
|
|
||||||
{
|
|
||||||
for _, mode := range []csi.VolumeCapability_AccessMode_Mode{
|
|
||||||
csi.VolumeCapability_AccessMode_MULTI_NODE_SINGLE_WRITER,
|
|
||||||
csi.VolumeCapability_AccessMode_MULTI_NODE_MULTI_WRITER,
|
csi.VolumeCapability_AccessMode_MULTI_NODE_MULTI_WRITER,
|
||||||
} {
|
} {
|
||||||
volumeCapabilityAccessModes = append(volumeCapabilityAccessModes, &csi.VolumeCapability_AccessMode{Mode: mode})
|
volumeCapabilityAccessModes = append(volumeCapabilityAccessModes, &csi.VolumeCapability_AccessMode{Mode: mode})
|
||||||
}
|
}
|
||||||
break
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
capabilitySupport := false
|
capabilitySupport := false
|
||||||
for _, capability := range volumeCapabilities
|
for _, capability := range volumeCapabilities
|
||||||
|
@ -342,10 +323,14 @@ func (cs *ControllerServer) checkCaps(volumeCapabilities []*csi.VolumeCapability
|
||||||
|
|
||||||
if (!capabilitySupport)
|
if (!capabilitySupport)
|
||||||
{
|
{
|
||||||
return status.Errorf(codes.NotFound, "%v not supported", volumeCapabilities)
|
return nil, status.Errorf(codes.NotFound, "%v not supported", req.GetVolumeCapabilities())
|
||||||
}
|
}
|
||||||
|
|
||||||
return nil
|
return &csi.ValidateVolumeCapabilitiesResponse{
|
||||||
|
Confirmed: &csi.ValidateVolumeCapabilitiesResponse_Confirmed{
|
||||||
|
VolumeCapabilities: req.VolumeCapabilities,
|
||||||
|
},
|
||||||
|
}, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// ListVolumes returns a list of volumes
|
// ListVolumes returns a list of volumes
|
||||||
|
|
|
@ -227,32 +227,7 @@ func (ns *NodeServer) NodeStageVolume(ctx context.Context, req *csi.NodeStageVol
|
||||||
isBlock := req.GetVolumeCapability().GetBlock() != nil
|
isBlock := req.GetVolumeCapability().GetBlock() != nil
|
||||||
|
|
||||||
// Check that it's not already mounted
|
// Check that it's not already mounted
|
||||||
notmnt, err := mount.IsNotMountPoint(ns.mounter, targetPath)
|
_, err = mount.IsNotMountPoint(ns.mounter, targetPath)
|
||||||
if (err == nil)
|
|
||||||
{
|
|
||||||
if (!notmnt)
|
|
||||||
{
|
|
||||||
klog.Errorf("target path %s is already mounted", targetPath)
|
|
||||||
return nil, fmt.Errorf("target path %s is already mounted", targetPath)
|
|
||||||
}
|
|
||||||
var finfo os.FileInfo
|
|
||||||
finfo, err = os.Stat(targetPath)
|
|
||||||
if (err != nil)
|
|
||||||
{
|
|
||||||
klog.Errorf("failed to stat %s: %v", targetPath, err)
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
if (finfo.IsDir() != (!isBlock))
|
|
||||||
{
|
|
||||||
err = os.Remove(targetPath)
|
|
||||||
if (err != nil)
|
|
||||||
{
|
|
||||||
klog.Errorf("failed to remove %s (to recreate it with correct type): %v", targetPath, err)
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
err = os.ErrNotExist
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (err != nil)
|
if (err != nil)
|
||||||
{
|
{
|
||||||
if (os.IsNotExist(err))
|
if (os.IsNotExist(err))
|
||||||
|
@ -305,7 +280,6 @@ func (ns *NodeServer) NodeStageVolume(ctx context.Context, req *csi.NodeStageVol
|
||||||
diskMounter := &mount.SafeFormatAndMount{Interface: ns.mounter, Exec: utilexec.New()}
|
diskMounter := &mount.SafeFormatAndMount{Interface: ns.mounter, Exec: utilexec.New()}
|
||||||
if (isBlock)
|
if (isBlock)
|
||||||
{
|
{
|
||||||
klog.Infof("bind-mounting %s to %s", devicePath, targetPath)
|
|
||||||
err = diskMounter.Mount(devicePath, targetPath, "", []string{"bind"})
|
err = diskMounter.Mount(devicePath, targetPath, "", []string{"bind"})
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
|
@ -335,40 +309,39 @@ func (ns *NodeServer) NodeStageVolume(ctx context.Context, req *csi.NodeStageVol
|
||||||
readOnly := Contains(opt, "ro")
|
readOnly := Contains(opt, "ro")
|
||||||
if (existingFormat == "" && !readOnly)
|
if (existingFormat == "" && !readOnly)
|
||||||
{
|
{
|
||||||
|
var cmdOut []byte
|
||||||
switch fsType
|
switch fsType
|
||||||
{
|
{
|
||||||
case "ext4":
|
case "ext4":
|
||||||
args := []string{"-m0", "-Enodiscard,lazy_itable_init=1,lazy_journal_init=1", devicePath}
|
args := []string{"-m0", "-Enodiscard,lazy_itable_init=1,lazy_journal_init=1", devicePath}
|
||||||
_, err = systemCombined("mkfs.ext4", args...)
|
cmdOut, err = diskMounter.Exec.Command("mkfs.ext4", args...).CombinedOutput()
|
||||||
case "xfs":
|
case "xfs":
|
||||||
_, err = systemCombined("mkfs.xfs", "-K", devicePath)
|
cmdOut, err = diskMounter.Exec.Command("mkfs.xfs", "-K", devicePath).CombinedOutput()
|
||||||
}
|
}
|
||||||
if (err != nil)
|
if (err != nil)
|
||||||
{
|
{
|
||||||
|
klog.Errorf("failed to run mkfs error: %v, output: %v", err, string(cmdOut))
|
||||||
goto unmap
|
goto unmap
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
klog.Infof("formatting and mounting %s to %s with FS %s, options: %v", devicePath, targetPath, fsType, opt)
|
|
||||||
err = diskMounter.FormatAndMount(devicePath, targetPath, fsType, opt)
|
err = diskMounter.FormatAndMount(devicePath, targetPath, fsType, opt)
|
||||||
if (err == nil)
|
|
||||||
{
|
|
||||||
klog.Infof("successfully mounted %s to %s", devicePath, targetPath)
|
|
||||||
}
|
|
||||||
|
|
||||||
// Try to run online resize on mount.
|
// Try to run online resize on mount.
|
||||||
// FIXME: Implement online resize. It requires online resize support in vitastor-nbd.
|
// FIXME: Implement online resize. It requires online resize support in vitastor-nbd.
|
||||||
if (err == nil && existingFormat != "" && !readOnly)
|
if (err == nil && existingFormat != "" && !readOnly)
|
||||||
{
|
{
|
||||||
|
var cmdOut []byte
|
||||||
switch (fsType)
|
switch (fsType)
|
||||||
{
|
{
|
||||||
case "ext4":
|
case "ext4":
|
||||||
_, err = systemCombined("resize2fs", devicePath)
|
cmdOut, err = diskMounter.Exec.Command("resize2fs", devicePath).CombinedOutput()
|
||||||
case "xfs":
|
case "xfs":
|
||||||
_, err = systemCombined("xfs_growfs", devicePath)
|
cmdOut, err = diskMounter.Exec.Command("xfs_growfs", devicePath).CombinedOutput()
|
||||||
}
|
}
|
||||||
if (err != nil)
|
if (err != nil)
|
||||||
{
|
{
|
||||||
|
klog.Errorf("failed to run resizefs error: %v, output: %v", err, string(cmdOut))
|
||||||
goto unmap
|
goto unmap
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -412,7 +385,7 @@ func (ns *NodeServer) NodeUnstageVolume(ctx context.Context, req *csi.NodeUnstag
|
||||||
defer ns.unlockVolume(ctxVars["configPath"]+":"+volName)
|
defer ns.unlockVolume(ctxVars["configPath"]+":"+volName)
|
||||||
|
|
||||||
targetPath := req.GetStagingTargetPath()
|
targetPath := req.GetStagingTargetPath()
|
||||||
devicePath, _, err := mount.GetDeviceNameFromMount(ns.mounter, targetPath)
|
devicePath, refCount, err := mount.GetDeviceNameFromMount(ns.mounter, targetPath)
|
||||||
if (err != nil)
|
if (err != nil)
|
||||||
{
|
{
|
||||||
if (os.IsNotExist(err))
|
if (os.IsNotExist(err))
|
||||||
|
@ -429,16 +402,6 @@ func (ns *NodeServer) NodeUnstageVolume(ctx context.Context, req *csi.NodeUnstag
|
||||||
return &csi.NodeUnstageVolumeResponse{}, nil
|
return &csi.NodeUnstageVolumeResponse{}, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
refList, err := ns.mounter.GetMountRefs(targetPath)
|
|
||||||
if (err != nil)
|
|
||||||
{
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
if (len(refList) > 0)
|
|
||||||
{
|
|
||||||
klog.Warningf("%s is still referenced: %v", targetPath, refList)
|
|
||||||
}
|
|
||||||
|
|
||||||
// unmount
|
// unmount
|
||||||
err = mount.CleanupMountPoint(targetPath, ns.mounter, false)
|
err = mount.CleanupMountPoint(targetPath, ns.mounter, false)
|
||||||
if (err != nil)
|
if (err != nil)
|
||||||
|
@ -447,7 +410,7 @@ func (ns *NodeServer) NodeUnstageVolume(ctx context.Context, req *csi.NodeUnstag
|
||||||
}
|
}
|
||||||
|
|
||||||
// unmap device
|
// unmap device
|
||||||
if (len(refList) == 0)
|
if (refCount == 1)
|
||||||
{
|
{
|
||||||
if (!ns.useVduse)
|
if (!ns.useVduse)
|
||||||
{
|
{
|
||||||
|
@ -488,20 +451,15 @@ func (ns *NodeServer) NodePublishVolume(ctx context.Context, req *csi.NodePublis
|
||||||
isBlock := req.GetVolumeCapability().GetBlock() != nil
|
isBlock := req.GetVolumeCapability().GetBlock() != nil
|
||||||
|
|
||||||
// Check that stagingTargetPath is mounted
|
// Check that stagingTargetPath is mounted
|
||||||
notmnt, err := mount.IsNotMountPoint(ns.mounter, stagingTargetPath)
|
_, err = mount.IsNotMountPoint(ns.mounter, stagingTargetPath)
|
||||||
if (err != nil)
|
if (err != nil)
|
||||||
{
|
{
|
||||||
klog.Errorf("staging path %v is not mounted: %w", stagingTargetPath, err)
|
klog.Errorf("staging path %v is not mounted: %v", stagingTargetPath, err)
|
||||||
return nil, fmt.Errorf("staging path %v is not mounted: %w", stagingTargetPath, err)
|
return nil, fmt.Errorf("staging path %v is not mounted: %v", stagingTargetPath, err)
|
||||||
}
|
|
||||||
else if (notmnt)
|
|
||||||
{
|
|
||||||
klog.Errorf("staging path %v is not mounted", stagingTargetPath)
|
|
||||||
return nil, fmt.Errorf("staging path %v is not mounted", stagingTargetPath)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Check that targetPath is not already mounted
|
// Check that targetPath is not already mounted
|
||||||
notmnt, err = mount.IsNotMountPoint(ns.mounter, targetPath)
|
_, err = mount.IsNotMountPoint(ns.mounter, targetPath)
|
||||||
if (err != nil)
|
if (err != nil)
|
||||||
{
|
{
|
||||||
if (os.IsNotExist(err))
|
if (os.IsNotExist(err))
|
||||||
|
@ -536,11 +494,6 @@ func (ns *NodeServer) NodePublishVolume(ctx context.Context, req *csi.NodePublis
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else if (!notmnt)
|
|
||||||
{
|
|
||||||
klog.Errorf("target path %s is already mounted", targetPath)
|
|
||||||
return nil, fmt.Errorf("target path %s is already mounted", targetPath)
|
|
||||||
}
|
|
||||||
|
|
||||||
execArgs := []string{"--bind", stagingTargetPath, targetPath}
|
execArgs := []string{"--bind", stagingTargetPath, targetPath}
|
||||||
if (req.GetReadonly())
|
if (req.GetReadonly())
|
||||||
|
|
|
@ -4,7 +4,6 @@
|
||||||
package vitastor
|
package vitastor
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"bytes"
|
|
||||||
"errors"
|
"errors"
|
||||||
"encoding/json"
|
"encoding/json"
|
||||||
"fmt"
|
"fmt"
|
||||||
|
@ -16,8 +15,6 @@ import (
|
||||||
"syscall"
|
"syscall"
|
||||||
|
|
||||||
"k8s.io/klog"
|
"k8s.io/klog"
|
||||||
"google.golang.org/grpc/codes"
|
|
||||||
"google.golang.org/grpc/status"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
func Contains(list []string, s string) bool
|
func Contains(list []string, s string) bool
|
||||||
|
@ -76,10 +73,6 @@ func checkVduseSupport() bool
|
||||||
" For VDUSE you need at least Linux 5.15 and the following kernel modules: vdpa, virtio-vdpa, vduse.",
|
" For VDUSE you need at least Linux 5.15 and the following kernel modules: vdpa, virtio-vdpa, vduse.",
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
else
|
|
||||||
{
|
|
||||||
klog.Infof("VDUSE support enabled successfully")
|
|
||||||
}
|
|
||||||
return vduse
|
return vduse
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -104,7 +97,6 @@ func mapNbd(volName string, ctxVars map[string]string, readonly bool) (string, e
|
||||||
{
|
{
|
||||||
return "", fmt.Errorf("vitastor-nbd did not return the name of NBD device. output: %s", stderr)
|
return "", fmt.Errorf("vitastor-nbd did not return the name of NBD device. output: %s", stderr)
|
||||||
}
|
}
|
||||||
klog.Infof("Attached volume %s via NBD as %s", volName, dev)
|
|
||||||
return dev, err
|
return dev, err
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -225,7 +217,6 @@ func mapVduse(stateDir string, volName string, ctxVars map[string]string, readon
|
||||||
err = os.WriteFile(stateFile, stateJSON, 0600)
|
err = os.WriteFile(stateFile, stateJSON, 0600)
|
||||||
if (err == nil)
|
if (err == nil)
|
||||||
{
|
{
|
||||||
klog.Infof("Attached volume %s via VDUSE as %s (VDPA ID %s)", volName, blockdev, vdpaId)
|
|
||||||
return blockdev, vdpaId, nil
|
return blockdev, vdpaId, nil
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -308,35 +299,3 @@ func unmapVduseById(stateDir, vdpaId string)
|
||||||
os.Remove(pidFile)
|
os.Remove(pidFile)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func system(program string, args ...string) ([]byte, []byte, error)
|
|
||||||
{
|
|
||||||
klog.Infof("Running "+program+" "+strings.Join(args, " "))
|
|
||||||
c := exec.Command(program, args...)
|
|
||||||
var stdout, stderr bytes.Buffer
|
|
||||||
c.Stdout, c.Stderr = &stdout, &stderr
|
|
||||||
err := c.Run()
|
|
||||||
if (err != nil)
|
|
||||||
{
|
|
||||||
stdoutStr, stderrStr := string(stdout.Bytes()), string(stderr.Bytes())
|
|
||||||
klog.Errorf(program+" "+strings.Join(args, " ")+" failed: %s\nOutput:\n%s", err, stdoutStr+stderrStr)
|
|
||||||
return nil, nil, status.Error(codes.Internal, stdoutStr+stderrStr+" (status "+err.Error()+")")
|
|
||||||
}
|
|
||||||
return stdout.Bytes(), stderr.Bytes(), nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func systemCombined(program string, args ...string) ([]byte, error)
|
|
||||||
{
|
|
||||||
klog.Infof("Running "+program+" "+strings.Join(args, " "))
|
|
||||||
c := exec.Command(program, args...)
|
|
||||||
var out bytes.Buffer
|
|
||||||
c.Stdout, c.Stderr = &out, &out
|
|
||||||
err := c.Run()
|
|
||||||
if (err != nil)
|
|
||||||
{
|
|
||||||
outStr := string(out.Bytes())
|
|
||||||
klog.Errorf(program+" "+strings.Join(args, " ")+" failed: %s, status %s\n", outStr, err)
|
|
||||||
return nil, status.Error(codes.Internal, outStr+" (status "+err.Error()+")")
|
|
||||||
}
|
|
||||||
return out.Bytes(), nil
|
|
||||||
}
|
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
vitastor (1.9.3-1) unstable; urgency=medium
|
vitastor (1.8.0-1) unstable; urgency=medium
|
||||||
|
|
||||||
* Bugfixes
|
* Bugfixes
|
||||||
|
|
||||||
|
|
|
@ -106,8 +106,8 @@ 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).
|
||||||
|
|
||||||
Setting this parameter to "all" or "small" in OSD parameters requires enabling
|
Setting this parameter to "all" or "small" in OSD parameters requires enabling
|
||||||
[disable_journal_fsync](layout-osd.en.md#disable_journal_fsync) and
|
[disable_journal_fsync](layout-osd.en.yml#disable_journal_fsync) and
|
||||||
[disable_meta_fsync](layout-osd.en.md#disable_meta_fsync), setting it to
|
[disable_meta_fsync](layout-osd.en.yml#disable_meta_fsync), setting it to
|
||||||
"all" also requires enabling [disable_data_fsync](layout-osd.en.md#disable_data_fsync).
|
"all" also requires enabling [disable_data_fsync](layout-osd.en.yml#disable_data_fsync).
|
||||||
vitastor-disk tried to do that by default, first checking/disabling drive cache.
|
vitastor-disk tried to do that by default, first checking/disabling drive cache.
|
||||||
If it can't disable drive cache, OSD get initialized with "none".
|
If it can't disable drive cache, OSD get initialized with "none".
|
||||||
|
|
|
@ -112,6 +112,6 @@ HDD-дисках с внутренним SSD или "медиа" кэшем - н
|
||||||
указано в спецификациях).
|
указано в спецификациях).
|
||||||
|
|
||||||
Указание "all" или "small" в настройках / командной строке OSD требует
|
Указание "all" или "small" в настройках / командной строке OSD требует
|
||||||
включения [disable_journal_fsync](layout-osd.ru.md#disable_journal_fsync) и
|
включения [disable_journal_fsync](layout-osd.ru.yml#disable_journal_fsync) и
|
||||||
[disable_meta_fsync](layout-osd.ru.md#disable_meta_fsync), значение "all"
|
[disable_meta_fsync](layout-osd.ru.yml#disable_meta_fsync), значение "all"
|
||||||
также требует включения [disable_data_fsync](layout-osd.ru.md#disable_data_fsync).
|
также требует включения [disable_data_fsync](layout-osd.ru.yml#disable_data_fsync).
|
||||||
|
|
|
@ -118,13 +118,12 @@ Physical block size of the journal device. Must be a multiple of
|
||||||
- Type: boolean
|
- Type: boolean
|
||||||
- Default: false
|
- Default: false
|
||||||
|
|
||||||
Do not issue fsyncs to the data device, i.e. do not force it to flush cache.
|
Do not issue fsyncs to the data device, i.e. do not flush its cache.
|
||||||
Safe ONLY if your data device has write-through cache or if write-back
|
Safe ONLY if your data device has write-through cache. If you disable
|
||||||
cache is disabled. If you disable drive cache manually with `hdparm` or
|
the cache yourself using `hdparm` or `scsi_disk/cache_type` then make sure
|
||||||
writing to `/sys/.../scsi_disk/cache_type` then make sure that you do it
|
that the cache disable command is run every time before starting Vitastor
|
||||||
every time before starting Vitastor OSD (vitastor-disk does it automatically).
|
OSD, for example, in the systemd unit. See also `immediate_commit` option
|
||||||
See also [immediate_commit](layout-cluster.en.md#immediate_commit)
|
for the instructions to disable cache and how to benefit from it.
|
||||||
for information about how to benefit from disabled cache.
|
|
||||||
|
|
||||||
## disable_meta_fsync
|
## disable_meta_fsync
|
||||||
|
|
||||||
|
@ -172,7 +171,8 @@ size, it actually has to write the whole 4 KB sector.
|
||||||
|
|
||||||
Because of this it can actually be beneficial to use SSDs which work well
|
Because of this it can actually be beneficial to use SSDs which work well
|
||||||
with 512 byte sectors and use 512 byte disk_alignment, journal_block_size
|
with 512 byte sectors and use 512 byte disk_alignment, journal_block_size
|
||||||
and meta_block_size. But at the moment, no such SSDs are known...
|
and meta_block_size. But the only SSD that may fit into this category is
|
||||||
|
Intel Optane (probably, not tested yet).
|
||||||
|
|
||||||
Clients don't need to be aware of disk_alignment, so it's not required to
|
Clients don't need to be aware of disk_alignment, so it's not required to
|
||||||
put a modified value into etcd key /vitastor/config/global.
|
put a modified value into etcd key /vitastor/config/global.
|
||||||
|
|
|
@ -122,14 +122,13 @@ SSD-диске, иначе производительность пострада
|
||||||
- Тип: булево (да/нет)
|
- Тип: булево (да/нет)
|
||||||
- Значение по умолчанию: false
|
- Значение по умолчанию: false
|
||||||
|
|
||||||
Не отправлять fsync-и устройству данных, т.е. не заставлять его сбрасывать кэш.
|
Не отправлять fsync-и устройству данных, т.е. не сбрасывать его кэш.
|
||||||
Безопасно, ТОЛЬКО если ваше устройство данных имеет кэш со сквозной
|
Безопасно, ТОЛЬКО если ваше устройство данных имеет кэш со сквозной
|
||||||
записью (write-through) или если кэш с отложенной записью (write-back) отключён.
|
записью (write-through). Если вы отключаете кэш через `hdparm` или
|
||||||
Если вы отключаете кэш вручную через `hdparm` или запись в `/sys/.../scsi_disk/cache_type`,
|
`scsi_disk/cache_type`, то удостоверьтесь, что команда отключения кэша
|
||||||
то удостоверьтесь, что вы делаете это каждый раз перед запуском Vitastor OSD
|
выполняется перед каждым запуском Vitastor OSD, например, в systemd unit-е.
|
||||||
(vitastor-disk делает это автоматически). Смотрите также опцию
|
Смотрите также опцию `immediate_commit` для инструкций по отключению кэша
|
||||||
[immediate_commit](layout-cluster.ru.md#immediate_commit) для информации о том,
|
и о том, как из этого извлечь выгоду.
|
||||||
как извлечь выгоду из отключённого кэша.
|
|
||||||
|
|
||||||
## disable_meta_fsync
|
## disable_meta_fsync
|
||||||
|
|
||||||
|
@ -180,8 +179,9 @@ SSD и HDD диски используют 4 КБ физические сект
|
||||||
|
|
||||||
Поэтому, на самом деле, может быть выгодно найти SSD, хорошо работающие с
|
Поэтому, на самом деле, может быть выгодно найти SSD, хорошо работающие с
|
||||||
меньшими, 512-байтными, блоками и использовать 512-байтные disk_alignment,
|
меньшими, 512-байтными, блоками и использовать 512-байтные disk_alignment,
|
||||||
journal_block_size и meta_block_size. Однако на данный момент такие SSD
|
journal_block_size и meta_block_size. Однако единственные SSD, которые
|
||||||
не известны...
|
теоретически могут попасть в эту категорию - это Intel Optane (но и это
|
||||||
|
пока не проверялось автором).
|
||||||
|
|
||||||
Клиентам не обязательно знать про disk_alignment, так что помещать значение
|
Клиентам не обязательно знать про disk_alignment, так что помещать значение
|
||||||
этого параметра в etcd в /vitastor/config/global не нужно.
|
этого параметра в etcd в /vitastor/config/global не нужно.
|
||||||
|
|
|
@ -68,17 +68,11 @@ but they are not connected to the cluster.
|
||||||
- Type: string
|
- Type: string
|
||||||
|
|
||||||
RDMA device name to use for Vitastor OSD communications (for example,
|
RDMA device name to use for Vitastor OSD communications (for example,
|
||||||
"rocep5s0f0"). If not specified, Vitastor will try to find an RoCE
|
"rocep5s0f0"). Now Vitastor supports all adapters, even ones without
|
||||||
device matching [osd_network](osd.en.md#osd_network), preferring RoCEv2,
|
ODP support, like Mellanox ConnectX-3 and non-Mellanox cards.
|
||||||
or choose the first available RDMA device if no RoCE devices are
|
|
||||||
found or if `osd_network` is not specified. Auto-selection is also
|
|
||||||
unsupported with old libibverbs < v32, like in Debian 10 Buster or
|
|
||||||
CentOS 7.
|
|
||||||
|
|
||||||
Vitastor supports all adapters, even ones without ODP support, like
|
Versions up to Vitastor 1.2.0 required ODP which is only present in
|
||||||
Mellanox ConnectX-3 and non-Mellanox cards. Versions up to Vitastor
|
Mellanox ConnectX >= 4. See also [rdma_odp](#rdma_odp).
|
||||||
1.2.0 required ODP which is only present in Mellanox ConnectX >= 4.
|
|
||||||
See also [rdma_odp](#rdma_odp).
|
|
||||||
|
|
||||||
Run `ibv_devinfo -v` as root to list available RDMA devices and their
|
Run `ibv_devinfo -v` as root to list available RDMA devices and their
|
||||||
features.
|
features.
|
||||||
|
@ -101,17 +95,15 @@ your device has.
|
||||||
## rdma_gid_index
|
## rdma_gid_index
|
||||||
|
|
||||||
- Type: integer
|
- Type: integer
|
||||||
|
- Default: 0
|
||||||
|
|
||||||
Global address identifier index of the RDMA device to use. Different GID
|
Global address identifier index of the RDMA device to use. Different GID
|
||||||
indexes may correspond to different protocols like RoCEv1, RoCEv2 and iWARP.
|
indexes may correspond to different protocols like RoCEv1, RoCEv2 and iWARP.
|
||||||
Search for "GID" in `ibv_devinfo -v` output to determine which GID index
|
Search for "GID" in `ibv_devinfo -v` output to determine which GID index
|
||||||
you need.
|
you need.
|
||||||
|
|
||||||
If not specified, Vitastor will try to auto-select a RoCEv2 IPv4 GID, then
|
**IMPORTANT:** If you want to use RoCEv2 (as recommended) then the correct
|
||||||
RoCEv2 IPv6 GID, then RoCEv1 IPv4 GID, then RoCEv1 IPv6 GID, then IB GID.
|
rdma_gid_index is usually 1 (IPv6) or 3 (IPv4).
|
||||||
GID auto-selection is unsupported with libibverbs < v32.
|
|
||||||
|
|
||||||
A correct rdma_gid_index for RoCEv2 is usually 1 (IPv6) or 3 (IPv4).
|
|
||||||
|
|
||||||
## rdma_mtu
|
## rdma_mtu
|
||||||
|
|
||||||
|
|
|
@ -71,17 +71,12 @@ RDMA может быть нужно только если у клиентов е
|
||||||
- Тип: строка
|
- Тип: строка
|
||||||
|
|
||||||
Название RDMA-устройства для связи с Vitastor OSD (например, "rocep5s0f0").
|
Название RDMA-устройства для связи с Vitastor OSD (например, "rocep5s0f0").
|
||||||
Если не указано, Vitastor попробует найти RoCE-устройство, соответствующее
|
Сейчас Vitastor поддерживает все модели адаптеров, включая те, у которых
|
||||||
[osd_network](osd.en.md#osd_network), предпочитая RoCEv2, или выбрать первое
|
|
||||||
попавшееся RDMA-устройство, если RoCE-устройств нет или если сеть `osd_network`
|
|
||||||
не задана. Также автовыбор не поддерживается со старыми версиями библиотеки
|
|
||||||
libibverbs < v32, например в Debian 10 Buster или CentOS 7.
|
|
||||||
|
|
||||||
Vitastor поддерживает все модели адаптеров, включая те, у которых
|
|
||||||
нет поддержки ODP, то есть вы можете использовать RDMA с ConnectX-3 и
|
нет поддержки ODP, то есть вы можете использовать RDMA с ConnectX-3 и
|
||||||
картами производства не Mellanox. Версии Vitastor до 1.2.0 включительно
|
картами производства не Mellanox.
|
||||||
требовали ODP, который есть только на Mellanox ConnectX 4 и более новых.
|
|
||||||
См. также [rdma_odp](#rdma_odp).
|
Версии Vitastor до 1.2.0 включительно требовали ODP, который есть только
|
||||||
|
на Mellanox ConnectX 4 и более новых. См. также [rdma_odp](#rdma_odp).
|
||||||
|
|
||||||
Запустите `ibv_devinfo -v` от имени суперпользователя, чтобы посмотреть
|
Запустите `ibv_devinfo -v` от имени суперпользователя, чтобы посмотреть
|
||||||
список доступных RDMA-устройств, их параметры и возможности.
|
список доступных RDMA-устройств, их параметры и возможности.
|
||||||
|
@ -106,18 +101,15 @@ Control) и ECN (Explicit Congestion Notification).
|
||||||
## rdma_gid_index
|
## rdma_gid_index
|
||||||
|
|
||||||
- Тип: целое число
|
- Тип: целое число
|
||||||
|
- Значение по умолчанию: 0
|
||||||
|
|
||||||
Номер глобального идентификатора адреса RDMA-устройства, который следует
|
Номер глобального идентификатора адреса RDMA-устройства, который следует
|
||||||
использовать. Разным gid_index могут соответствовать разные протоколы связи:
|
использовать. Разным gid_index могут соответствовать разные протоколы связи:
|
||||||
RoCEv1, RoCEv2, iWARP. Чтобы понять, какой нужен вам - смотрите строчки со
|
RoCEv1, RoCEv2, iWARP. Чтобы понять, какой нужен вам - смотрите строчки со
|
||||||
словом "GID" в выводе команды `ibv_devinfo -v`.
|
словом "GID" в выводе команды `ibv_devinfo -v`.
|
||||||
|
|
||||||
Если не указан, Vitastor попробует автоматически выбрать сначала GID,
|
**ВАЖНО:** Если вы хотите использовать RoCEv2 (как мы и рекомендуем), то
|
||||||
соответствующий RoCEv2 IPv4, потом RoCEv2 IPv6, потом RoCEv1 IPv4, потом
|
правильный rdma_gid_index, как правило, 1 (IPv6) или 3 (IPv4).
|
||||||
RoCEv1 IPv6, потом IB. Авто-выбор GID не поддерживается со старыми версиями
|
|
||||||
libibverbs < v32.
|
|
||||||
|
|
||||||
Правильный rdma_gid_index для RoCEv2, как правило, 1 (IPv6) или 3 (IPv4).
|
|
||||||
|
|
||||||
## rdma_mtu
|
## rdma_mtu
|
||||||
|
|
||||||
|
|
|
@ -55,7 +55,7 @@ Examples:
|
||||||
OSD placement tree is set in a separate etcd key `/vitastor/config/node_placement`
|
OSD placement tree is set in a separate etcd key `/vitastor/config/node_placement`
|
||||||
in the following JSON format:
|
in the following JSON format:
|
||||||
|
|
||||||
```
|
`
|
||||||
{
|
{
|
||||||
"<node name or OSD number>": {
|
"<node name or OSD number>": {
|
||||||
"level": "<level>",
|
"level": "<level>",
|
||||||
|
@ -63,7 +63,7 @@ in the following JSON format:
|
||||||
},
|
},
|
||||||
...
|
...
|
||||||
}
|
}
|
||||||
```
|
`
|
||||||
|
|
||||||
Here, if a node name is a number then it is assumed to refer to an OSD.
|
Here, if a node name is a number then it is assumed to refer to an OSD.
|
||||||
Level of the OSD is always "osd" and cannot be overriden. You may only
|
Level of the OSD is always "osd" and cannot be overriden. You may only
|
||||||
|
|
|
@ -54,7 +54,7 @@
|
||||||
Дерево размещения OSD задаётся в отдельном ключе etcd `/vitastor/config/node_placement`
|
Дерево размещения OSD задаётся в отдельном ключе etcd `/vitastor/config/node_placement`
|
||||||
в следующем JSON-формате:
|
в следующем JSON-формате:
|
||||||
|
|
||||||
```
|
`
|
||||||
{
|
{
|
||||||
"<имя узла или номер OSD>": {
|
"<имя узла или номер OSD>": {
|
||||||
"level": "<уровень>",
|
"level": "<уровень>",
|
||||||
|
@ -62,7 +62,7 @@
|
||||||
},
|
},
|
||||||
...
|
...
|
||||||
}
|
}
|
||||||
```
|
`
|
||||||
|
|
||||||
Здесь, если название узла - число, считается, что это OSD. Уровень OSD
|
Здесь, если название узла - число, считается, что это OSD. Уровень OSD
|
||||||
всегда равен "osd" и не может быть переопределён. Для OSD вы можете только
|
всегда равен "osd" и не может быть переопределён. Для OSD вы можете только
|
||||||
|
|
|
@ -97,9 +97,9 @@
|
||||||
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).
|
||||||
|
|
||||||
Setting this parameter to "all" or "small" in OSD parameters requires enabling
|
Setting this parameter to "all" or "small" in OSD parameters requires enabling
|
||||||
[disable_journal_fsync](layout-osd.en.md#disable_journal_fsync) and
|
[disable_journal_fsync](layout-osd.en.yml#disable_journal_fsync) and
|
||||||
[disable_meta_fsync](layout-osd.en.md#disable_meta_fsync), setting it to
|
[disable_meta_fsync](layout-osd.en.yml#disable_meta_fsync), setting it to
|
||||||
"all" also requires enabling [disable_data_fsync](layout-osd.en.md#disable_data_fsync).
|
"all" also requires enabling [disable_data_fsync](layout-osd.en.yml#disable_data_fsync).
|
||||||
vitastor-disk tried to do that by default, first checking/disabling drive cache.
|
vitastor-disk tried to do that by default, first checking/disabling drive cache.
|
||||||
If it can't disable drive cache, OSD get initialized with "none".
|
If it can't disable drive cache, OSD get initialized with "none".
|
||||||
info_ru: |
|
info_ru: |
|
||||||
|
@ -156,6 +156,6 @@
|
||||||
указано в спецификациях).
|
указано в спецификациях).
|
||||||
|
|
||||||
Указание "all" или "small" в настройках / командной строке OSD требует
|
Указание "all" или "small" в настройках / командной строке OSD требует
|
||||||
включения [disable_journal_fsync](layout-osd.ru.md#disable_journal_fsync) и
|
включения [disable_journal_fsync](layout-osd.ru.yml#disable_journal_fsync) и
|
||||||
[disable_meta_fsync](layout-osd.ru.md#disable_meta_fsync), значение "all"
|
[disable_meta_fsync](layout-osd.ru.yml#disable_meta_fsync), значение "all"
|
||||||
также требует включения [disable_data_fsync](layout-osd.ru.md#disable_data_fsync).
|
также требует включения [disable_data_fsync](layout-osd.ru.yml#disable_data_fsync).
|
||||||
|
|
|
@ -110,22 +110,20 @@
|
||||||
type: bool
|
type: bool
|
||||||
default: false
|
default: false
|
||||||
info: |
|
info: |
|
||||||
Do not issue fsyncs to the data device, i.e. do not force it to flush cache.
|
Do not issue fsyncs to the data device, i.e. do not flush its cache.
|
||||||
Safe ONLY if your data device has write-through cache or if write-back
|
Safe ONLY if your data device has write-through cache. If you disable
|
||||||
cache is disabled. If you disable drive cache manually with `hdparm` or
|
the cache yourself using `hdparm` or `scsi_disk/cache_type` then make sure
|
||||||
writing to `/sys/.../scsi_disk/cache_type` then make sure that you do it
|
that the cache disable command is run every time before starting Vitastor
|
||||||
every time before starting Vitastor OSD (vitastor-disk does it automatically).
|
OSD, for example, in the systemd unit. See also `immediate_commit` option
|
||||||
See also [immediate_commit](layout-cluster.en.md#immediate_commit)
|
for the instructions to disable cache and how to benefit from it.
|
||||||
for information about how to benefit from disabled cache.
|
|
||||||
info_ru: |
|
info_ru: |
|
||||||
Не отправлять fsync-и устройству данных, т.е. не заставлять его сбрасывать кэш.
|
Не отправлять fsync-и устройству данных, т.е. не сбрасывать его кэш.
|
||||||
Безопасно, ТОЛЬКО если ваше устройство данных имеет кэш со сквозной
|
Безопасно, ТОЛЬКО если ваше устройство данных имеет кэш со сквозной
|
||||||
записью (write-through) или если кэш с отложенной записью (write-back) отключён.
|
записью (write-through). Если вы отключаете кэш через `hdparm` или
|
||||||
Если вы отключаете кэш вручную через `hdparm` или запись в `/sys/.../scsi_disk/cache_type`,
|
`scsi_disk/cache_type`, то удостоверьтесь, что команда отключения кэша
|
||||||
то удостоверьтесь, что вы делаете это каждый раз перед запуском Vitastor OSD
|
выполняется перед каждым запуском Vitastor OSD, например, в systemd unit-е.
|
||||||
(vitastor-disk делает это автоматически). Смотрите также опцию
|
Смотрите также опцию `immediate_commit` для инструкций по отключению кэша
|
||||||
[immediate_commit](layout-cluster.ru.md#immediate_commit) для информации о том,
|
и о том, как из этого извлечь выгоду.
|
||||||
как извлечь выгоду из отключённого кэша.
|
|
||||||
- name: disable_meta_fsync
|
- name: disable_meta_fsync
|
||||||
type: bool
|
type: bool
|
||||||
default: false
|
default: false
|
||||||
|
@ -181,7 +179,8 @@
|
||||||
|
|
||||||
Because of this it can actually be beneficial to use SSDs which work well
|
Because of this it can actually be beneficial to use SSDs which work well
|
||||||
with 512 byte sectors and use 512 byte disk_alignment, journal_block_size
|
with 512 byte sectors and use 512 byte disk_alignment, journal_block_size
|
||||||
and meta_block_size. But at the moment, no such SSDs are known...
|
and meta_block_size. But the only SSD that may fit into this category is
|
||||||
|
Intel Optane (probably, not tested yet).
|
||||||
|
|
||||||
Clients don't need to be aware of disk_alignment, so it's not required to
|
Clients don't need to be aware of disk_alignment, so it's not required to
|
||||||
put a modified value into etcd key /vitastor/config/global.
|
put a modified value into etcd key /vitastor/config/global.
|
||||||
|
@ -199,8 +198,9 @@
|
||||||
|
|
||||||
Поэтому, на самом деле, может быть выгодно найти SSD, хорошо работающие с
|
Поэтому, на самом деле, может быть выгодно найти SSD, хорошо работающие с
|
||||||
меньшими, 512-байтными, блоками и использовать 512-байтные disk_alignment,
|
меньшими, 512-байтными, блоками и использовать 512-байтные disk_alignment,
|
||||||
journal_block_size и meta_block_size. Однако на данный момент такие SSD
|
journal_block_size и meta_block_size. Однако единственные SSD, которые
|
||||||
не известны...
|
теоретически могут попасть в эту категорию - это Intel Optane (но и это
|
||||||
|
пока не проверялось автором).
|
||||||
|
|
||||||
Клиентам не обязательно знать про disk_alignment, так что помещать значение
|
Клиентам не обязательно знать про disk_alignment, так что помещать значение
|
||||||
этого параметра в etcd в /vitastor/config/global не нужно.
|
этого параметра в etcd в /vitastor/config/global не нужно.
|
||||||
|
|
|
@ -48,17 +48,11 @@
|
||||||
type: string
|
type: string
|
||||||
info: |
|
info: |
|
||||||
RDMA device name to use for Vitastor OSD communications (for example,
|
RDMA device name to use for Vitastor OSD communications (for example,
|
||||||
"rocep5s0f0"). If not specified, Vitastor will try to find an RoCE
|
"rocep5s0f0"). Now Vitastor supports all adapters, even ones without
|
||||||
device matching [osd_network](osd.en.md#osd_network), preferring RoCEv2,
|
ODP support, like Mellanox ConnectX-3 and non-Mellanox cards.
|
||||||
or choose the first available RDMA device if no RoCE devices are
|
|
||||||
found or if `osd_network` is not specified. Auto-selection is also
|
|
||||||
unsupported with old libibverbs < v32, like in Debian 10 Buster or
|
|
||||||
CentOS 7.
|
|
||||||
|
|
||||||
Vitastor supports all adapters, even ones without ODP support, like
|
Versions up to Vitastor 1.2.0 required ODP which is only present in
|
||||||
Mellanox ConnectX-3 and non-Mellanox cards. Versions up to Vitastor
|
Mellanox ConnectX >= 4. See also [rdma_odp](#rdma_odp).
|
||||||
1.2.0 required ODP which is only present in Mellanox ConnectX >= 4.
|
|
||||||
See also [rdma_odp](#rdma_odp).
|
|
||||||
|
|
||||||
Run `ibv_devinfo -v` as root to list available RDMA devices and their
|
Run `ibv_devinfo -v` as root to list available RDMA devices and their
|
||||||
features.
|
features.
|
||||||
|
@ -70,17 +64,12 @@
|
||||||
PFC (Priority Flow Control) and ECN (Explicit Congestion Notification).
|
PFC (Priority Flow Control) and ECN (Explicit Congestion Notification).
|
||||||
info_ru: |
|
info_ru: |
|
||||||
Название RDMA-устройства для связи с Vitastor OSD (например, "rocep5s0f0").
|
Название RDMA-устройства для связи с Vitastor OSD (например, "rocep5s0f0").
|
||||||
Если не указано, Vitastor попробует найти RoCE-устройство, соответствующее
|
Сейчас Vitastor поддерживает все модели адаптеров, включая те, у которых
|
||||||
[osd_network](osd.en.md#osd_network), предпочитая RoCEv2, или выбрать первое
|
|
||||||
попавшееся RDMA-устройство, если RoCE-устройств нет или если сеть `osd_network`
|
|
||||||
не задана. Также автовыбор не поддерживается со старыми версиями библиотеки
|
|
||||||
libibverbs < v32, например в Debian 10 Buster или CentOS 7.
|
|
||||||
|
|
||||||
Vitastor поддерживает все модели адаптеров, включая те, у которых
|
|
||||||
нет поддержки ODP, то есть вы можете использовать RDMA с ConnectX-3 и
|
нет поддержки ODP, то есть вы можете использовать RDMA с ConnectX-3 и
|
||||||
картами производства не Mellanox. Версии Vitastor до 1.2.0 включительно
|
картами производства не Mellanox.
|
||||||
требовали ODP, который есть только на Mellanox ConnectX 4 и более новых.
|
|
||||||
См. также [rdma_odp](#rdma_odp).
|
Версии Vitastor до 1.2.0 включительно требовали ODP, который есть только
|
||||||
|
на Mellanox ConnectX 4 и более новых. См. также [rdma_odp](#rdma_odp).
|
||||||
|
|
||||||
Запустите `ibv_devinfo -v` от имени суперпользователя, чтобы посмотреть
|
Запустите `ibv_devinfo -v` от имени суперпользователя, чтобы посмотреть
|
||||||
список доступных RDMA-устройств, их параметры и возможности.
|
список доступных RDMA-устройств, их параметры и возможности.
|
||||||
|
@ -105,29 +94,23 @@
|
||||||
`ibv_devinfo -v`.
|
`ibv_devinfo -v`.
|
||||||
- name: rdma_gid_index
|
- name: rdma_gid_index
|
||||||
type: int
|
type: int
|
||||||
|
default: 0
|
||||||
info: |
|
info: |
|
||||||
Global address identifier index of the RDMA device to use. Different GID
|
Global address identifier index of the RDMA device to use. Different GID
|
||||||
indexes may correspond to different protocols like RoCEv1, RoCEv2 and iWARP.
|
indexes may correspond to different protocols like RoCEv1, RoCEv2 and iWARP.
|
||||||
Search for "GID" in `ibv_devinfo -v` output to determine which GID index
|
Search for "GID" in `ibv_devinfo -v` output to determine which GID index
|
||||||
you need.
|
you need.
|
||||||
|
|
||||||
If not specified, Vitastor will try to auto-select a RoCEv2 IPv4 GID, then
|
**IMPORTANT:** If you want to use RoCEv2 (as recommended) then the correct
|
||||||
RoCEv2 IPv6 GID, then RoCEv1 IPv4 GID, then RoCEv1 IPv6 GID, then IB GID.
|
rdma_gid_index is usually 1 (IPv6) or 3 (IPv4).
|
||||||
GID auto-selection is unsupported with libibverbs < v32.
|
|
||||||
|
|
||||||
A correct rdma_gid_index for RoCEv2 is usually 1 (IPv6) or 3 (IPv4).
|
|
||||||
info_ru: |
|
info_ru: |
|
||||||
Номер глобального идентификатора адреса RDMA-устройства, который следует
|
Номер глобального идентификатора адреса RDMA-устройства, который следует
|
||||||
использовать. Разным gid_index могут соответствовать разные протоколы связи:
|
использовать. Разным gid_index могут соответствовать разные протоколы связи:
|
||||||
RoCEv1, RoCEv2, iWARP. Чтобы понять, какой нужен вам - смотрите строчки со
|
RoCEv1, RoCEv2, iWARP. Чтобы понять, какой нужен вам - смотрите строчки со
|
||||||
словом "GID" в выводе команды `ibv_devinfo -v`.
|
словом "GID" в выводе команды `ibv_devinfo -v`.
|
||||||
|
|
||||||
Если не указан, Vitastor попробует автоматически выбрать сначала GID,
|
**ВАЖНО:** Если вы хотите использовать RoCEv2 (как мы и рекомендуем), то
|
||||||
соответствующий RoCEv2 IPv4, потом RoCEv2 IPv6, потом RoCEv1 IPv4, потом
|
правильный rdma_gid_index, как правило, 1 (IPv6) или 3 (IPv4).
|
||||||
RoCEv1 IPv6, потом IB. Авто-выбор GID не поддерживается со старыми версиями
|
|
||||||
libibverbs < v32.
|
|
||||||
|
|
||||||
Правильный rdma_gid_index для RoCEv2, как правило, 1 (IPv6) или 3 (IPv4).
|
|
||||||
- name: rdma_mtu
|
- name: rdma_mtu
|
||||||
type: int
|
type: int
|
||||||
default: 4096
|
default: 4096
|
||||||
|
|
|
@ -0,0 +1,55 @@
|
||||||
|
#!/usr/bin/nodejs
|
||||||
|
|
||||||
|
const fs = require('fs');
|
||||||
|
const yaml = require('yaml');
|
||||||
|
|
||||||
|
const L = {
|
||||||
|
en: {},
|
||||||
|
ru: {
|
||||||
|
Type: 'Тип',
|
||||||
|
Default: 'Значение по умолчанию',
|
||||||
|
Minimum: 'Минимальное значение',
|
||||||
|
},
|
||||||
|
};
|
||||||
|
const types = {
|
||||||
|
en: {
|
||||||
|
string: 'string',
|
||||||
|
bool: 'boolean',
|
||||||
|
int: 'integer',
|
||||||
|
sec: 'seconds',
|
||||||
|
ms: 'milliseconds',
|
||||||
|
us: 'microseconds',
|
||||||
|
},
|
||||||
|
ru: {
|
||||||
|
string: 'строка',
|
||||||
|
bool: 'булево (да/нет)',
|
||||||
|
int: 'целое число',
|
||||||
|
sec: 'секунды',
|
||||||
|
ms: 'миллисекунды',
|
||||||
|
us: 'микросекунды',
|
||||||
|
},
|
||||||
|
};
|
||||||
|
const params_files = fs.readdirSync(__dirname+'/params')
|
||||||
|
.filter(f => f.substr(-4) == '.yml')
|
||||||
|
.map(f => f.substr(0, f.length-4));
|
||||||
|
|
||||||
|
for (const file of params_files)
|
||||||
|
{
|
||||||
|
const cfg = yaml.parse(fs.readFileSync(__dirname+'/params/'+file+'.yml', { encoding: 'utf-8' }));
|
||||||
|
for (const lang in types)
|
||||||
|
{
|
||||||
|
let out = '\n\n{{< toc >}}';
|
||||||
|
for (const c of cfg)
|
||||||
|
{
|
||||||
|
out += `\n\n## ${c.name}\n\n`;
|
||||||
|
out += `- ${L[lang]['Type'] || 'Type'}: ${c["type_"+lang] || types[lang][c.type] || c.type}\n`;
|
||||||
|
if (c.default !== undefined)
|
||||||
|
out += `- ${L[lang]['Default'] || 'Default'}: ${c.default}\n`;
|
||||||
|
if (c.min !== undefined)
|
||||||
|
out += `- ${L[lang]['Minimum'] || 'Minimum'}: ${c.min}\n`;
|
||||||
|
out += `\n`+(c["info_"+lang] || c["info"]).replace(/\s+$/, '');
|
||||||
|
}
|
||||||
|
const head = fs.readFileSync(__dirname+'/params/head/'+file+'.'+lang+'.md', { encoding: 'utf-8' });
|
||||||
|
fs.writeFileSync(__dirname+'/hugo/content/config/'+file+'.'+lang+'.md', head.replace(/\s+$/, '')+out+"\n");
|
||||||
|
}
|
||||||
|
}
|
|
@ -4,8 +4,6 @@
|
||||||
|
|
||||||
[Читать на русском](opennebula.ru.md)
|
[Читать на русском](opennebula.ru.md)
|
||||||
|
|
||||||
# OpenNebula
|
|
||||||
|
|
||||||
## Automatic Installation
|
## Automatic Installation
|
||||||
|
|
||||||
OpenNebula plugin is packaged as `vitastor-opennebula` Debian and RPM package since Vitastor 1.9.0. So:
|
OpenNebula plugin is packaged as `vitastor-opennebula` Debian and RPM package since Vitastor 1.9.0. So:
|
||||||
|
|
|
@ -4,8 +4,6 @@
|
||||||
|
|
||||||
[Read in English](opennebula.en.md)
|
[Read in English](opennebula.en.md)
|
||||||
|
|
||||||
# OpenNebula
|
|
||||||
|
|
||||||
## Автоматическая установка
|
## Автоматическая установка
|
||||||
|
|
||||||
Плагин OpenNebula Vitastor распространяется как Debian и RPM пакет `vitastor-opennebula`, начиная с версии Vitastor 1.9.0. Так что:
|
Плагин OpenNebula Vitastor распространяется как Debian и RPM пакет `vitastor-opennebula`, начиная с версии Vitastor 1.9.0. Так что:
|
||||||
|
|
|
@ -6,150 +6,19 @@
|
||||||
|
|
||||||
# Architecture
|
# Architecture
|
||||||
|
|
||||||
- [Server-side components](#server-side-components)
|
|
||||||
- [Basic concepts](#basic-concepts)
|
- [Basic concepts](#basic-concepts)
|
||||||
- [Client-side components](#client-side-components)
|
|
||||||
- [Additional utilities](#additional-utilities)
|
|
||||||
- [Overall read/write process](#overall-read-write-process)
|
|
||||||
- [Nuances of request handling](#nuances-of-request-handling)
|
|
||||||
- [Similarities to Ceph](#similarities-to-ceph)
|
- [Similarities to Ceph](#similarities-to-ceph)
|
||||||
- [Differences from Ceph](#differences-from-ceph)
|
- [Differences from Ceph](#differences-from-ceph)
|
||||||
- [Implementation Principles](#implementation-principles)
|
- [Implementation Principles](#implementation-principles)
|
||||||
|
|
||||||
## Server-side components
|
|
||||||
|
|
||||||
- **OSD** (Object Storage Daemon) is a process that directly works with the disk, stores data
|
|
||||||
and serves read/write requests. One OSD serves one disk (or one partition). OSDs talk to etcd
|
|
||||||
and to each other — they receive cluster state from etcd, and send read/write requests for
|
|
||||||
secondary copies of data to other OSDs.
|
|
||||||
- **etcd** — clustered key/value database, used as a reliable storage for configuration
|
|
||||||
and high-level cluster state. Etcd is the component that prevents splitbrain in the cluster.
|
|
||||||
Data blocks are not stored in etcd, etcd doesn't participate in data write or read path.
|
|
||||||
- **Монитор** — a separate node.js based daemon which monitors the cluster, calculates
|
|
||||||
required configuration changes and saves them to etcd, thus commanding OSDs to apply these
|
|
||||||
changes. Monitor also aggregates cluster statistics. OSD don't talk to monitor, monitor
|
|
||||||
only sends and receives data from etcd.
|
|
||||||
|
|
||||||
## Basic concepts
|
## Basic concepts
|
||||||
|
|
||||||
- **Pool** is a container for data that has equal redundancy scheme and disk placement rules.
|
- OSD (Object Storage Daemon) is a process that stores data and serves read/write requests.
|
||||||
- **PG (Placement Group)** is a "shard" of the cluster, subdivision unit that has its own
|
- PG (Placement Group) is a "shard" of the cluster, group of data stored on one set of replicas.
|
||||||
set of OSDs for data storage.
|
- Pool is a container for data that has equal redundancy scheme and placement rules.
|
||||||
- **Failure Domain** is a group of OSDs, from the simultaneous failure of which you are
|
- Monitor is a separate daemon that watches cluster state and handles failures.
|
||||||
protected by Vitastor. Default failure domain is "host" (server), but you choose a
|
- Failure Domain is a group of OSDs that you allow to fail. It's "host" by default.
|
||||||
larger (for example, a rack of servers) or smaller (a single drive) failure domain
|
- Placement Tree groups OSDs in a hierarchy to later split them into Failure Domains.
|
||||||
for every pool.
|
|
||||||
- **Placement Tree** (similar to Ceph CRUSH Tree) groups OSDs in a hierarchy to later
|
|
||||||
split them into Failure Domains.
|
|
||||||
|
|
||||||
## Client-side components
|
|
||||||
|
|
||||||
- **Client library** encapsulates client I/O logic. Client library connects to etcd and to all OSDs,
|
|
||||||
receives cluster state from etcd, sends read and write requests directly to all OSDs. Due
|
|
||||||
to the symmetric distributed architecture, all data blocks (each 128 KB by default) are placed
|
|
||||||
to different OSDs, but clients always know where each data block is stored and connect directly
|
|
||||||
to the right OSD.
|
|
||||||
|
|
||||||
All other client-side components are based on the client library:
|
|
||||||
|
|
||||||
- **[vitastor-cli](../usage/cli.en.md)** — command-line utility for cluster management.
|
|
||||||
Allows to view cluster state, manage pools and images, i.e. create, modify and remove
|
|
||||||
virtual disks, their snapshots and clones.
|
|
||||||
- **[QEMU driver](../usage/qemu.en.md)** — pluggable QEMU module allowing QEMU/KVM virtual
|
|
||||||
machines work with virtual Vitastor disks directly from userspace through the client library,
|
|
||||||
without the need to attach disks as kernel block devices. However, if you want to attach
|
|
||||||
disks, you can also do that with the same driver and [VDUSE](../usage/qemu.en.md#vduse).
|
|
||||||
- **[vitastor-nbd](../usage/nbd.en.md)** — utility that allows to attach Vitastor disks as
|
|
||||||
kernel block devices using NBD (Network Block Device), which works more like "BUSE"
|
|
||||||
(Block Device In Userspace). Vitastor doesn't have Linux kernel modules for the same task
|
|
||||||
(at least by now). NBD is an older, non-recommended way to attach disks — you should use
|
|
||||||
VDUSE whenever you can.
|
|
||||||
- **[CSI driver](../installation/kubernetes.en.md)** — driver for attaching Vitastor images
|
|
||||||
as Kubernetes persistent volumes. Works through VDUSE (when available) or NBD — images are
|
|
||||||
attached as kernel block devices and mounted into containers.
|
|
||||||
- **Drivers for Proxmox, OpenStack and so on** — pluggable modules for corresponding systems,
|
|
||||||
allowing to use Vitastor as storage in them.
|
|
||||||
- **[vitastor-nfs](../usage/nfs.en.md)** — NFS 3.0 server allowing export of two file system variants:
|
|
||||||
the first is a simplified pseudo-FS for file-based access to Vitastor block images (for non-QEMU
|
|
||||||
hypervisors with NFS support), the second is **VitastorFS**, full-featured clustered POSIX FS.
|
|
||||||
Both variants support parallel access from multiple vitastor-nfs servers. In fact, you are
|
|
||||||
not required to setup separate NFS servers at all and use vitastor-nfs mount command on every
|
|
||||||
client node — it starts the NFS server and mounts the FS locally.
|
|
||||||
- **[fio driver](../usage/fio.en.md)** — pluggable module for fio disk benchmarking tool for
|
|
||||||
running performance tests on your Vitastor cluster.
|
|
||||||
- **vitastor-kv** — client for a key-value DB working over shared block volumes (usual
|
|
||||||
vitastor images). VitastorFS metadata is stored in vitastor-kv.
|
|
||||||
|
|
||||||
## Additional utilities
|
|
||||||
|
|
||||||
- **vitastor-disk** — a Vitastor OSD disk management tool. You can create, remove,
|
|
||||||
resize and move OSD partitions with it.
|
|
||||||
|
|
||||||
## Overall read/write process
|
|
||||||
|
|
||||||
- Vitastor stores virtual disks, also named "images" or "inodes".
|
|
||||||
- Each image is stored in some pool. Pool specifies storage parameters such as redundancy
|
|
||||||
scheme (replication or EC — erasure codes, i.e. error correction codes), failure domain
|
|
||||||
and restrictions on OSD selection for image data placement. See [Pool configuration](../config/pool.en.md) for details.
|
|
||||||
- Each image is split into objects/blocks of fixed size, equal to [block_size](../config/layout-cluster.en.md#block_size)
|
|
||||||
(128 KB by default), multiplied by data part count for EC or 1 for replicas. That is,
|
|
||||||
if a pool uses EC 4+2 coding scheme (4 data parts + 2 parity parts), then, with the
|
|
||||||
default block_size, images are split into 512 KB objects.
|
|
||||||
- Client read/write requests are split into parts at object boundaries.
|
|
||||||
- Each object is mapped to a PG number it belongs to, by simply taking a remainder of
|
|
||||||
division of its offset by PG count of the image's pool.
|
|
||||||
- Client reads primary OSD for all PGs from etcd. Primary OSD for each PG is assigned
|
|
||||||
by the monitor during cluster operation, along with the full PG OSD set.
|
|
||||||
- If not already connected, client connects to primary OSDs of all PGs involved in a
|
|
||||||
read/write request and sends parts of the request to them.
|
|
||||||
- If a primary OSD is unavailable, client retries connection attempts indefinitely
|
|
||||||
either until it becomes available or until the monitor assigns another OSD as primary
|
|
||||||
for that PG.
|
|
||||||
- Client also retries requests if the primary OSD replies with error code EPIPE, meaning
|
|
||||||
that the PG is inactive at this OSD at the moment - for example, when the primary OSD
|
|
||||||
is switched, or if the primary OSD itself loses connection to replicas during request
|
|
||||||
handling.
|
|
||||||
- Primary OSD determines where the parts of the object are stored. By default, all objects
|
|
||||||
are assumed to be stored at the target OSD set of a PG, but some of them may be present
|
|
||||||
at a different OSD set if they are degraded or moved, or if the data rebalancing process
|
|
||||||
is active. OSDs doesn't do any network requests, if calculates locations of all objects
|
|
||||||
during PG activation and stores it in memory.
|
|
||||||
- Primary OSD handles the request locally when it can - for example, when it's a read
|
|
||||||
from a replicated pool or when it's a read from a EC pool involving only one data part
|
|
||||||
stored on the OSD's local disk.
|
|
||||||
- When a request requires reads or writes to additional OSDs, primary OSD uses already
|
|
||||||
established connections to secondary OSDs of the PG to execute these requests. This happens
|
|
||||||
in parallel to local disk operations. All such connections are guaranteed to be already
|
|
||||||
established when the PG is active, and if any of them is dropped, PG is restarted and
|
|
||||||
all current read/write operations to it fail with EPIPE error and are retried by clients.
|
|
||||||
- After completing all secondary read/write requests, primary OSD sends the response to
|
|
||||||
the client.
|
|
||||||
|
|
||||||
### Nuances of request handling
|
|
||||||
|
|
||||||
- If a pool uses erasure codes and some of the OSDs are unavailable, primary OSDs recover
|
|
||||||
data from the remaining parts during read.
|
|
||||||
- Each object has a version number. During write, primary OSD first determines the current
|
|
||||||
version of the object. As primary OSD usually stores the object or its part itself, most
|
|
||||||
of the time version is read from the memory of the OSD itself. However, if primary OSD
|
|
||||||
doesn't contain parts of the object, it requests the version number from a secondary OSD
|
|
||||||
which has that part. Such request still doesn't involve reading from the disk though,
|
|
||||||
because object metadata, including version number, is always stored in OSD memory.
|
|
||||||
- If a pool uses erasure codes, partial writes of an object require reading other parts of
|
|
||||||
it from secondary OSDs or from the local disk of the primary OSD itself. This is called
|
|
||||||
"read-modify-write" process.
|
|
||||||
- If a pool uses erasure codes, two-phase write process is used to get rid of the Write Hole
|
|
||||||
problem: first a new version of object parts is written to all secondary OSDs without
|
|
||||||
removing the previous version, and then, after receiving successful write confirmations
|
|
||||||
from all OSDs, new version is committed and the old one is allowed to be removed.
|
|
||||||
- In a pool doesn't use immediate_commit mode, then write requests sent by clients aren't
|
|
||||||
treated as committed to physical media instantly. Clients have to send separate type of
|
|
||||||
requests (SYNC) to commit changes, and before it isn't sent, new versions of data are
|
|
||||||
allowed to be lost if some OSDs die. Thus, when immediate_commit is disabled, clients
|
|
||||||
store copies of all write requests in memory and repeat them from there when the
|
|
||||||
connection to primary OSD is lost. This in-memory copy is removed after a successful
|
|
||||||
SYNC, and to prevent excessive memory usage, clients also do an automatic SYNC
|
|
||||||
every [client_dirty_limit](../config/network.en.md#client_dirty_limit) written bytes.
|
|
||||||
|
|
||||||
## Similarities to Ceph
|
## Similarities to Ceph
|
||||||
|
|
||||||
|
|
|
@ -11,7 +11,6 @@
|
||||||
- [Серверные компоненты](#серверные-компоненты)
|
- [Серверные компоненты](#серверные-компоненты)
|
||||||
- [Базовые понятия](#базовые-понятия)
|
- [Базовые понятия](#базовые-понятия)
|
||||||
- [Клиентские компоненты](#клиентские-компоненты)
|
- [Клиентские компоненты](#клиентские-компоненты)
|
||||||
- [Дополнительные утилиты](#дополнительные-утилиты)
|
|
||||||
- [Общий процесс записи и чтения](#общий-процесс-записи-и-чтения)
|
- [Общий процесс записи и чтения](#общий-процесс-записи-и-чтения)
|
||||||
- [Особенности обработки запросов](#особенности-обработки-запросов)
|
- [Особенности обработки запросов](#особенности-обработки-запросов)
|
||||||
- [Схожесть с Ceph](#схожесть-с-ceph)
|
- [Схожесть с Ceph](#схожесть-с-ceph)
|
||||||
|
@ -35,9 +34,8 @@
|
||||||
- **Пул (Pool)** — контейнер для данных, имеющих одну и ту же схему избыточности и правила распределения по OSD.
|
- **Пул (Pool)** — контейнер для данных, имеющих одну и ту же схему избыточности и правила распределения по OSD.
|
||||||
- **PG (Placement Group)** — "шард", единица деления пулов в кластере, которой назначается свой набор
|
- **PG (Placement Group)** — "шард", единица деления пулов в кластере, которой назначается свой набор
|
||||||
OSD для хранения данных (копий или частей объектов).
|
OSD для хранения данных (копий или частей объектов).
|
||||||
- **Домен отказа (Failure Domain)** — группа OSD, от одновременного падения которых должен защищать
|
- **Домен отказа (Failure Domain)** — группа OSD, одновременное падение которых рассматривается
|
||||||
Vitastor. По умолчанию домен отказа — "host" (сервер), но вы можете установить для пула как больший
|
как вероятное. По умолчанию это "host" (сервер).
|
||||||
домен отказа (например, стойку серверов), так и меньший (например, отдельный диск).
|
|
||||||
- **Дерево распределения** (Placement Tree, в Ceph CRUSH Tree) — иерархическая группировка OSD
|
- **Дерево распределения** (Placement Tree, в Ceph CRUSH Tree) — иерархическая группировка OSD
|
||||||
в узлы, которые далее можно использовать как домены отказа.
|
в узлы, которые далее можно использовать как домены отказа.
|
||||||
|
|
||||||
|
@ -51,39 +49,25 @@
|
||||||
|
|
||||||
На базе клиентской библиотеки реализованы все остальные клиенты:
|
На базе клиентской библиотеки реализованы все остальные клиенты:
|
||||||
|
|
||||||
- **[vitastor-cli](../usage/cli.ru.md)** — утилита командной строки для управления кластером.
|
- **vitastor-cli** — утилита командной строки для управления кластером. В данный момент позволяет
|
||||||
Позволяет просматривать общее состояние кластера, управлять пулами и образами — то есть
|
просматривать общее состояние кластера и управлять образами — т.е. создавать, менять и удалять
|
||||||
создавать, менять и удалять виртуальные диски, их снимки и клоны.
|
виртуальные диски, их снимки и клоны.
|
||||||
- **[Драйвер QEMU](../usage/qemu.ru.md)** — подключаемый модуль QEMU, позволяющий QEMU/KVM
|
- **Драйвер QEMU** — подключаемый модуль QEMU, позволяющий QEMU/KVM виртуальным машинам работать
|
||||||
виртуальным машинам работать с виртуальными дисками Vitastor напрямую из пространства пользователя
|
с виртуальными дисками Vitastor напрямую из пространства пользователя с помощью клиентской
|
||||||
с помощью клиентской библиотеки, без необходимости подключения дисков в виде блочных устройств
|
библиотеки, без необходимости отображения дисков в виде блочных устройств. Тот же драйвер
|
||||||
Linux. Если, однако, вы хотите подключать диски в виде блочных устройств, то вы тоже можете
|
позволяет подключать диски в систему через [VDUSE](../usage/qemu.ru.md#vduse).
|
||||||
сделать это с помощью того же самого драйвера и [VDUSE](../usage/qemu.ru.md#vduse).
|
- **vitastor-nbd** — утилита, позволяющая монтировать образы Vitastor в виде блочных устройств
|
||||||
- **[vitastor-nbd](../usage/nbd.ru.md)** — утилита, позволяющая монтировать образы Vitastor
|
с помощью NBD (Network Block Device), на самом деле скорее работающего как "BUSE"
|
||||||
в виде блочных устройств с помощью NBD (Network Block Device), на самом деле скорее работающего
|
(Block Device In Userspace). Модуля ядра Linux для выполнения той же задачи в Vitastor нет
|
||||||
как "BUSE" (Block Device In Userspace). Модуля ядра Linux для выполнения той же задачи в
|
(по крайней мере, пока).
|
||||||
Vitastor нет (по крайней мере, пока). NBD — более старый и нерекомендуемый способ подключения
|
- **CSI драйвер** — драйвер для подключения Vitastor-образов в виде персистентных томов (PV) Kubernetes.
|
||||||
дисков — вам следует использовать VDUSE всегда, когда это возможно.
|
Работает через vitastor-nbd — образы отражаются в виде блочных устройств и монтируются
|
||||||
- **[CSI драйвер](../installation/kubernetes.ru.md)** — драйвер для подключения Vitastor-образов
|
в контейнеры.
|
||||||
в виде персистентных томов (PV) Kubernetes. Работает через VDUSE (если доступно) или через
|
|
||||||
NBD — образы отражаются в виде блочных устройств и монтируются в контейнеры.
|
|
||||||
- **Драйвера Proxmox, OpenStack и т.п.** — подключаемые модули для соответствующих систем,
|
- **Драйвера Proxmox, OpenStack и т.п.** — подключаемые модули для соответствующих систем,
|
||||||
позволяющие использовать Vitastor как хранилище в оных.
|
позволяющие использовать Vitastor как хранилище в оных.
|
||||||
- **[vitastor-nfs](../usage/nfs.ru.md)** — NFS 3.0 сервер, предоставляющий два варианта файловой системы:
|
- **vitastor-nfs** — утилита, предоставляющая файловый доступ к образам в кластере Vitastor
|
||||||
первая — упрощённая для файлового доступа к блочным образам (для не-QEMU гипервизоров, поддерживающих NFS),
|
по протоколу NFS 3.0. Предназначена для гипервизоров, не основанных на QEMU и Linux, но при
|
||||||
вторая — VitastorFS, полноценная кластерная POSIX ФС. Оба варианта поддерживают параллельный
|
этом поддерживающих NFS.
|
||||||
доступ с нескольких vitastor-nfs серверов. На самом деле можно вообще не выделять
|
|
||||||
отдельные NFS-серверы, а вместо этого использовать команду vitastor-nfs mount, запускающую
|
|
||||||
NFS-сервер прямо на клиентской машине и монтирующую ФС локально.
|
|
||||||
- **[Драйвер fio](../usage/fio.ru.md)** — подключаемый модуль для утилиты тестирования
|
|
||||||
производительности дисков fio, позволяющий тестировать Vitastor-кластеры.
|
|
||||||
- **vitastor-kv** — клиент для key-value базы данных, работающей поверх разделяемого блочного
|
|
||||||
образа (обычного блочного образа vitastor). Метаданные VitastorFS хранятся именно в vitastor-kv.
|
|
||||||
|
|
||||||
## Дополнительные утилиты
|
|
||||||
|
|
||||||
- **vitastor-disk** — утилита для разметки дисков под Vitastor OSD. С её помощью можно
|
|
||||||
создавать, удалять, менять размеры или перемещать разделы OSD.
|
|
||||||
|
|
||||||
## Общий процесс записи и чтения
|
## Общий процесс записи и чтения
|
||||||
|
|
||||||
|
@ -114,22 +98,16 @@
|
||||||
находиться на других OSD, если эти объекты деградированы или перемещены, или идёт процесс
|
находиться на других OSD, если эти объекты деградированы или перемещены, или идёт процесс
|
||||||
ребаланса. Запросы для проверки по сети не отправляются, информация о местоположении всех
|
ребаланса. Запросы для проверки по сети не отправляются, информация о местоположении всех
|
||||||
объектов рассчитывается первичным OSD при активации PG и хранится в памяти.
|
объектов рассчитывается первичным OSD при активации PG и хранится в памяти.
|
||||||
- Когда это возможно, первичный OSD обрабатывает запрос локально. Например, так происходит
|
- Первичный OSD соединяется (если ещё не соединён) с вторичными OSD, на которых располагаются
|
||||||
при чтениях объектов из пулов с репликацией или при чтении из EC пула, затрагивающего
|
части объекта, и отправляет им запросы чтения/записи, а также читает/пишет из/в своё локальное
|
||||||
только часть, хранимую на диске самого первичного OSD.
|
хранилище, если сам входит в набор.
|
||||||
- Когда запрос требует записи или чтения с вторичных OSD, первичный OSD использует заранее
|
|
||||||
установленные соединения с ними для выполнения этих запросов. Это происходит параллельно
|
|
||||||
локальным операциям чтения/записи с диска самого OSD. Так как соединения к вторичным OSD PG
|
|
||||||
устанавливаются при её запуске, то они уже гарантированно установлены, когда PG активна,
|
|
||||||
и если любое из этих соединений отключается, PG перезапускается, а все текущие запросы чтения
|
|
||||||
и записи в неё завершаются с ошибкой EPIPE, после чего повторяются клиентами.
|
|
||||||
- После завершения всех вторичных операций чтения/записи первичный OSD отправляет ответ клиенту.
|
- После завершения всех вторичных операций чтения/записи первичный OSD отправляет ответ клиенту.
|
||||||
|
|
||||||
### Особенности обработки запросов
|
### Особенности обработки запросов
|
||||||
|
|
||||||
- Если в пуле используются коды коррекции ошибок и при этом часть OSD недоступна, первичный
|
- Если в пуле используются коды коррекции ошибок и при этом часть OSD недоступна, первичный
|
||||||
OSD при чтении восстанавливает данные из оставшихся частей.
|
OSD при чтении восстанавливает данные из оставшихся частей.
|
||||||
- Каждый объект имеет номер версии. При записи объекта первичный OSD сначала получает номер
|
- Каждый объект имеет номер версии. При записи объекта первичный OSD сначала читает из номер
|
||||||
версии объекта. Так как первичный OSD обычно сам хранит копию или часть объекта, номер
|
версии объекта. Так как первичный OSD обычно сам хранит копию или часть объекта, номер
|
||||||
версии обычно читается из памяти самого OSD. Однако, если ни одна часть обновляемого объекта
|
версии обычно читается из памяти самого OSD. Однако, если ни одна часть обновляемого объекта
|
||||||
не находится на первичном OSD, для получения номера версии он обращается к одному из вторичных
|
не находится на первичном OSD, для получения номера версии он обращается к одному из вторичных
|
||||||
|
@ -137,20 +115,20 @@
|
||||||
так как метаданные объектов, включая номер версии, все OSD хранят в памяти.
|
так как метаданные объектов, включая номер версии, все OSD хранят в памяти.
|
||||||
- Если в пуле используются коды коррекции ошибок, перед частичной записью объекта для вычисления
|
- Если в пуле используются коды коррекции ошибок, перед частичной записью объекта для вычисления
|
||||||
чётности зачастую требуется чтение частей объекта с вторичных OSD или с локального диска
|
чётности зачастую требуется чтение частей объекта с вторичных OSD или с локального диска
|
||||||
самого первичного OSD. Это называется процессом "чтение-модификация-запись" (read-modify-write).
|
самого первичного OSD.
|
||||||
- Если в пуле используются коды коррекции ошибок, для закрытия Write Hole применяется
|
- Также, если в пуле используются коды коррекции ошибок, для закрытия Write Hole применяется
|
||||||
двухфазный алгоритм записи: сначала на все вторичные OSD записывается новая версия частей
|
двухфазный алгоритм записи: сначала на все вторичные OSD записывается новая версия частей
|
||||||
объекта, но при этом старая версия не удаляется, а потом, после получения подтверждения
|
объекта, но при этом старая версия не удаляется, а потом, после получения подтверждения
|
||||||
успешной записи от всех вторичных OSD, новая версия фиксируется и разрешается удаление старой.
|
успешной записи от всех вторичных OSD, новая версия фиксируется и разрешается удаление старой.
|
||||||
- Если в пуле не включён режим immediate_commit, то запросы записи, отправляемые клиентами,
|
- Если в кластере не включён режим immediate_commit, то запросы записи, отправляемые клиентами,
|
||||||
не считаются зафиксированными на физических накопителях сразу. Для фиксации данных клиенты
|
не считаются зафиксированными на физических накопителях сразу. Для фиксации данных клиенты
|
||||||
должны отдельно отправлять запросы SYNC (отдельный от чтения и записи вид запроса),
|
должны отдельно отправлять запросы SYNC (отдельный от чтения и записи вид запроса),
|
||||||
а пока такой запрос не отправлен, считается, что записанные данные могут исчезнуть,
|
а пока такой запрос не отправлен, считается, что записанные данные могут исчезнуть,
|
||||||
если соответствующий OSD упадёт. Поэтому, когда режим immediate_commit отключён, все
|
если соответствующий OSD упадёт. Поэтому, когда режим immediate_commit отключён, все
|
||||||
запросы записи клиенты копируют в памяти и при потере соединения и повторном соединении
|
запросы записи клиенты копируют в памяти и при потере соединения и повторном соединении
|
||||||
с OSD повторяют из памяти. Скопированные в память данные удаляются при успешном SYNC,
|
с OSD повторяют из памяти. Скопированные в память данные удаляются при успешном fsync,
|
||||||
а чтобы хранение этих данных не приводило к чрезмерному потреблению памяти, клиенты
|
а чтобы хранение этих данных не приводило к чрезмерному потреблению памяти, клиенты
|
||||||
автоматически выполняют SYNC каждые [client_dirty_limit](../config/network.ru.md#client_dirty_limit)
|
автоматически выполняют fsync каждые [client_dirty_limit](../config/network.ru.md#client_dirty_limit)
|
||||||
записанных байт.
|
записанных байт.
|
||||||
|
|
||||||
## Схожесть с Ceph
|
## Схожесть с Ceph
|
||||||
|
|
|
@ -32,7 +32,7 @@
|
||||||
|
|
||||||
- SATA SSD: Micron 5100/5200/5300/5400, Samsung PM863/PM883/PM893, Intel D3-S4510/4520/4610/4620, Kingston DC500M
|
- SATA SSD: Micron 5100/5200/5300/5400, Samsung PM863/PM883/PM893, Intel D3-S4510/4520/4610/4620, Kingston DC500M
|
||||||
- NVMe: Micron 9100/9200/9300/9400, Micron 7300/7450, Samsung PM983/PM9A3, Samsung PM1723/1735/1743,
|
- NVMe: Micron 9100/9200/9300/9400, Micron 7300/7450, Samsung PM983/PM9A3, Samsung PM1723/1735/1743,
|
||||||
Intel DC-P3700/P4500/P4600, Intel D5-P4320, Intel D7-P5500/P5600, Intel Optane, Kingston DC1000B/DC1500M
|
Intel DC-P3700/P4500/P4600, Intel D7-P5500/P5600, Intel Optane, Kingston DC1000B/DC1500M
|
||||||
- HDD: HGST Ultrastar, Toshiba MG, Seagate EXOS
|
- HDD: HGST Ultrastar, Toshiba MG, Seagate EXOS
|
||||||
|
|
||||||
## Configure monitors
|
## Configure monitors
|
||||||
|
|
|
@ -22,7 +22,7 @@
|
||||||
использовать и десктопные SSD, включив режим отложенного fsync, но производительность будет хуже.
|
использовать и десктопные SSD, включив режим отложенного fsync, но производительность будет хуже.
|
||||||
О конденсаторах читайте [здесь](../config/layout-cluster.ru.md#immediate_commit).
|
О конденсаторах читайте [здесь](../config/layout-cluster.ru.md#immediate_commit).
|
||||||
- Если хотите использовать HDD, берите современные модели с Media или SSD кэшем - HGST Ultrastar,
|
- Если хотите использовать HDD, берите современные модели с Media или SSD кэшем - HGST Ultrastar,
|
||||||
Toshiba MG, Seagate EXOS или что-то похожее. Если такого кэша у ваших дисков нет,
|
Toshiba MG08, Seagate EXOS или что-то похожее. Если такого кэша у ваших дисков нет,
|
||||||
обязательно возьмите SSD под метаданные и журнал (маленькие, буквально 2 ГБ на 1 ТБ HDD-места).
|
обязательно возьмите SSD под метаданные и журнал (маленькие, буквально 2 ГБ на 1 ТБ HDD-места).
|
||||||
- Возьмите быструю сеть, минимум 10 гбит/с. Идеал - что-то вроде Mellanox ConnectX-4 с RoCEv2.
|
- Возьмите быструю сеть, минимум 10 гбит/с. Идеал - что-то вроде Mellanox ConnectX-4 с RoCEv2.
|
||||||
- Для лучшей производительности отключите энергосбережение CPU: `cpupower idle-set -D 0 && cpupower frequency-set -g performance`.
|
- Для лучшей производительности отключите энергосбережение CPU: `cpupower idle-set -D 0 && cpupower frequency-set -g performance`.
|
||||||
|
@ -32,8 +32,8 @@
|
||||||
|
|
||||||
- SATA SSD: Micron 5100/5200/5300/5400, Samsung PM863/PM883/PM893, Intel D3-S4510/4520/4610/4620, Kingston DC500M
|
- SATA SSD: Micron 5100/5200/5300/5400, Samsung PM863/PM883/PM893, Intel D3-S4510/4520/4610/4620, Kingston DC500M
|
||||||
- NVMe: Micron 9100/9200/9300/9400, Micron 7300/7450, Samsung PM983/PM9A3, Samsung PM1723/1735/1743,
|
- NVMe: Micron 9100/9200/9300/9400, Micron 7300/7450, Samsung PM983/PM9A3, Samsung PM1723/1735/1743,
|
||||||
Intel DC-P3700/P4500/P4600, Intel D5-P4320, Intel D7-P5500/P5600, Intel Optane, Kingston DC1000B/DC1500M
|
Intel DC-P3700/P4500/P4600, Intel D7-P5500/P5600, Intel Optane, Kingston DC1000B/DC1500M
|
||||||
- HDD: HGST Ultrastar, Toshiba MG, Seagate EXOS
|
- HDD: HGST Ultrastar, Toshiba MG06/MG07/MG08, Seagate EXOS
|
||||||
|
|
||||||
## Настройте мониторы
|
## Настройте мониторы
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,6 @@
|
||||||
|
---
|
||||||
|
title: Common Parameters
|
||||||
|
weight: 1
|
||||||
|
---
|
||||||
|
|
||||||
|
These are the most common parameters which apply to all components of Vitastor.
|
|
@ -0,0 +1,6 @@
|
||||||
|
---
|
||||||
|
title: Общие параметры
|
||||||
|
weight: 1
|
||||||
|
---
|
||||||
|
|
||||||
|
Это наиболее общие параметры, используемые всеми компонентами Vitastor.
|
|
@ -0,0 +1,7 @@
|
||||||
|
---
|
||||||
|
title: Cluster-Wide Disk Layout Parameters
|
||||||
|
weight: 2
|
||||||
|
---
|
||||||
|
|
||||||
|
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.
|
|
@ -0,0 +1,7 @@
|
||||||
|
---
|
||||||
|
title: Дисковые параметры уровня кластера
|
||||||
|
weight: 2
|
||||||
|
---
|
||||||
|
|
||||||
|
Данные параметры используются клиентами и OSD, задаются в момент инициализации
|
||||||
|
диска OSD и не могут быть изменены после этого без потери данных.
|
|
@ -0,0 +1,7 @@
|
||||||
|
---
|
||||||
|
title: OSD Disk Layout Parameters
|
||||||
|
weight: 3
|
||||||
|
---
|
||||||
|
|
||||||
|
These parameters apply to OSDs, are fixed at the moment of OSD drive
|
||||||
|
initialization and can't be changed after it without losing data.
|
|
@ -0,0 +1,8 @@
|
||||||
|
---
|
||||||
|
title: Дисковые параметры OSD
|
||||||
|
weight: 3
|
||||||
|
---
|
||||||
|
|
||||||
|
Данные параметры используются только OSD и, также как и общекластерные
|
||||||
|
дисковые параметры, задаются в момент инициализации дисков OSD и не могут быть
|
||||||
|
изменены после этого без потери данных.
|
|
@ -0,0 +1,6 @@
|
||||||
|
---
|
||||||
|
title: Monitor Parameters
|
||||||
|
weight: 6
|
||||||
|
---
|
||||||
|
|
||||||
|
These parameters only apply to Monitors.
|
|
@ -0,0 +1,6 @@
|
||||||
|
---
|
||||||
|
title: Параметры мониторов
|
||||||
|
weight: 6
|
||||||
|
---
|
||||||
|
|
||||||
|
Данные параметры используются только мониторами Vitastor.
|
|
@ -0,0 +1,7 @@
|
||||||
|
---
|
||||||
|
title: Network Protocol Parameters
|
||||||
|
weight: 4
|
||||||
|
---
|
||||||
|
|
||||||
|
These parameters apply to clients and OSDs and affect network connection logic
|
||||||
|
between clients, OSDs and etcd.
|
|
@ -0,0 +1,7 @@
|
||||||
|
---
|
||||||
|
title: Параметры сетевого протокола
|
||||||
|
weight: 4
|
||||||
|
---
|
||||||
|
|
||||||
|
Данные параметры используются клиентами и OSD и влияют на логику сетевого
|
||||||
|
взаимодействия между клиентами, OSD, а также etcd.
|
|
@ -0,0 +1,7 @@
|
||||||
|
---
|
||||||
|
title: Runtime OSD Parameters
|
||||||
|
weight: 5
|
||||||
|
---
|
||||||
|
|
||||||
|
These parameters only apply to OSDs, are not fixed at the moment of OSD drive
|
||||||
|
initialization and can be changed with an OSD restart.
|
|
@ -0,0 +1,8 @@
|
||||||
|
---
|
||||||
|
title: Изменяемые параметры OSD
|
||||||
|
weight: 5
|
||||||
|
---
|
||||||
|
|
||||||
|
Данные параметры используются только OSD, но, в отличие от дисковых параметров,
|
||||||
|
не фиксируются в момент инициализации дисков OSD и могут быть изменены в любой
|
||||||
|
момент с перезапуском OSD.
|
|
@ -169,25 +169,6 @@ Upgrading is performed without stopping clients (VMs/containers), you just need
|
||||||
upgrade and restart servers one by one. However, ideally you should restart VMs too
|
upgrade and restart servers one by one. However, ideally you should restart VMs too
|
||||||
to make them use the new version of the client library.
|
to make them use the new version of the client library.
|
||||||
|
|
||||||
### 1.7.x to 1.8.0
|
|
||||||
|
|
||||||
It's recommended to upgrade from version <= 1.7.x to version >= 1.8.0 with full downtime,
|
|
||||||
i.e. you should first stop clients and then the cluster (OSDs and monitor), because 1.8.0
|
|
||||||
includes a fix for etcd event stream inconsistency which could lead to "incomplete" objects
|
|
||||||
appearing in EC pools, and in rare cases, probably, even to data corruption during mass OSD
|
|
||||||
restarts. It doesn't mean that you WILL hit this problem if you upgrade without full downtime,
|
|
||||||
but it's better to secure yourself against it.
|
|
||||||
|
|
||||||
Also, if you upgrade version from <= 1.7.x to version >= 1.8.0, BUT <= 1.9.0: restart all clients
|
|
||||||
(VMs and so on), otherwise they will hang when monitor clears old PG configuration key,
|
|
||||||
which happens 24 hours after upgrade.
|
|
||||||
|
|
||||||
This is fixed in 1.9.1. So, after upgrading version <= 1.7.x directly to version >= 1.9.1,
|
|
||||||
you DO NOT have to restart all old clients immediately - they will work like before until
|
|
||||||
you decide to upgrade them too. The downside is that you'll have to remove the old PG
|
|
||||||
configuration key (`/vitastor/config/pgs`) from etcd by hand when you make sure that all
|
|
||||||
your clients are restarted.
|
|
||||||
|
|
||||||
### 1.1.x to 1.2.0
|
### 1.1.x to 1.2.0
|
||||||
|
|
||||||
Upgrading version <= 1.1.x to version >= 1.2.0, if you use EC n+k with k>=2, is recommended
|
Upgrading version <= 1.1.x to version >= 1.2.0, if you use EC n+k with k>=2, is recommended
|
||||||
|
|
|
@ -166,25 +166,6 @@ done
|
||||||
достаточно обновлять серверы по одному. Однако, конечно, чтобы запущенные виртуальные машины
|
достаточно обновлять серверы по одному. Однако, конечно, чтобы запущенные виртуальные машины
|
||||||
начали использовать новую версию клиентской библиотеки, их тоже нужно перезапустить.
|
начали использовать новую версию клиентской библиотеки, их тоже нужно перезапустить.
|
||||||
|
|
||||||
### 1.7.x -> 1.8.0
|
|
||||||
|
|
||||||
Обновляться с версий <= 1.7.x до версий >= 1.8.0 рекомендуется с полной остановкой
|
|
||||||
сначала клиентов, а затем кластера, так как в 1.8.0 исправлена проблема (неконсистентность
|
|
||||||
потоков событий от etcd), способная приводить к появлению incomplete объектов в EC-пулах
|
|
||||||
и, хоть и редко, но даже к повреждению данных при массовых перезапусках OSD. Если вы
|
|
||||||
обновляетесь без полной остановки - это не значит, что вы обязательно столкнётесь с этой
|
|
||||||
проблемой, но лучше подстраховаться.
|
|
||||||
|
|
||||||
Также, если вы обновляетесь с версии <= 1.7.x до версии >= 1.8.0, НО <= 1.9.0: перезапустите всех
|
|
||||||
клиентов (процессы виртуальных машин можно перезапустить путём миграции на другой сервер),
|
|
||||||
иначе они зависнут, когда монитор удалит старый ключ конфигурации PG, что происходит через
|
|
||||||
24 часа после обновления.
|
|
||||||
|
|
||||||
Однако, это исправлено в 1.9.1. Так что, если вы обновляетесь с <= 1.7.x сразу до >= 1.9.1,
|
|
||||||
вам НЕ нужно сразу перезапускать всех клиентов - они будут работать, как раньше. Минус,
|
|
||||||
правда, в том, что старый ключ конфигурации PG (`/vitastor/config/pgs`) будет нужно удалить
|
|
||||||
вам из etcd вручную - после того, как вы убедитесь, что все клиенты перезапущены.
|
|
||||||
|
|
||||||
### 1.1.x -> 1.2.0
|
### 1.1.x -> 1.2.0
|
||||||
|
|
||||||
Обновляться с версий <= 1.1.x до версий >= 1.2.0, если вы используете EC n+k и k>=2,
|
Обновляться с версий <= 1.1.x до версий >= 1.2.0, если вы используете EC n+k и k>=2,
|
||||||
|
|
|
@ -13,7 +13,6 @@ It supports the following commands:
|
||||||
- [prepare](#prepare)
|
- [prepare](#prepare)
|
||||||
- [upgrade-simple](#upgrade-simple)
|
- [upgrade-simple](#upgrade-simple)
|
||||||
- [resize](#resize)
|
- [resize](#resize)
|
||||||
- [raw-resize](#raw-resize)
|
|
||||||
- [start/stop/restart/enable/disable](#start/stop/restart/enable/disable)
|
- [start/stop/restart/enable/disable](#start/stop/restart/enable/disable)
|
||||||
- [purge](#purge)
|
- [purge](#purge)
|
||||||
- [read-sb](#read-sb)
|
- [read-sb](#read-sb)
|
||||||
|
@ -51,16 +50,12 @@ Options (automatic mode):
|
||||||
--osd_per_disk <N>
|
--osd_per_disk <N>
|
||||||
Create <N> OSDs on each disk (default 1)
|
Create <N> OSDs on each disk (default 1)
|
||||||
--hybrid
|
--hybrid
|
||||||
Prepare hybrid (HDD+SSD, NVMe+SATA or etc) OSDs using provided devices. By default,
|
Prepare hybrid (HDD+SSD) OSDs using provided devices. SSDs will be used for
|
||||||
any passed SSDs will be used for journals and metadata, HDDs will be used for data,
|
journals and metadata, HDDs will be used for data. Partitions for journals and
|
||||||
but you can override this behaviour with --fast-devices option. Journal and metadata
|
metadata will be created automatically. Whether disks are SSD or HDD is decided
|
||||||
partitions will be created automatically. In the default mode, SSD and HDD disks
|
by the `/sys/block/.../queue/rotational` flag. In hybrid mode, default object
|
||||||
are distinguished by the `/sys/block/.../queue/rotational` flag. When HDDs are used
|
size is 1 MB instead of 128 KB, default journal size is 1 GB instead of 32 MB,
|
||||||
for data in hybrid mode, default block_size is 1 MB instead of 128 KB, default journal
|
and throttle_small_writes is enabled by default.
|
||||||
size is 1 GB instead of 32 MB, and throttle_small_writes is enabled by default.
|
|
||||||
--fast-devices /dev/nvmeX,/dev/nvmeY
|
|
||||||
In --hybrid mode, use these devices for journal and metadata instead of auto-detecting
|
|
||||||
and extracting them from the main [devices...] list.
|
|
||||||
--disable_data_fsync auto
|
--disable_data_fsync auto
|
||||||
Disable data device cache and fsync (1/yes/true = on, default auto)
|
Disable data device cache and fsync (1/yes/true = on, default auto)
|
||||||
--disable_meta_fsync auto
|
--disable_meta_fsync auto
|
||||||
|
@ -132,49 +127,25 @@ Requires the `sfdisk` utility.
|
||||||
|
|
||||||
## resize
|
## resize
|
||||||
|
|
||||||
`vitastor-disk resize <osd_num>|<osd_device> [OPTIONS]`
|
`vitastor-disk resize <ALL_OSD_PARAMETERS> <NEW_LAYOUT> [--iodepth 32]`
|
||||||
|
|
||||||
Resize data area and/or move journal and metadata:
|
Resize data area and/or rewrite/move journal and metadata.
|
||||||
|
|
||||||
| <!-- --> | <!-- --> |
|
|
||||||
|---------------------------|----------------------------------------|
|
|
||||||
| `--move-journal TARGET` | move journal to `TARGET` |
|
|
||||||
| `--move-meta TARGET` | move metadata to `TARGET` |
|
|
||||||
| `--journal-size NEW_SIZE` | resize journal to `NEW_SIZE` |
|
|
||||||
| `--data-size NEW_SIZE` | resize data device to `NEW_SIZE` |
|
|
||||||
| `--dry-run` | only show new layout, do not apply it |
|
|
||||||
|
|
||||||
`NEW_SIZE` may include k/m/g/t suffixes.
|
|
||||||
|
|
||||||
`TARGET` may be one of:
|
|
||||||
|
|
||||||
| <!-- --> | <!-- --> |
|
|
||||||
|----------------|--------------------------------------------------------------------------|
|
|
||||||
| `<partition>` | move journal/metadata to an existing GPT partition |
|
|
||||||
| `<raw_device>` | create a GPT partition on `<raw_device>` and move journal/metadata to it |
|
|
||||||
| `""` | (empty string) move journal/metadata back to the data device |
|
|
||||||
|
|
||||||
## raw-resize
|
|
||||||
|
|
||||||
`vitastor-disk raw-resize <ALL_OSD_PARAMETERS> <NEW_LAYOUT> [--iodepth 32]`
|
|
||||||
|
|
||||||
Resize data area and/or rewrite/move journal and metadata (manual format).
|
|
||||||
|
|
||||||
`ALL_OSD_PARAMETERS` must include all (at least all disk-related)
|
`ALL_OSD_PARAMETERS` must include all (at least all disk-related)
|
||||||
parameters from OSD command line (i.e. from systemd unit or superblock).
|
parameters from OSD command line (i.e. from systemd unit or superblock).
|
||||||
|
|
||||||
`NEW_LAYOUT` may include new disk layout parameters:
|
`NEW_LAYOUT` may include new disk layout parameters:
|
||||||
|
|
||||||
| <!-- --> | <!-- --> |
|
```
|
||||||
|-----------------------------|-------------------------------------------|
|
--new_data_offset SIZE resize data area so it starts at SIZE
|
||||||
| `--new_data_offset SIZE` | resize data area so it starts at `SIZE` |
|
--new_data_len SIZE resize data area to SIZE bytes
|
||||||
| `--new_data_len SIZE` | resize data area to `SIZE` bytes |
|
--new_meta_device PATH use PATH for new metadata
|
||||||
| `--new_meta_device PATH` | use `PATH` for new metadata |
|
--new_meta_offset SIZE make new metadata area start at SIZE
|
||||||
| `--new_meta_offset SIZE` | make new metadata area start at `SIZE` |
|
--new_meta_len SIZE make new metadata area SIZE bytes long
|
||||||
| `--new_meta_len SIZE` | make new metadata area `SIZE` bytes long |
|
--new_journal_device PATH use PATH for new journal
|
||||||
| `--new_journal_device PATH` | use `PATH` for new journal |
|
--new_journal_offset SIZE make new journal area start at SIZE
|
||||||
| `--new_journal_offset SIZE` | make new journal area start at `SIZE` |
|
--new_journal_len SIZE make new journal area SIZE bytes long
|
||||||
| `--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
|
SIZE may include k/m/g/t suffixes. If any of the new layout parameter
|
||||||
options are not specified, old values will be used.
|
options are not specified, old values will be used.
|
||||||
|
@ -246,14 +217,10 @@ Intended for use from startup scripts (i.e. from systemd units).
|
||||||
|
|
||||||
## dump-journal
|
## dump-journal
|
||||||
|
|
||||||
`vitastor-disk dump-journal [OPTIONS] <osd_device>`
|
|
||||||
|
|
||||||
`vitastor-disk dump-journal [OPTIONS] <journal_file> <journal_block_size> <offset> <size>`
|
`vitastor-disk dump-journal [OPTIONS] <journal_file> <journal_block_size> <offset> <size>`
|
||||||
|
|
||||||
Dump journal in human-readable or JSON (if `--json` is specified) format.
|
Dump journal in human-readable or JSON (if `--json` is specified) format.
|
||||||
|
|
||||||
You can specify any OSD device (data, metadata or journal), or the layout manually.
|
|
||||||
|
|
||||||
Options:
|
Options:
|
||||||
|
|
||||||
```
|
```
|
||||||
|
@ -266,35 +233,23 @@ Options:
|
||||||
|
|
||||||
## write-journal
|
## write-journal
|
||||||
|
|
||||||
`vitastor-disk write-journal <osd_device>`
|
|
||||||
|
|
||||||
`vitastor-disk write-journal <journal_file> <journal_block_size> <bitmap_size> <offset> <size>`
|
`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
|
Write journal from JSON taken from standard input in the same format as produced by
|
||||||
`dump-journal --json --format data`.
|
`dump-journal --json --format data`.
|
||||||
|
|
||||||
You can specify any OSD device (data, metadata or journal), or the layout manually.
|
|
||||||
|
|
||||||
## dump-meta
|
## dump-meta
|
||||||
|
|
||||||
`vitastor-disk dump-meta <osd_device>`
|
|
||||||
|
|
||||||
`vitastor-disk dump-meta <meta_file> <meta_block_size> <offset> <size>`
|
`vitastor-disk dump-meta <meta_file> <meta_block_size> <offset> <size>`
|
||||||
|
|
||||||
Dump metadata in JSON format.
|
Dump metadata in JSON format.
|
||||||
|
|
||||||
You can specify any OSD device (data, metadata or journal), or the layout manually.
|
|
||||||
|
|
||||||
## write-meta
|
## write-meta
|
||||||
|
|
||||||
`vitastor-disk write-meta <osd_device>`
|
|
||||||
|
|
||||||
`vitastor-disk write-meta <meta_file> <offset> <size>`
|
`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`.
|
Write metadata from JSON taken from standard input in the same format as produced by `dump-meta`.
|
||||||
|
|
||||||
You can specify any OSD device (data, metadata or journal), or the layout manually.
|
|
||||||
|
|
||||||
## simple-offsets
|
## simple-offsets
|
||||||
|
|
||||||
`vitastor-disk simple-offsets <device>`
|
`vitastor-disk simple-offsets <device>`
|
||||||
|
|
|
@ -13,7 +13,6 @@ vitastor-disk - инструмент командной строки для уп
|
||||||
- [prepare](#prepare)
|
- [prepare](#prepare)
|
||||||
- [upgrade-simple](#upgrade-simple)
|
- [upgrade-simple](#upgrade-simple)
|
||||||
- [resize](#resize)
|
- [resize](#resize)
|
||||||
- [raw-resize](#raw-resize)
|
|
||||||
- [start/stop/restart/enable/disable](#start/stop/restart/enable/disable)
|
- [start/stop/restart/enable/disable](#start/stop/restart/enable/disable)
|
||||||
- [purge](#purge)
|
- [purge](#purge)
|
||||||
- [read-sb](#read-sb)
|
- [read-sb](#read-sb)
|
||||||
|
@ -51,17 +50,12 @@ vitastor-disk - инструмент командной строки для уп
|
||||||
--osd_per_disk <N>
|
--osd_per_disk <N>
|
||||||
Создавать по несколько (<N>) OSD на каждом диске (по умолчанию 1)
|
Создавать по несколько (<N>) OSD на каждом диске (по умолчанию 1)
|
||||||
--hybrid
|
--hybrid
|
||||||
Инициализировать гибридные (HDD+SSD, NVMe+SATA и т.п.) OSD на указанных дисках.
|
Инициализировать гибридные (HDD+SSD) OSD на указанных дисках. SSD будут
|
||||||
По умолчанию, SSD будут использованы для журналов и метаданных, а HDD - для данных,
|
использованы для журналов и метаданных, а HDD - для данных. Разделы для журналов
|
||||||
но вы можете поменять это поведение опцией --fast-devices. Разделы для журналов
|
и метаданных будут созданы автоматически. Является ли диск SSD или HDD, определяется
|
||||||
и метаданных будут созданы автоматически. В режиме по умолчанию SSD и HDD-диски
|
по флагу `/sys/block/.../queue/rotational`. В гибридном режиме по умолчанию
|
||||||
различаются по флагу `/sys/block/.../queue/rotational`. Когда в гибридном режиме
|
используется размер объекта 1 МБ вместо 128 КБ, размер журнала 1 ГБ вместо 32 МБ
|
||||||
для данных используются HDD, по умолчанию размер блока устанавливается 1 МБ вместо
|
и включённый throttle_small_writes.
|
||||||
128 КБ, размер журнала 1 ГБ вместо 32 МБ, и throttle_small_writes включается по
|
|
||||||
умолчанию.
|
|
||||||
--fast-devices /dev/nvmeX,/dev/nvmeY
|
|
||||||
Использовать данные диски для журналов и метаданных в гибридном режиме вместо их
|
|
||||||
автоопределения и извлечения из основного списка [devices...].
|
|
||||||
--disable_data_fsync auto
|
--disable_data_fsync auto
|
||||||
Отключать кэш и fsync-и для устройств данных. (1/yes/true = да, по умолчанию автоопределение)
|
Отключать кэш и fsync-и для устройств данных. (1/yes/true = да, по умолчанию автоопределение)
|
||||||
--disable_meta_fsync auto
|
--disable_meta_fsync auto
|
||||||
|
@ -135,51 +129,27 @@ throttle_target_mbs, throttle_target_parallelism, throttle_threshold_us.
|
||||||
|
|
||||||
## resize
|
## resize
|
||||||
|
|
||||||
`vitastor-disk resize <osd_num>|<osd_device> [OPTIONS]`
|
`vitastor-disk resize <ALL_OSD_PARAMETERS> <NEW_LAYOUT> [--iodepth 32]`
|
||||||
|
|
||||||
Изменить размер области данных и/или переместить журнал и метаданные:
|
Изменить размер области данных и/или переместить журнал и метаданные.
|
||||||
|
|
||||||
| <!-- --> | <!-- --> |
|
В `ALL_OSD_PARAMETERS` нужно указать все относящиеся к диску параметры OSD
|
||||||
|-------------------------------|------------------------------------------------|
|
|
||||||
| `--move-journal ЦЕЛЬ` | переместить журнал на `ЦЕЛЬ` |
|
|
||||||
| `--move-meta ЦЕЛЬ` | переместить метаданные на `ЦЕЛЬ` |
|
|
||||||
| `--journal-size НОВЫЙ_РАЗМЕР` | изменить размер журнала на `НОВЫЙ_РАЗМЕР` |
|
|
||||||
| `--data-size НОВЫЙ_РАЗМЕР` | изменить размер диска данных на `НОВЫЙ_РАЗМЕР` |
|
|
||||||
| `--dry-run` | показать новые параметры, но не применять их |
|
|
||||||
|
|
||||||
`НОВЫЙ_РАЗМЕР` может быть указан с суффиксами k/m/g/t (кило/мега/гига/терабайт).
|
|
||||||
|
|
||||||
`ЦЕЛЬ` может быть одним из:
|
|
||||||
|
|
||||||
| <!-- --> | <!-- --> |
|
|
||||||
|-----------------|-------------------------------------------------------------------------------------|
|
|
||||||
| `<раздел>` | переместить журнал/метаданные на существующий GPT-раздел |
|
|
||||||
| `<полный_диск>` | создать GPT-раздел на диске `<полный_диск>` и переместить журнал/метаданные на него |
|
|
||||||
| `""` | (пустая строка) переместить журнал/метаданные обратно на диск данных |
|
|
||||||
|
|
||||||
## raw-resize
|
|
||||||
|
|
||||||
`vitastor-disk raw-resize <ВСЕ_ПАРАМЕТРЫ_OSD> <НОВЫЕ_РАЗМЕРЫ> [--iodepth 32]`
|
|
||||||
|
|
||||||
Изменить размер области данных и/или переместить журнал и метаданные (ручной формат).
|
|
||||||
|
|
||||||
В `ВСЕ_ПАРАМЕТРЫ_OSD` нужно указать все относящиеся к диску параметры OSD
|
|
||||||
из суперблока OSD или из файла сервиса systemd (в старых версиях).
|
из суперблока OSD или из файла сервиса systemd (в старых версиях).
|
||||||
|
|
||||||
В `НОВЫЕ_РАЗМЕРЫ` нужно указать новые параметры расположения данных:
|
В `NEW_LAYOUT` нужно указать новые параметры расположения данных:
|
||||||
|
|
||||||
| <!-- --> | <!-- --> |
|
```
|
||||||
|-------------------------------|-------------------------------------------------------|
|
--new_data_offset РАЗМЕР сдвинуть начало области данных на РАЗМЕР байт
|
||||||
| `--new_data_offset РАЗМЕР` | сдвинуть начало области данных на `РАЗМЕР` байт |
|
--new_data_len РАЗМЕР изменить размер области данных до РАЗМЕР байт
|
||||||
| `--new_data_len РАЗМЕР` | изменить размер области данных до `РАЗМЕР` байт |
|
--new_meta_device ПУТЬ использовать ПУТЬ как новое устройство метаданных
|
||||||
| `--new_meta_device ПУТЬ` | использовать `ПУТЬ` как новое устройство метаданных |
|
--new_meta_offset РАЗМЕР разместить новые метаданные по смещению РАЗМЕР байт
|
||||||
| `--new_meta_offset РАЗМЕР` | разместить новые метаданные по смещению `РАЗМЕР` байт |
|
--new_meta_len РАЗМЕР сделать новые метаданные размером РАЗМЕР байт
|
||||||
| `--new_meta_len РАЗМЕР` | сделать новые метаданные размером `РАЗМЕР` байт |
|
--new_journal_device ПУТЬ использовать ПУТЬ как новое устройство журнала
|
||||||
| `--new_journal_device ПУТЬ` | использовать `ПУТЬ` как новое устройство журнала |
|
--new_journal_offset РАЗМЕР разместить новый журнал по смещению РАЗМЕР байт
|
||||||
| `--new_journal_offset РАЗМЕР` | разместить новый журнал по смещению `РАЗМЕР` байт |
|
--new_journal_len РАЗМЕР сделать новый журнал размером РАЗМЕР байт
|
||||||
| `--new_journal_len РАЗМЕР` | сделать новый журнал размером `РАЗМЕР` байт |
|
```
|
||||||
|
|
||||||
`РАЗМЕР` может быть указан с суффиксами k/m/g/t. Если любой из новых параметров
|
РАЗМЕР может быть указан с суффиксами k/m/g/t. Если любой из новых параметров
|
||||||
расположения не указан, он принимается равным старому значению.
|
расположения не указан, он принимается равным старому значению.
|
||||||
|
|
||||||
## start/stop/restart/enable/disable
|
## start/stop/restart/enable/disable
|
||||||
|
@ -254,15 +224,10 @@ OSD отключены fsync-и.
|
||||||
|
|
||||||
## dump-journal
|
## dump-journal
|
||||||
|
|
||||||
`vitastor-disk dump-journal <osd_device>`
|
|
||||||
|
|
||||||
`vitastor-disk dump-journal [OPTIONS] <journal_file> <journal_block_size> <offset> <size>`
|
`vitastor-disk dump-journal [OPTIONS] <journal_file> <journal_block_size> <offset> <size>`
|
||||||
|
|
||||||
Вывести журнал в человекочитаемом или в JSON (с опцией `--json`) виде.
|
Вывести журнал в человекочитаемом или в JSON (с опцией `--json`) виде.
|
||||||
|
|
||||||
Вы можете указать любой раздел OSD - данных, журнала или метаданных - либо указать все
|
|
||||||
параметры расположения вручную.
|
|
||||||
|
|
||||||
Опции:
|
Опции:
|
||||||
|
|
||||||
```
|
```
|
||||||
|
@ -275,37 +240,22 @@ OSD отключены fsync-и.
|
||||||
|
|
||||||
## write-journal
|
## write-journal
|
||||||
|
|
||||||
`vitastor-disk write-journal <osd_device>`
|
|
||||||
|
|
||||||
`vitastor-disk write-journal <journal_file> <journal_block_size> <bitmap_size> <offset> <size>`
|
`vitastor-disk write-journal <journal_file> <journal_block_size> <bitmap_size> <offset> <size>`
|
||||||
|
|
||||||
Записать журнал из JSON со стандартного ввода в формате, аналогичном `dump-journal --json --format data`.
|
Записать журнал из JSON со стандартного ввода в формате, аналогичном `dump-journal --json --format data`.
|
||||||
|
|
||||||
Вы можете указать любой раздел OSD - данных, журнала или метаданных - либо указать все
|
|
||||||
параметры расположения вручную.
|
|
||||||
|
|
||||||
## dump-meta
|
## dump-meta
|
||||||
|
|
||||||
`vitastor-disk dump-meta <osd_device>`
|
|
||||||
|
|
||||||
`vitastor-disk dump-meta <meta_file> <meta_block_size> <offset> <size>`
|
`vitastor-disk dump-meta <meta_file> <meta_block_size> <offset> <size>`
|
||||||
|
|
||||||
Вывести метаданные в формате JSON.
|
Вывести метаданные в формате JSON.
|
||||||
|
|
||||||
Вы можете указать любой раздел OSD - данных, журнала или метаданных - либо указать все
|
|
||||||
параметры расположения вручную.
|
|
||||||
|
|
||||||
## write-meta
|
## write-meta
|
||||||
|
|
||||||
`vitastor-disk write-meta <osd_device>`
|
|
||||||
|
|
||||||
`vitastor-disk write-meta <meta_file> <offset> <size>`
|
`vitastor-disk write-meta <meta_file> <offset> <size>`
|
||||||
|
|
||||||
Записать метаданные из JSON со стандартного ввода в формате, аналогичном `dump-meta`.
|
Записать метаданные из JSON со стандартного ввода в формате, аналогичном `dump-meta`.
|
||||||
|
|
||||||
Вы можете указать любой раздел OSD - данных, журнала или метаданных - либо указать все
|
|
||||||
параметры расположения вручную.
|
|
||||||
|
|
||||||
## simple-offsets
|
## simple-offsets
|
||||||
|
|
||||||
`vitastor-disk simple-offsets <device>`
|
`vitastor-disk simple-offsets <device>`
|
||||||
|
|
|
@ -157,16 +157,16 @@ behind. Defragmentation removes garbage and moves data still in use to new volum
|
||||||
Options:
|
Options:
|
||||||
|
|
||||||
| <!-- --> | <!-- --> |
|
| <!-- --> | <!-- --> |
|
||||||
|----------------------------|------------------------------------------------------------------------ |
|
|--------------------------|------------------------------------------------------------------------ |
|
||||||
| `--volume_untouched 86400` | Defragment volumes last appended to at least this number of seconds ago |
|
| --volume_untouched 86400 | Defragment volumes last appended to at least this number of seconds ago |
|
||||||
| `--defrag_percent 50` | Defragment volumes with at least this % of removed data |
|
| --defrag_percent 50 | Defragment volumes with at least this % of removed data |
|
||||||
| `--defrag_block_count 16` | Read this number of pool blocks at once during defrag |
|
| --defrag_block_count 16 | Read this number of pool blocks at once during defrag |
|
||||||
| `--defrag_iodepth 16` | Move up to this number of files in parallel during defrag |
|
| --defrag_iodepth 16 | Move up to this number of files in parallel during defrag |
|
||||||
| `--trace` | Print verbose defragmentation status |
|
| --trace | Print verbose defragmentation status |
|
||||||
| `--dry-run` | Skip modifications, only print status |
|
| --dry-run | Skip modifications, only print status |
|
||||||
| `--recalc-stats` | Recalculate all volume statistics |
|
| --recalc-stats | Recalculate all volume statistics |
|
||||||
| `--include-empty` | Include old and empty volumes; make sure to restart NFS servers before using it |
|
| --include-empty | Include old and empty volumes; make sure to restart NFS servers before using it |
|
||||||
| `--no-rm` | Move, but do not delete data |
|
| --no-rm | Move, but do not delete data |
|
||||||
|
|
||||||
## Common options
|
## Common options
|
||||||
|
|
||||||
|
|
|
@ -165,16 +165,16 @@ JSON-формате :-). Для инспекции содержимого БД
|
||||||
Опции:
|
Опции:
|
||||||
|
|
||||||
| <!-- --> | <!-- --> |
|
| <!-- --> | <!-- --> |
|
||||||
|----------------------------|------------------------------------------------------------------------ |
|
|--------------------------|------------------------------------------------------------------------ |
|
||||||
| `--volume_untouched 86400` | Дефрагментировать только тома, в которые уже не писали это число секунд |
|
| --volume_untouched 86400 | Дефрагментировать только тома, в которые уже не писали это число секунд |
|
||||||
| `--defrag_percent 50` | Дефрагментировать только тома, в которых этот % данных удалён |
|
| --defrag_percent 50 | Дефрагментировать только тома, в которых этот % данных удалён |
|
||||||
| `--defrag_block_count 16` | Читать это количество блоков пула за один раз |
|
| --defrag_block_count 16 | Читать это количество блоков пула за один раз |
|
||||||
| `--defrag_iodepth 16` | Перемещать одновременно до этого числа файлов |
|
| --defrag_iodepth 16 | Перемещать одновременно до этого числа файлов |
|
||||||
| `--trace` | Печатать детальную статистику дефрагментации |
|
| --trace | Печатать детальную статистику дефрагментации |
|
||||||
| `--dry-run` | Не производить никаких изменений, только описать выполняемые действия |
|
| --dry-run | Не производить никаких изменений, только описать выполняемые действия |
|
||||||
| `--recalc-stats` | Пересчитать и сохранить статистику всех томов |
|
| --recalc-stats | Пересчитать и сохранить статистику всех томов |
|
||||||
| `--include-empty` | Дефрагментировать старые и пустые тома; обязательно перезапустите NFS-сервера после использования этой опции |
|
| --include-empty | Дефрагментировать старые и пустые тома; обязательно перезапустите NFS-сервера после использования этой опции |
|
||||||
| `--no-rm` | Перемещать, но не удалять данные |
|
| --no-rm | Перемещать, но не удалять данные |
|
||||||
|
|
||||||
## Общие опции
|
## Общие опции
|
||||||
|
|
||||||
|
|
|
@ -151,9 +151,9 @@ Example performance comparison:
|
||||||
To try VDUSE you need at least Linux 5.15, built with VDUSE support
|
To try VDUSE you need at least Linux 5.15, built with VDUSE support
|
||||||
(CONFIG_VDPA=m, CONFIG_VDPA_USER=m, CONFIG_VIRTIO_VDPA=m).
|
(CONFIG_VDPA=m, CONFIG_VDPA_USER=m, CONFIG_VIRTIO_VDPA=m).
|
||||||
|
|
||||||
Debian Linux kernels had these options disabled until 6.6, so make sure you install a newer kernel
|
Debian Linux kernels have these options disabled by now, so if you want to try it on Debian,
|
||||||
(from bookworm-backports, trixie or newer Debian version) if you want to try VDUSE. You can also
|
use a kernel from Ubuntu [kernel-ppa/mainline](https://kernel.ubuntu.com/~kernel-ppa/mainline/), Proxmox,
|
||||||
build modules for an existing kernel manually:
|
or build modules for Debian kernel manually:
|
||||||
|
|
||||||
```
|
```
|
||||||
mkdir build
|
mkdir build
|
||||||
|
|
|
@ -154,9 +154,9 @@ VDUSE - на данный момент лучший интерфейс для п
|
||||||
Чтобы попробовать VDUSE, вам нужно ядро Linux как минимум версии 5.15, собранное с поддержкой
|
Чтобы попробовать VDUSE, вам нужно ядро Linux как минимум версии 5.15, собранное с поддержкой
|
||||||
VDUSE (CONFIG_VDPA=m, CONFIG_VDPA_USER=m, CONFIG_VIRTIO_VDPA=m).
|
VDUSE (CONFIG_VDPA=m, CONFIG_VDPA_USER=m, CONFIG_VIRTIO_VDPA=m).
|
||||||
|
|
||||||
В ядрах в Debian Linux эти опции включены, только начиная с 6.6, так что установите свежее ядро
|
В ядрах в Debian Linux поддержка пока отключена по умолчанию, так что чтобы попробовать VDUSE
|
||||||
из bookworm-backports, trixie или из более новой версии Debian, если хотите попробовать VDUSE.
|
на Debian, поставьте ядро из Ubuntu [kernel-ppa/mainline](https://kernel.ubuntu.com/~kernel-ppa/mainline/),
|
||||||
Либо же вы можете самостоятельно собрать модули для установленного ядра:
|
из Proxmox или соберите модули для ядра Debian вручную:
|
||||||
|
|
||||||
```
|
```
|
||||||
mkdir build
|
mkdir build
|
||||||
|
|
|
@ -0,0 +1,6 @@
|
||||||
|
---
|
||||||
|
title: "{{ replace .Name "-" " " | title }}"
|
||||||
|
date: {{ .Date }}
|
||||||
|
draft: true
|
||||||
|
---
|
||||||
|
|
|
@ -0,0 +1,35 @@
|
||||||
|
baseURL: http://localhost
|
||||||
|
title: Vitastor
|
||||||
|
theme: hugo-geekdoc
|
||||||
|
#languageCode: en-us
|
||||||
|
|
||||||
|
pluralizeListTitles: false
|
||||||
|
|
||||||
|
# Geekdoc required configuration
|
||||||
|
pygmentsUseClasses: true
|
||||||
|
pygmentsCodeFences: true
|
||||||
|
disablePathToLower: true
|
||||||
|
|
||||||
|
# Required if you want to render robots.txt template
|
||||||
|
enableRobotsTXT: true
|
||||||
|
|
||||||
|
defaultContentLanguage: en
|
||||||
|
languages:
|
||||||
|
en:
|
||||||
|
weight: 1
|
||||||
|
languageName: English
|
||||||
|
ru:
|
||||||
|
weight: 1
|
||||||
|
languageName: Русский
|
||||||
|
|
||||||
|
markup:
|
||||||
|
goldmark:
|
||||||
|
renderer:
|
||||||
|
# Needed for mermaid shortcode
|
||||||
|
unsafe: true
|
||||||
|
tableOfContents:
|
||||||
|
startLevel: 1
|
||||||
|
endLevel: 9
|
||||||
|
|
||||||
|
taxonomies:
|
||||||
|
tag: tags
|
|
@ -0,0 +1,6 @@
|
||||||
|
## The Idea
|
||||||
|
|
||||||
|
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).
|
|
@ -0,0 +1,5 @@
|
||||||
|
---
|
||||||
|
title: Parameter Reference
|
||||||
|
weight: 1
|
||||||
|
---
|
||||||
|
|
|
@ -0,0 +1,5 @@
|
||||||
|
---
|
||||||
|
title: Перечень настроек
|
||||||
|
weight: 1
|
||||||
|
---
|
||||||
|
|
|
@ -0,0 +1,5 @@
|
||||||
|
---
|
||||||
|
title: Pool configuration
|
||||||
|
weight: 100
|
||||||
|
---
|
||||||
|
|
|
@ -0,0 +1,5 @@
|
||||||
|
---
|
||||||
|
title: Packages
|
||||||
|
weight: 2
|
||||||
|
---
|
||||||
|
|
|
@ -0,0 +1,5 @@
|
||||||
|
---
|
||||||
|
title: Quick Start
|
||||||
|
weight: 1
|
||||||
|
---
|
||||||
|
|
|
@ -0,0 +1,5 @@
|
||||||
|
---
|
||||||
|
title: Building from Source
|
||||||
|
weight: 3
|
||||||
|
---
|
||||||
|
|
|
@ -0,0 +1,4 @@
|
||||||
|
---
|
||||||
|
title: Introduction
|
||||||
|
weight: -1
|
||||||
|
---
|
|
@ -0,0 +1,5 @@
|
||||||
|
---
|
||||||
|
title: Architecture
|
||||||
|
weight: 3
|
||||||
|
---
|
||||||
|
|
|
@ -0,0 +1,5 @@
|
||||||
|
---
|
||||||
|
title: Author and License
|
||||||
|
weight: 3
|
||||||
|
---
|
||||||
|
|
|
@ -0,0 +1,5 @@
|
||||||
|
---
|
||||||
|
title: Features
|
||||||
|
weight: 1
|
||||||
|
---
|
||||||
|
|
|
@ -0,0 +1,5 @@
|
||||||
|
---
|
||||||
|
title: Example Comparison with Ceph
|
||||||
|
weight: 4
|
||||||
|
---
|
||||||
|
|
|
@ -0,0 +1,5 @@
|
||||||
|
---
|
||||||
|
title: Vitastor's Theoretical Maximum Performance
|
||||||
|
weight: 3
|
||||||
|
---
|
||||||
|
|
|
@ -0,0 +1,5 @@
|
||||||
|
---
|
||||||
|
title: Tuning
|
||||||
|
weight: 2
|
||||||
|
---
|
||||||
|
|
|
@ -0,0 +1,5 @@
|
||||||
|
---
|
||||||
|
title: Understanding Storage Performance
|
||||||
|
weight: 1
|
||||||
|
---
|
||||||
|
|
|
@ -0,0 +1,7 @@
|
||||||
|
---
|
||||||
|
title: Vitastor CLI
|
||||||
|
weight: 1
|
||||||
|
---
|
||||||
|
|
||||||
|
{{< toc >}}
|
||||||
|
|
|
@ -0,0 +1,5 @@
|
||||||
|
---
|
||||||
|
title: NBD
|
||||||
|
weight: 6
|
||||||
|
---
|
||||||
|
|
|
@ -0,0 +1,5 @@
|
||||||
|
---
|
||||||
|
title: QEMU and qemu-img
|
||||||
|
weight: 2
|
||||||
|
---
|
||||||
|
|
|
@ -0,0 +1,37 @@
|
||||||
|
---
|
||||||
|
nav_navigation: Навигация
|
||||||
|
nav_tags: Теги
|
||||||
|
nav_more: Подробнее
|
||||||
|
nav_top: К началу
|
||||||
|
|
||||||
|
form_placeholder_search: Поиск
|
||||||
|
|
||||||
|
error_page_title: Открыта несуществующая страница
|
||||||
|
error_message_title: Потерялись?
|
||||||
|
error_message_code: Ошибка 404
|
||||||
|
error_message_text: >
|
||||||
|
Похоже, страница, которую вы открыли, не существует. Попробуйте найти
|
||||||
|
нужную информацию с <a class="gdoc-error__link" href="{{ . }}">главной страницы</a>.
|
||||||
|
|
||||||
|
button_toggle_dark: Переключить тёмный/светлый/авто режим
|
||||||
|
button_nav_open: Показать навигацию
|
||||||
|
button_nav_close: Скрыть навигацию
|
||||||
|
button_menu_open: Открыть меню
|
||||||
|
button_menu_close: Закрыть меню
|
||||||
|
button_homepage: На главную
|
||||||
|
|
||||||
|
title_anchor_prefix: "Ссылка на:"
|
||||||
|
|
||||||
|
posts_read_more: Читать подробнее
|
||||||
|
posts_read_time:
|
||||||
|
one: "Одна минута на чтение"
|
||||||
|
other: "{{ . }} минут(ы) на чтение"
|
||||||
|
posts_update_prefix: Обновлено
|
||||||
|
|
||||||
|
footer_build_with: >
|
||||||
|
Сделано на <a href="https://gohugo.io/" class="gdoc-footer__link">Hugo</a> с
|
||||||
|
<svg class="icon gdoc_heart"><use xlink:href="#gdoc_heart"></use></svg>
|
||||||
|
footer_legal_notice: Правовая информация
|
||||||
|
footer_privacy_policy: Приватность
|
||||||
|
|
||||||
|
language_switch_no_tranlation_prefix: "Страница не переведена:"
|
|
@ -0,0 +1,34 @@
|
||||||
|
<footer class="gdoc-footer">
|
||||||
|
<div class="container flex">
|
||||||
|
<div class="flex flex-wrap" style="flex: 1">
|
||||||
|
<span class="gdoc-footer__item gdoc-footer__item--row">
|
||||||
|
© Vitaliy Filippov, 2021+
|
||||||
|
</span>
|
||||||
|
</div>
|
||||||
|
<div class="flex flex-wrap">
|
||||||
|
{{ with .Site.Params.GeekdocLegalNotice }}
|
||||||
|
<span class="gdoc-footer__item gdoc-footer__item--row">
|
||||||
|
<a href="{{ . | relURL }}" class="gdoc-footer__link">{{ i18n "footer_legal_notice" }}</a>
|
||||||
|
</span>
|
||||||
|
{{ end }}
|
||||||
|
{{ with .Site.Params.GeekdocPrivacyPolicy }}
|
||||||
|
<span class="gdoc-footer__item gdoc-footer__item--row">
|
||||||
|
<a href="{{ . | relURL }}" class="gdoc-footer__link">{{ i18n "footer_privacy_policy" }}</a>
|
||||||
|
</span>
|
||||||
|
{{ end }}
|
||||||
|
</div>
|
||||||
|
{{ if (default true .Site.Params.GeekdocBackToTop) }}
|
||||||
|
<div class="flex flex-25 justify-end">
|
||||||
|
<span class="gdoc-footer__item gdoc-footer__item--row" style="margin-right: 50px">
|
||||||
|
{{ i18n "footer_build_with" | safeHTML }}
|
||||||
|
</span>
|
||||||
|
<span class="gdoc-footer__item">
|
||||||
|
<a class="gdoc-footer__link fake-link" href="#" aria-label="{{ i18n "nav_top" }}">
|
||||||
|
<svg class="icon gdoc_keyboard_arrow_up"><use xlink:href="#gdoc_keyboard_arrow_up"></use></svg>
|
||||||
|
<span class="hidden-mobile">{{ i18n "nav_top" }}</span>
|
||||||
|
</a>
|
||||||
|
</span>
|
||||||
|
</div>
|
||||||
|
{{ end }}
|
||||||
|
</div>
|
||||||
|
</footer>
|
|
@ -0,0 +1,215 @@
|
||||||
|
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
||||||
|
<svg
|
||||||
|
xmlns:osb="http://www.openswatchbook.org/uri/2009/osb"
|
||||||
|
xmlns:dc="http://purl.org/dc/elements/1.1/"
|
||||||
|
xmlns:cc="http://creativecommons.org/ns#"
|
||||||
|
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
|
||||||
|
xmlns:svg="http://www.w3.org/2000/svg"
|
||||||
|
xmlns="http://www.w3.org/2000/svg"
|
||||||
|
xmlns:xlink="http://www.w3.org/1999/xlink"
|
||||||
|
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
|
||||||
|
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
|
||||||
|
sodipodi:docname="logo_only2.svg"
|
||||||
|
inkscape:version="1.0.2 (e86c870879, 2021-01-15)"
|
||||||
|
id="svg1340"
|
||||||
|
version="1.1"
|
||||||
|
viewBox="0 0 100 86.80192"
|
||||||
|
height="86.801918mm"
|
||||||
|
width="100mm"
|
||||||
|
inkscape:export-filename="/var/home/vitali/SVN/vitastor/presentation/logos/logo_only.png"
|
||||||
|
inkscape:export-xdpi="92.889999"
|
||||||
|
inkscape:export-ydpi="92.889999">
|
||||||
|
<defs
|
||||||
|
id="defs1334">
|
||||||
|
<linearGradient
|
||||||
|
osb:paint="gradient"
|
||||||
|
id="linearGradient866">
|
||||||
|
<stop
|
||||||
|
id="stop862"
|
||||||
|
offset="0"
|
||||||
|
style="stop-color:#c0c0c0;stop-opacity:1" />
|
||||||
|
<stop
|
||||||
|
id="stop864"
|
||||||
|
offset="1"
|
||||||
|
style="stop-color:#000000;stop-opacity:0" />
|
||||||
|
</linearGradient>
|
||||||
|
<linearGradient
|
||||||
|
id="linearGradient846"
|
||||||
|
osb:paint="gradient">
|
||||||
|
<stop
|
||||||
|
style="stop-color:#ffd42a;stop-opacity:1"
|
||||||
|
offset="0"
|
||||||
|
id="stop842" />
|
||||||
|
<stop
|
||||||
|
style="stop-color:#ffa200;stop-opacity:1"
|
||||||
|
offset="1"
|
||||||
|
id="stop844" />
|
||||||
|
</linearGradient>
|
||||||
|
<radialGradient
|
||||||
|
r="50"
|
||||||
|
fy="159.11139"
|
||||||
|
fx="202.36813"
|
||||||
|
cy="159.11139"
|
||||||
|
cx="202.36813"
|
||||||
|
gradientTransform="matrix(1.2462942,-1.2279529,0.77712408,0.78873143,-190.96813,230.1331)"
|
||||||
|
gradientUnits="userSpaceOnUse"
|
||||||
|
id="radialGradient1530"
|
||||||
|
xlink:href="#linearGradient1352"
|
||||||
|
inkscape:collect="always" />
|
||||||
|
<linearGradient
|
||||||
|
inkscape:collect="always"
|
||||||
|
id="linearGradient1352">
|
||||||
|
<stop
|
||||||
|
style="stop-color:#00c9e6;stop-opacity:1"
|
||||||
|
offset="0"
|
||||||
|
id="stop1348" />
|
||||||
|
<stop
|
||||||
|
style="stop-color:#5240d3;stop-opacity:1"
|
||||||
|
offset="1"
|
||||||
|
id="stop1350" />
|
||||||
|
</linearGradient>
|
||||||
|
<linearGradient
|
||||||
|
y2="62.555599"
|
||||||
|
x2="51.484566"
|
||||||
|
y1="62.555599"
|
||||||
|
x1="38.105473"
|
||||||
|
gradientTransform="rotate(-16.930773,271.11609,-412.42594)"
|
||||||
|
gradientUnits="userSpaceOnUse"
|
||||||
|
id="linearGradient1508"
|
||||||
|
xlink:href="#linearGradient1323"
|
||||||
|
inkscape:collect="always" />
|
||||||
|
<linearGradient
|
||||||
|
inkscape:collect="always"
|
||||||
|
id="linearGradient1323">
|
||||||
|
<stop
|
||||||
|
style="stop-color:#000000;stop-opacity:0.47178105"
|
||||||
|
offset="0"
|
||||||
|
id="stop1319" />
|
||||||
|
<stop
|
||||||
|
style="stop-color:#eeaaff;stop-opacity:0;"
|
||||||
|
offset="1"
|
||||||
|
id="stop1321" />
|
||||||
|
</linearGradient>
|
||||||
|
<radialGradient
|
||||||
|
r="21.541935"
|
||||||
|
fy="24.614815"
|
||||||
|
fx="45.312912"
|
||||||
|
cy="24.614815"
|
||||||
|
cx="45.312912"
|
||||||
|
gradientTransform="matrix(1.0933447,0.13113705,-0.12664108,1.0558599,-1.082187,93.974708)"
|
||||||
|
gradientUnits="userSpaceOnUse"
|
||||||
|
id="radialGradient1504"
|
||||||
|
xlink:href="#linearGradient846"
|
||||||
|
inkscape:collect="always" />
|
||||||
|
<filter
|
||||||
|
style="color-interpolation-filters:sRGB"
|
||||||
|
inkscape:label="Drop Shadow"
|
||||||
|
id="filter1497"
|
||||||
|
width="2"
|
||||||
|
height="2"
|
||||||
|
x="-0.5"
|
||||||
|
y="-0.5">
|
||||||
|
<feFlood
|
||||||
|
flood-opacity="0.498039"
|
||||||
|
flood-color="rgb(0,0,0)"
|
||||||
|
result="flood"
|
||||||
|
id="feFlood1487" />
|
||||||
|
<feComposite
|
||||||
|
in="flood"
|
||||||
|
in2="SourceGraphic"
|
||||||
|
operator="in"
|
||||||
|
result="composite1"
|
||||||
|
id="feComposite1489" />
|
||||||
|
<feGaussianBlur
|
||||||
|
in="composite1"
|
||||||
|
stdDeviation="6"
|
||||||
|
result="blur"
|
||||||
|
id="feGaussianBlur1491" />
|
||||||
|
<feOffset
|
||||||
|
dx="0"
|
||||||
|
dy="6"
|
||||||
|
result="offset"
|
||||||
|
id="feOffset1493" />
|
||||||
|
<feComposite
|
||||||
|
in="offset"
|
||||||
|
in2="offset"
|
||||||
|
operator="atop"
|
||||||
|
result="composite2"
|
||||||
|
id="feComposite1495" />
|
||||||
|
</filter>
|
||||||
|
<radialGradient
|
||||||
|
r="21.541935"
|
||||||
|
fy="24.614815"
|
||||||
|
fx="45.312912"
|
||||||
|
cy="24.614815"
|
||||||
|
cx="45.312912"
|
||||||
|
gradientTransform="matrix(1.0933447,0.13113705,-0.12664108,1.0558599,-1.082187,93.974708)"
|
||||||
|
gradientUnits="userSpaceOnUse"
|
||||||
|
id="radialGradient1506"
|
||||||
|
xlink:href="#linearGradient846"
|
||||||
|
inkscape:collect="always" />
|
||||||
|
</defs>
|
||||||
|
<sodipodi:namedview
|
||||||
|
inkscape:window-maximized="1"
|
||||||
|
inkscape:window-y="0"
|
||||||
|
inkscape:window-x="0"
|
||||||
|
inkscape:window-height="992"
|
||||||
|
inkscape:window-width="1920"
|
||||||
|
fit-margin-bottom="0"
|
||||||
|
fit-margin-right="0"
|
||||||
|
fit-margin-left="0"
|
||||||
|
fit-margin-top="-30"
|
||||||
|
showgrid="false"
|
||||||
|
inkscape:document-rotation="0"
|
||||||
|
inkscape:current-layer="layer1"
|
||||||
|
inkscape:document-units="mm"
|
||||||
|
inkscape:cy="47.914558"
|
||||||
|
inkscape:cx="-103.69646"
|
||||||
|
inkscape:zoom="0.7"
|
||||||
|
inkscape:pageshadow="2"
|
||||||
|
inkscape:pageopacity="1"
|
||||||
|
borderopacity="1.0"
|
||||||
|
bordercolor="#666666"
|
||||||
|
pagecolor="#000000"
|
||||||
|
id="base" />
|
||||||
|
<metadata
|
||||||
|
id="metadata1337">
|
||||||
|
<rdf:RDF>
|
||||||
|
<cc:Work
|
||||||
|
rdf:about="">
|
||||||
|
<dc:format>image/svg+xml</dc:format>
|
||||||
|
<dc:type
|
||||||
|
rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
|
||||||
|
<dc:title></dc:title>
|
||||||
|
</cc:Work>
|
||||||
|
</rdf:RDF>
|
||||||
|
</metadata>
|
||||||
|
<g
|
||||||
|
transform="translate(-133.26969,-52.101187)"
|
||||||
|
id="layer1"
|
||||||
|
inkscape:groupmode="layer"
|
||||||
|
inkscape:label="Слой 1">
|
||||||
|
<path
|
||||||
|
style="fill:url(#radialGradient1530);fill-opacity:1;fill-rule:evenodd;stroke:#000000;stroke-width:0;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
|
||||||
|
d="m 133.26969,59.089473 50,75.000087 50,-75.000087 z"
|
||||||
|
id="path1528"
|
||||||
|
sodipodi:nodetypes="cccc" />
|
||||||
|
<path
|
||||||
|
d="m 194.29572,89.403603 -8.41706,2.562119 -2.50682,7.49308 7.17785,23.579008 9.60097,-14.40173 z"
|
||||||
|
style="fill:url(#linearGradient1508);fill-opacity:1;stroke-width:0;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:0.501961"
|
||||||
|
id="path1459" />
|
||||||
|
<g
|
||||||
|
transform="translate(135.70225,-49.385894)"
|
||||||
|
id="g1465">
|
||||||
|
<path
|
||||||
|
id="path1461"
|
||||||
|
style="fill:url(#radialGradient1504);fill-opacity:1;fill-rule:evenodd;stroke:#000000;stroke-width:0;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1;filter:url(#filter1497)"
|
||||||
|
d="m 28.817436,101.36529 c 3.112699,10.74423 6.225077,21.48892 9.333984,32.23438 2.519532,0 5.039063,0 7.558594,0 -0.985406,8.09729 -2.085815,16.18202 -2.951172,24.29297 -0.06053,0.88723 1.098131,1.61652 1.76,0.9155 1.007514,-1.05482 1.676008,-2.3829 2.528566,-3.56053 7.51538,-11.37722 14.987447,-22.78299 22.482919,-34.17333 -3.239584,0 -6.479167,0 -9.71875,0 2.887267,-6.79562 5.775365,-13.59088 8.662109,-20.38672 -13.284505,0 -26.56901,0 -39.853516,0 0.06576,0.22591 0.131511,0.45182 0.197266,0.67773 z" />
|
||||||
|
<path
|
||||||
|
sodipodi:nodetypes="cccccccc"
|
||||||
|
id="path1463"
|
||||||
|
d="m 30.735882,102.2764 h 35.342242 l -8.662729,20.3854 h 9.173783 l -22.106472,33.62346 3.027029,-24.27377 H 39.34604 Z"
|
||||||
|
style="fill:url(#radialGradient1506);fill-opacity:1;fill-rule:evenodd;stroke:#000000;stroke-width:0;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1" />
|
||||||
|
</g>
|
||||||
|
</g>
|
||||||
|
</svg>
|
After Width: | Height: | Size: 7.4 KiB |
|
@ -0,0 +1,138 @@
|
||||||
|
/* Global customization */
|
||||||
|
|
||||||
|
:root {
|
||||||
|
--code-max-height: 60rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Light mode theming */
|
||||||
|
:root,
|
||||||
|
:root[color-mode="light"] {
|
||||||
|
--header-background: #404050;
|
||||||
|
--header-font-color: #ffffff;
|
||||||
|
|
||||||
|
--body-background: #ffffff;
|
||||||
|
--body-font-color: #343a40;
|
||||||
|
|
||||||
|
--button-background: #62cb97;
|
||||||
|
--button-border-color: #4ec58a;
|
||||||
|
|
||||||
|
--link-color: #c54e8a;
|
||||||
|
--link-color-visited: #c54e8a;
|
||||||
|
|
||||||
|
--code-background: #f5f6f8;
|
||||||
|
--code-accent-color: #e3e7eb;
|
||||||
|
--code-accent-color-lite: #eff1f3;
|
||||||
|
|
||||||
|
--accent-color: #e9ecef;
|
||||||
|
--accent-color-lite: #f8f9fa;
|
||||||
|
|
||||||
|
--control-icons: #b2bac1;
|
||||||
|
|
||||||
|
--footer-background: #606070;
|
||||||
|
--footer-font-color: #ffffff;
|
||||||
|
--footer-link-color: #ffcc5c;
|
||||||
|
--footer-link-color-visited: #ffcc5c;
|
||||||
|
}
|
||||||
|
@media (prefers-color-scheme: light) {
|
||||||
|
:root {
|
||||||
|
--header-background: #404050;
|
||||||
|
--header-font-color: #ffffff;
|
||||||
|
|
||||||
|
--body-background: #ffffff;
|
||||||
|
--body-font-color: #343a40;
|
||||||
|
|
||||||
|
--button-background: #62cb97;
|
||||||
|
--button-border-color: #4ec58a;
|
||||||
|
|
||||||
|
--link-color: #c54e8a;
|
||||||
|
--link-color-visited: #c54e8a;
|
||||||
|
|
||||||
|
--code-background: #f5f6f8;
|
||||||
|
--code-accent-color: #e3e7eb;
|
||||||
|
--code-accent-color-lite: #eff1f3;
|
||||||
|
|
||||||
|
--accent-color: #e9ecef;
|
||||||
|
--accent-color-lite: #f8f9fa;
|
||||||
|
|
||||||
|
--control-icons: #b2bac1;
|
||||||
|
|
||||||
|
--footer-background: #606070;
|
||||||
|
--footer-font-color: #ffffff;
|
||||||
|
--footer-link-color: #ffcc5c;
|
||||||
|
--footer-link-color-visited: #ffcc5c;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Dark mode theming */
|
||||||
|
:root[color-mode="dark"] {
|
||||||
|
--header-background: #202830;
|
||||||
|
--header-font-color: #ffffff;
|
||||||
|
|
||||||
|
--body-background: #343a44;
|
||||||
|
--body-font-color: #ced3d8;
|
||||||
|
|
||||||
|
--button-background: #62cb97;
|
||||||
|
--button-border-color: #4ec58a;
|
||||||
|
|
||||||
|
--link-color: #7ac29e;
|
||||||
|
--link-color-visited: #7ac29e;
|
||||||
|
|
||||||
|
--code-background: #2f353a;
|
||||||
|
--code-accent-color: #262b2f;
|
||||||
|
--code-accent-color-lite: #2b3035;
|
||||||
|
|
||||||
|
--accent-color: #2b3035;
|
||||||
|
--accent-color-lite: #2f353a;
|
||||||
|
|
||||||
|
--control-icons: #b2bac1;
|
||||||
|
|
||||||
|
--footer-background: #2f333e;
|
||||||
|
--footer-font-color: #cccccc;
|
||||||
|
--footer-link-color: #7ac29e;
|
||||||
|
--footer-link-color-visited: #7ac29e;
|
||||||
|
}
|
||||||
|
@media (prefers-color-scheme: dark) {
|
||||||
|
:root {
|
||||||
|
--header-background: #404070;
|
||||||
|
--header-font-color: #ffffff;
|
||||||
|
|
||||||
|
--body-background: #343a40;
|
||||||
|
--body-font-color: #ced3d8;
|
||||||
|
|
||||||
|
--button-background: #62cb97;
|
||||||
|
--button-border-color: #4ec58a;
|
||||||
|
|
||||||
|
--link-color: #7ac29e;
|
||||||
|
--link-color-visited: #7ac29e;
|
||||||
|
|
||||||
|
--code-background: #2f353a;
|
||||||
|
--code-accent-color: #262b2f;
|
||||||
|
--code-accent-color-lite: #2b3035;
|
||||||
|
|
||||||
|
--accent-color: #2b3035;
|
||||||
|
--accent-color-lite: #2f353a;
|
||||||
|
|
||||||
|
--control-icons: #b2bac1;
|
||||||
|
|
||||||
|
--footer-background: #2f333e;
|
||||||
|
--footer-font-color: #cccccc;
|
||||||
|
--footer-link-color: #7ac29e;
|
||||||
|
--footer-link-color-visited: #7ac29e;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.gdoc-brand__img {
|
||||||
|
width: 48px;
|
||||||
|
height: auto;
|
||||||
|
margin-top: -4px;
|
||||||
|
margin-bottom: -4px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.gdoc-menu-header > span {
|
||||||
|
display: flex;
|
||||||
|
flex-direction: row-reverse;
|
||||||
|
}
|
||||||
|
|
||||||
|
span.gdoc-language {
|
||||||
|
margin-right: 20px;
|
||||||
|
}
|
Binary file not shown.
After Width: | Height: | Size: 709 B |
Binary file not shown.
After Width: | Height: | Size: 1.5 KiB |
|
@ -0,0 +1,196 @@
|
||||||
|
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
||||||
|
<svg
|
||||||
|
xmlns:osb="http://www.openswatchbook.org/uri/2009/osb"
|
||||||
|
xmlns:dc="http://purl.org/dc/elements/1.1/"
|
||||||
|
xmlns:cc="http://creativecommons.org/ns#"
|
||||||
|
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
|
||||||
|
xmlns:svg="http://www.w3.org/2000/svg"
|
||||||
|
xmlns="http://www.w3.org/2000/svg"
|
||||||
|
xmlns:xlink="http://www.w3.org/1999/xlink"
|
||||||
|
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
|
||||||
|
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
|
||||||
|
sodipodi:docname="favicon.svg"
|
||||||
|
inkscape:version="1.0.2 (e86c870879, 2021-01-15)"
|
||||||
|
id="svg1340"
|
||||||
|
version="1.1"
|
||||||
|
viewBox="0 0 100 100"
|
||||||
|
height="100mm"
|
||||||
|
width="100mm"
|
||||||
|
inkscape:export-filename="/var/home/vitali/SVN/vitastor/docs/static/favicon/favicon-64x64.png"
|
||||||
|
inkscape:export-xdpi="16.26"
|
||||||
|
inkscape:export-ydpi="16.26">
|
||||||
|
<defs
|
||||||
|
id="defs1334">
|
||||||
|
<linearGradient
|
||||||
|
osb:paint="gradient"
|
||||||
|
id="linearGradient866">
|
||||||
|
<stop
|
||||||
|
id="stop862"
|
||||||
|
offset="0"
|
||||||
|
style="stop-color:#c0c0c0;stop-opacity:1" />
|
||||||
|
<stop
|
||||||
|
id="stop864"
|
||||||
|
offset="1"
|
||||||
|
style="stop-color:#000000;stop-opacity:0" />
|
||||||
|
</linearGradient>
|
||||||
|
<linearGradient
|
||||||
|
id="linearGradient846"
|
||||||
|
osb:paint="gradient">
|
||||||
|
<stop
|
||||||
|
style="stop-color:#ffd42a;stop-opacity:1"
|
||||||
|
offset="0"
|
||||||
|
id="stop842" />
|
||||||
|
<stop
|
||||||
|
style="stop-color:#ffa200;stop-opacity:1"
|
||||||
|
offset="1"
|
||||||
|
id="stop844" />
|
||||||
|
</linearGradient>
|
||||||
|
<radialGradient
|
||||||
|
r="50"
|
||||||
|
fy="159.11139"
|
||||||
|
fx="202.36813"
|
||||||
|
cy="159.11139"
|
||||||
|
cx="202.36813"
|
||||||
|
gradientTransform="matrix(1.2462942,-1.2279529,0.77712408,0.78873143,-190.96813,230.1331)"
|
||||||
|
gradientUnits="userSpaceOnUse"
|
||||||
|
id="radialGradient1530"
|
||||||
|
xlink:href="#linearGradient1352"
|
||||||
|
inkscape:collect="always" />
|
||||||
|
<linearGradient
|
||||||
|
inkscape:collect="always"
|
||||||
|
id="linearGradient1352">
|
||||||
|
<stop
|
||||||
|
style="stop-color:#00c9e6;stop-opacity:1"
|
||||||
|
offset="0"
|
||||||
|
id="stop1348" />
|
||||||
|
<stop
|
||||||
|
style="stop-color:#5240d3;stop-opacity:1"
|
||||||
|
offset="1"
|
||||||
|
id="stop1350" />
|
||||||
|
</linearGradient>
|
||||||
|
<linearGradient
|
||||||
|
y2="62.555599"
|
||||||
|
x2="51.484566"
|
||||||
|
y1="62.555599"
|
||||||
|
x1="38.105473"
|
||||||
|
gradientTransform="rotate(-16.930773,271.11609,-412.42594)"
|
||||||
|
gradientUnits="userSpaceOnUse"
|
||||||
|
id="linearGradient1508"
|
||||||
|
xlink:href="#linearGradient1323"
|
||||||
|
inkscape:collect="always" />
|
||||||
|
<linearGradient
|
||||||
|
inkscape:collect="always"
|
||||||
|
id="linearGradient1323">
|
||||||
|
<stop
|
||||||
|
style="stop-color:#000000;stop-opacity:0.47178105"
|
||||||
|
offset="0"
|
||||||
|
id="stop1319" />
|
||||||
|
<stop
|
||||||
|
style="stop-color:#eeaaff;stop-opacity:0;"
|
||||||
|
offset="1"
|
||||||
|
id="stop1321" />
|
||||||
|
</linearGradient>
|
||||||
|
<filter
|
||||||
|
style="color-interpolation-filters:sRGB"
|
||||||
|
inkscape:label="Drop Shadow"
|
||||||
|
id="filter1497"
|
||||||
|
width="2"
|
||||||
|
height="2"
|
||||||
|
x="-0.5"
|
||||||
|
y="-0.5">
|
||||||
|
<feFlood
|
||||||
|
flood-opacity="0.498039"
|
||||||
|
flood-color="rgb(0,0,0)"
|
||||||
|
result="flood"
|
||||||
|
id="feFlood1487" />
|
||||||
|
<feComposite
|
||||||
|
in="flood"
|
||||||
|
in2="SourceGraphic"
|
||||||
|
operator="in"
|
||||||
|
result="composite1"
|
||||||
|
id="feComposite1489" />
|
||||||
|
<feGaussianBlur
|
||||||
|
in="composite1"
|
||||||
|
stdDeviation="6"
|
||||||
|
result="blur"
|
||||||
|
id="feGaussianBlur1491" />
|
||||||
|
<feOffset
|
||||||
|
dx="0"
|
||||||
|
dy="6"
|
||||||
|
result="offset"
|
||||||
|
id="feOffset1493" />
|
||||||
|
<feComposite
|
||||||
|
in="offset"
|
||||||
|
in2="offset"
|
||||||
|
operator="atop"
|
||||||
|
result="composite2"
|
||||||
|
id="feComposite1495" />
|
||||||
|
</filter>
|
||||||
|
<radialGradient
|
||||||
|
r="21.541935"
|
||||||
|
fy="24.614815"
|
||||||
|
fx="45.312912"
|
||||||
|
cy="24.614815"
|
||||||
|
cx="45.312912"
|
||||||
|
gradientTransform="matrix(1.6678615,0.20004527,-0.19318681,1.6106796,108.48083,22.966962)"
|
||||||
|
gradientUnits="userSpaceOnUse"
|
||||||
|
id="radialGradient1506"
|
||||||
|
xlink:href="#linearGradient846"
|
||||||
|
inkscape:collect="always" />
|
||||||
|
</defs>
|
||||||
|
<sodipodi:namedview
|
||||||
|
inkscape:window-maximized="1"
|
||||||
|
inkscape:window-y="0"
|
||||||
|
inkscape:window-x="0"
|
||||||
|
inkscape:window-height="992"
|
||||||
|
inkscape:window-width="1920"
|
||||||
|
fit-margin-bottom="0"
|
||||||
|
fit-margin-right="0"
|
||||||
|
fit-margin-left="0"
|
||||||
|
fit-margin-top="0"
|
||||||
|
showgrid="false"
|
||||||
|
inkscape:document-rotation="0"
|
||||||
|
inkscape:current-layer="layer1"
|
||||||
|
inkscape:document-units="mm"
|
||||||
|
inkscape:cy="83.752268"
|
||||||
|
inkscape:cx="-103.69645"
|
||||||
|
inkscape:zoom="0.7"
|
||||||
|
inkscape:pageshadow="2"
|
||||||
|
inkscape:pageopacity="0"
|
||||||
|
borderopacity="1.0"
|
||||||
|
bordercolor="#666666"
|
||||||
|
pagecolor="#000000"
|
||||||
|
id="base" />
|
||||||
|
<metadata
|
||||||
|
id="metadata1337">
|
||||||
|
<rdf:RDF>
|
||||||
|
<cc:Work
|
||||||
|
rdf:about="">
|
||||||
|
<dc:format>image/svg+xml</dc:format>
|
||||||
|
<dc:type
|
||||||
|
rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
|
||||||
|
<dc:title></dc:title>
|
||||||
|
</cc:Work>
|
||||||
|
</rdf:RDF>
|
||||||
|
</metadata>
|
||||||
|
<g
|
||||||
|
transform="translate(-133.26969,-35.630924)"
|
||||||
|
id="layer1"
|
||||||
|
inkscape:groupmode="layer"
|
||||||
|
inkscape:label="Слой 1">
|
||||||
|
<path
|
||||||
|
style="fill:url(#radialGradient1530);fill-opacity:1;fill-rule:evenodd;stroke:#000000;stroke-width:0;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
|
||||||
|
d="m 133.26969,59.089473 50,75.000087 50,-75.000087 z"
|
||||||
|
id="path1528"
|
||||||
|
sodipodi:nodetypes="cccc" />
|
||||||
|
<path
|
||||||
|
d="m 194.29572,89.403603 -8.41706,2.562119 -2.50682,7.49308 7.17785,23.579008 9.60097,-14.40173 z"
|
||||||
|
style="fill:url(#linearGradient1508);fill-opacity:1;stroke-width:0;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:0.501961"
|
||||||
|
id="path1459" />
|
||||||
|
<path
|
||||||
|
sodipodi:nodetypes="cccccccc"
|
||||||
|
id="path1463"
|
||||||
|
d="m 157.01826,35.630924 h 53.91343 l -13.21471,31.09726 h 13.99432 l -33.7227,51.291496 4.61762,-37.02885 h -12.45344 z"
|
||||||
|
style="fill:url(#radialGradient1506);fill-opacity:1;fill-rule:evenodd;stroke:#000000;stroke-width:0;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1" />
|
||||||
|
</g>
|
||||||
|
</svg>
|
After Width: | Height: | Size: 6.2 KiB |
2
json11
2
json11
|
@ -1 +1 @@
|
||||||
Subproject commit fd37016cf85075303de74bab9c61e5d13bf71f64
|
Subproject commit 52a3af664f40775426b189c85b6088d436d05df3
|
|
@ -232,7 +232,6 @@ class EtcdAdapter
|
||||||
async become_master()
|
async become_master()
|
||||||
{
|
{
|
||||||
const state = { ...this.mon.get_mon_state(), id: ''+this.mon.etcd_lease_id };
|
const state = { ...this.mon.get_mon_state(), id: ''+this.mon.etcd_lease_id };
|
||||||
console.log('Waiting to become master');
|
|
||||||
// eslint-disable-next-line no-constant-condition
|
// eslint-disable-next-line no-constant-condition
|
||||||
while (1)
|
while (1)
|
||||||
{
|
{
|
||||||
|
@ -244,6 +243,7 @@ class EtcdAdapter
|
||||||
{
|
{
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
console.log('Waiting to become master');
|
||||||
await new Promise(ok => setTimeout(ok, this.mon.config.etcd_start_timeout));
|
await new Promise(ok => setTimeout(ok, this.mon.config.etcd_start_timeout));
|
||||||
}
|
}
|
||||||
console.log('Became master');
|
console.log('Became master');
|
||||||
|
|
|
@ -56,7 +56,6 @@ const etcd_tree = {
|
||||||
osd_out_time: 600, // seconds. min: 0
|
osd_out_time: 600, // seconds. min: 0
|
||||||
placement_levels: { datacenter: 1, rack: 2, host: 3, osd: 4, ... },
|
placement_levels: { datacenter: 1, rack: 2, host: 3, osd: 4, ... },
|
||||||
use_old_pg_combinator: false,
|
use_old_pg_combinator: false,
|
||||||
osd_backfillfull_ratio: 0.99,
|
|
||||||
// client and osd
|
// client and osd
|
||||||
tcp_header_buffer_size: 65536,
|
tcp_header_buffer_size: 65536,
|
||||||
use_sync_send_recv: false,
|
use_sync_send_recv: false,
|
||||||
|
|
98
mon/mon.js
98
mon/mon.js
|
@ -74,7 +74,6 @@ class Mon
|
||||||
this.state = JSON.parse(JSON.stringify(etcd_tree));
|
this.state = JSON.parse(JSON.stringify(etcd_tree));
|
||||||
this.prev_stats = { osd_stats: {}, osd_diff: {} };
|
this.prev_stats = { osd_stats: {}, osd_diff: {} };
|
||||||
this.recheck_pgs_active = false;
|
this.recheck_pgs_active = false;
|
||||||
this.updating_total_stats = false;
|
|
||||||
this.watcher_active = false;
|
this.watcher_active = false;
|
||||||
this.old_pg_config = false;
|
this.old_pg_config = false;
|
||||||
this.old_pg_stats_seen = false;
|
this.old_pg_stats_seen = false;
|
||||||
|
@ -219,10 +218,6 @@ class Mon
|
||||||
}
|
}
|
||||||
else if (key != '/stats' && key.substr(0, 13) != '/inode/stats/')
|
else if (key != '/stats' && key.substr(0, 13) != '/inode/stats/')
|
||||||
{
|
{
|
||||||
if (key == '/config/pgs' && !kv.value)
|
|
||||||
{
|
|
||||||
this.old_pg_config = false;
|
|
||||||
}
|
|
||||||
changed = true;
|
changed = true;
|
||||||
}
|
}
|
||||||
if (this.config.verbose)
|
if (this.config.verbose)
|
||||||
|
@ -427,6 +422,30 @@ class Mon
|
||||||
throw new Error('Failed to duplicate old PG config to new PG config');
|
throw new Error('Failed to duplicate old PG config to new PG config');
|
||||||
}
|
}
|
||||||
this.old_pg_config = true;
|
this.old_pg_config = true;
|
||||||
|
this.old_pg_config_timer = setInterval(() => this.check_clear_old_config().catch(console.error),
|
||||||
|
this.config.old_pg_config_clear_interval||3600000);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
async check_clear_old_config()
|
||||||
|
{
|
||||||
|
if (this.old_pg_config && this.old_pg_stats_seen)
|
||||||
|
{
|
||||||
|
this.old_pg_stats_seen = false;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if (this.old_pg_config)
|
||||||
|
{
|
||||||
|
await this.etcd.etcd_call('/kv/txn', { success: [
|
||||||
|
{ requestDeleteRange: { key: b64(this.config.etcd_prefix+'/config/pgs') } },
|
||||||
|
{ requestDeleteRange: { key: b64(this.config.etcd_prefix+'/pg/stats/'), range_end: b64(this.config.etcd_prefix+'/pg/stats0') } },
|
||||||
|
] }, this.config.etcd_mon_timeout, this.config.etcd_mon_retries);
|
||||||
|
this.old_pg_config = false;
|
||||||
|
}
|
||||||
|
if (this.old_pg_config_timer)
|
||||||
|
{
|
||||||
|
clearInterval(this.old_pg_config_timer);
|
||||||
|
this.old_pg_config_timer = null;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -568,7 +587,6 @@ class Mon
|
||||||
|
|
||||||
async apply_pool_pgs(results, up_osds, osd_tree, tree_hash)
|
async apply_pool_pgs(results, up_osds, osd_tree, tree_hash)
|
||||||
{
|
{
|
||||||
const etcd_request = { compare: [], success: [] };
|
|
||||||
for (const pool_id in (this.state.pg.config||{}).items||{})
|
for (const pool_id in (this.state.pg.config||{}).items||{})
|
||||||
{
|
{
|
||||||
// We should stop all PGs when deleting a pool or changing its PG count
|
// We should stop all PGs when deleting a pool or changing its PG count
|
||||||
|
@ -581,24 +599,9 @@ class Mon
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (!this.state.config.pools[pool_id])
|
|
||||||
{
|
|
||||||
// Delete PG history and stats of the deleted pool
|
|
||||||
etcd_request.success.push({ requestDeleteRange: {
|
|
||||||
key: b64(this.config.etcd_prefix+'/pg/history/'+pool_id+'/'),
|
|
||||||
range_end: b64(this.config.etcd_prefix+'/pg/history/'+pool_id+'0'),
|
|
||||||
} });
|
|
||||||
etcd_request.success.push({ requestDeleteRange: {
|
|
||||||
key: b64(this.config.etcd_prefix+'/pg/stats/'+pool_id+'/'),
|
|
||||||
range_end: b64(this.config.etcd_prefix+'/pg/stats/'+pool_id+'0'),
|
|
||||||
} });
|
|
||||||
etcd_request.success.push({ requestDeleteRange: {
|
|
||||||
key: b64(this.config.etcd_prefix+'/pgstats/'+pool_id+'/'),
|
|
||||||
range_end: b64(this.config.etcd_prefix+'/pgstats/'+pool_id+'0'),
|
|
||||||
} });
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
const new_pg_config = JSON.parse(JSON.stringify(this.state.pg.config));
|
const new_pg_config = JSON.parse(JSON.stringify(this.state.pg.config));
|
||||||
|
const etcd_request = { compare: [], success: [] };
|
||||||
for (const pool_id in (new_pg_config||{}).items||{})
|
for (const pool_id in (new_pg_config||{}).items||{})
|
||||||
{
|
{
|
||||||
if (!this.state.config.pools[pool_id])
|
if (!this.state.config.pools[pool_id])
|
||||||
|
@ -659,19 +662,7 @@ class Mon
|
||||||
this.etcd_watch_revision, pool_id, up_osds, osd_tree, real_prev_pgs, pool_res.pgs, pg_history);
|
this.etcd_watch_revision, pool_id, up_osds, osd_tree, real_prev_pgs, pool_res.pgs, pg_history);
|
||||||
}
|
}
|
||||||
new_pg_config.hash = tree_hash;
|
new_pg_config.hash = tree_hash;
|
||||||
const { backfillfull_pools, backfillfull_osds } = sum_object_counts(
|
return await this.save_pg_config(new_pg_config, etcd_request);
|
||||||
{ ...this.state, pg: { ...this.state.pg, config: new_pg_config } }, this.config
|
|
||||||
);
|
|
||||||
if (backfillfull_pools.join(',') != ((this.state.pg.config||{}).backfillfull_pools||[]).join(','))
|
|
||||||
{
|
|
||||||
this.log_backfillfull(backfillfull_osds, backfillfull_pools);
|
|
||||||
}
|
|
||||||
new_pg_config.backfillfull_pools = backfillfull_pools.length ? backfillfull_pools : undefined;
|
|
||||||
if (!await this.save_pg_config(new_pg_config, etcd_request))
|
|
||||||
{
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
return true;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
async save_pg_config(new_pg_config, etcd_request = { compare: [], success: [] })
|
async save_pg_config(new_pg_config, etcd_request = { compare: [], success: [] })
|
||||||
|
@ -743,7 +734,7 @@ class Mon
|
||||||
async update_total_stats()
|
async update_total_stats()
|
||||||
{
|
{
|
||||||
const txn = [];
|
const txn = [];
|
||||||
const { object_counts, object_bytes, backfillfull_pools, backfillfull_osds } = sum_object_counts(this.state, this.config);
|
const { object_counts, object_bytes } = sum_object_counts(this.state, this.config);
|
||||||
let stats = sum_op_stats(this.state.osd, this.prev_stats);
|
let stats = sum_op_stats(this.state.osd, this.prev_stats);
|
||||||
let { inode_stats, seen_pools } = sum_inode_stats(this.state, this.prev_stats);
|
let { inode_stats, seen_pools } = sum_inode_stats(this.state, this.prev_stats);
|
||||||
stats.object_counts = object_counts;
|
stats.object_counts = object_counts;
|
||||||
|
@ -796,27 +787,6 @@ class Mon
|
||||||
{
|
{
|
||||||
await this.etcd.etcd_call('/kv/txn', { success: txn }, this.config.etcd_mon_timeout, 0);
|
await this.etcd.etcd_call('/kv/txn', { success: txn }, this.config.etcd_mon_timeout, 0);
|
||||||
}
|
}
|
||||||
if (!this.recheck_pgs_active &&
|
|
||||||
backfillfull_pools.join(',') != ((this.state.pg.config||{}).backfillfull_pools||[]).join(','))
|
|
||||||
{
|
|
||||||
this.log_backfillfull(backfillfull_osds, backfillfull_pools);
|
|
||||||
const new_pg_config = { ...this.state.pg.config, backfillfull_pools: backfillfull_pools.length ? backfillfull_pools : undefined };
|
|
||||||
await this.save_pg_config(new_pg_config);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
log_backfillfull(osds, pools)
|
|
||||||
{
|
|
||||||
for (const osd in osds)
|
|
||||||
{
|
|
||||||
const bf = osds[osd];
|
|
||||||
console.log('OSD '+osd+' may fill up during rebalance: capacity '+(bf.cap/1024n/1024n)+
|
|
||||||
' MB, target user data '+(bf.clean/1024n/1024n)+' MB');
|
|
||||||
}
|
|
||||||
console.log(
|
|
||||||
(pools.length ? 'Pool(s) '+pools.join(', ') : 'No pools')+
|
|
||||||
' are backfillfull now, applying rebalance configuration'
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
schedule_update_stats()
|
schedule_update_stats()
|
||||||
|
@ -828,21 +798,7 @@ class Mon
|
||||||
this.stats_timer = setTimeout(() =>
|
this.stats_timer = setTimeout(() =>
|
||||||
{
|
{
|
||||||
this.stats_timer = null;
|
this.stats_timer = null;
|
||||||
if (this.updating_total_stats)
|
|
||||||
{
|
|
||||||
this.schedule_update_stats();
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
this.updating_total_stats = true;
|
|
||||||
try
|
|
||||||
{
|
|
||||||
this.update_total_stats().catch(console.error);
|
this.update_total_stats().catch(console.error);
|
||||||
}
|
|
||||||
catch (e)
|
|
||||||
{
|
|
||||||
console.error(e);
|
|
||||||
}
|
|
||||||
this.updating_total_stats = false;
|
|
||||||
}, this.config.mon_stats_timeout);
|
}, this.config.mon_stats_timeout);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
{
|
{
|
||||||
"name": "vitastor-mon",
|
"name": "vitastor-mon",
|
||||||
"version": "1.9.3",
|
"version": "1.8.0",
|
||||||
"description": "Vitastor SDS monitor service",
|
"description": "Vitastor SDS monitor service",
|
||||||
"main": "mon-main.js",
|
"main": "mon-main.js",
|
||||||
"scripts": {
|
"scripts": {
|
||||||
|
|
39
mon/stats.js
39
mon/stats.js
|
@ -109,8 +109,6 @@ function sum_object_counts(state, global_config)
|
||||||
pgstats[pool_id] = { ...(state.pg.stats[pool_id] || {}), ...(pgstats[pool_id] || {}) };
|
pgstats[pool_id] = { ...(state.pg.stats[pool_id] || {}), ...(pgstats[pool_id] || {}) };
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
const pool_per_osd = {};
|
|
||||||
const clean_per_osd = {};
|
|
||||||
for (const pool_id in pgstats)
|
for (const pool_id in pgstats)
|
||||||
{
|
{
|
||||||
let object_size = 0;
|
let object_size = 0;
|
||||||
|
@ -145,45 +143,10 @@ function sum_object_counts(state, global_config)
|
||||||
object_bytes[k] += BigInt(st[k+'_count']) * object_size;
|
object_bytes[k] += BigInt(st[k+'_count']) * object_size;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (st.object_count)
|
|
||||||
{
|
|
||||||
for (const pg_osd of (((state.pg.config.items||{})[pool_id]||{})[pg_num]||{}).osd_set||[])
|
|
||||||
{
|
|
||||||
if (!(pg_osd in clean_per_osd))
|
|
||||||
{
|
|
||||||
clean_per_osd[pg_osd] = 0n;
|
|
||||||
}
|
|
||||||
clean_per_osd[pg_osd] += BigInt(st.object_count);
|
|
||||||
pool_per_osd[pg_osd] = pool_per_osd[pg_osd]||{};
|
|
||||||
pool_per_osd[pg_osd][pool_id] = true;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
return { object_counts, object_bytes };
|
||||||
}
|
|
||||||
// If clean_per_osd[osd] is larger than osd capacity then it will fill up during rebalance
|
|
||||||
let backfillfull_pools = {};
|
|
||||||
let backfillfull_osds = {};
|
|
||||||
for (const osd in clean_per_osd)
|
|
||||||
{
|
|
||||||
const st = state.osd.stats[osd];
|
|
||||||
if (!st || !st.size || !st.data_block_size)
|
|
||||||
{
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
let cap = BigInt(st.size)/BigInt(st.data_block_size);
|
|
||||||
cap = cap * BigInt((global_config.osd_backfillfull_ratio||0.99)*1000000) / 1000000n;
|
|
||||||
if (cap < clean_per_osd[osd])
|
|
||||||
{
|
|
||||||
backfillfull_osds[osd] = { cap: BigInt(st.size), clean: clean_per_osd[osd]*BigInt(st.data_block_size) };
|
|
||||||
for (const pool_id in pool_per_osd[osd])
|
|
||||||
{
|
|
||||||
backfillfull_pools[pool_id] = true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
backfillfull_pools = Object.keys(backfillfull_pools).sort();
|
|
||||||
return { object_counts, object_bytes, backfillfull_pools, backfillfull_osds };
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// sum_inode_stats(this.state, this.prev_stats)
|
// sum_inode_stats(this.state, this.prev_stats)
|
||||||
|
|
|
@ -3,9 +3,7 @@
|
||||||
set -e
|
set -e
|
||||||
|
|
||||||
reapply_patch() {
|
reapply_patch() {
|
||||||
if ! [[ -e $1 ]]; then
|
if ! patch -f --dry-run -F 0 -R $1 < $2 >/dev/null; then
|
||||||
echo "$1 does not exist, OpenNebula is not installed"
|
|
||||||
elif ! patch -f --dry-run -F 0 -R $1 < $2 >/dev/null; then
|
|
||||||
already_applied=0
|
already_applied=0
|
||||||
if ! patch --no-backup-if-mismatch -r - -F 0 -f $1 < $2; then
|
if ! patch --no-backup-if-mismatch -r - -F 0 -f $1 < $2; then
|
||||||
applied_ok=0
|
applied_ok=0
|
||||||
|
@ -17,13 +15,8 @@ echo "Reapplying Vitastor patches to OpenNebula's oned.conf, vmm_execrc and down
|
||||||
already_applied=1
|
already_applied=1
|
||||||
applied_ok=1
|
applied_ok=1
|
||||||
reapply_patch /var/lib/one/remotes/datastore/downloader.sh /var/lib/one/remotes/datastore/vitastor/downloader-vitastor.sh.diff
|
reapply_patch /var/lib/one/remotes/datastore/downloader.sh /var/lib/one/remotes/datastore/vitastor/downloader-vitastor.sh.diff
|
||||||
|
reapply_patch /etc/one/oned.conf /var/lib/one/remotes/datastore/vitastor/oned.conf.diff
|
||||||
reapply_patch /etc/one/vmm_exec/vmm_execrc /var/lib/one/remotes/datastore/vitastor/vmm_execrc.diff
|
reapply_patch /etc/one/vmm_exec/vmm_execrc /var/lib/one/remotes/datastore/vitastor/vmm_execrc.diff
|
||||||
if [[ -e /etc/one/oned.conf ]]; then
|
|
||||||
if ! /var/lib/one/remotes/datastore/vitastor/patch-oned-conf.py /etc/one/oned.conf; then
|
|
||||||
applied_ok=0
|
|
||||||
already_applied=0
|
|
||||||
fi
|
|
||||||
fi
|
|
||||||
if [[ "$already_applied" = 1 ]]; then
|
if [[ "$already_applied" = 1 ]]; then
|
||||||
echo "OK: Vitastor OpenNebula patches are already applied"
|
echo "OK: Vitastor OpenNebula patches are already applied"
|
||||||
elif [[ "$applied_ok" = 1 ]]; then
|
elif [[ "$applied_ok" = 1 ]]; then
|
||||||
|
|
|
@ -54,20 +54,20 @@ index be02d646a8..27f876ec36 100644
|
||||||
TM_MAD_CONF = [
|
TM_MAD_CONF = [
|
||||||
NAME = "iscsi_libvirt", LN_TARGET = "NONE", CLONE_TARGET = "SELF", SHARED = "YES",
|
NAME = "iscsi_libvirt", LN_TARGET = "NONE", CLONE_TARGET = "SELF", SHARED = "YES",
|
||||||
DS_MIGRATE = "NO", DRIVER = "raw"
|
DS_MIGRATE = "NO", DRIVER = "raw"
|
||||||
@@ -1263,9 +1274,16 @@ DS_MAD_CONF = [
|
@@ -1219,9 +1230,16 @@ DS_MAD_CONF = [
|
||||||
NAME = "ceph",
|
NAME = "ceph",
|
||||||
REQUIRED_ATTRS = "DISK_TYPE,BRIDGE_LIST",
|
REQUIRED_ATTRS = "DISK_TYPE,BRIDGE_LIST",
|
||||||
PERSISTENT_ONLY = "NO",
|
PERSISTENT_ONLY = "NO",
|
||||||
MARKETPLACE_ACTIONS = "export"
|
MARKETPLACE_ACTIONS = "export"
|
||||||
+]
|
]
|
||||||
+
|
|
||||||
+DS_MAD_CONF = [
|
+DS_MAD_CONF = [
|
||||||
+ NAME = "vitastor",
|
+ NAME = "vitastor",
|
||||||
+ REQUIRED_ATTRS = "DISK_TYPE,BRIDGE_LIST",
|
+ REQUIRED_ATTRS = "DISK_TYPE,BRIDGE_LIST",
|
||||||
+ PERSISTENT_ONLY = "NO",
|
+ PERSISTENT_ONLY = "NO",
|
||||||
+ MARKETPLACE_ACTIONS = "export"
|
+ MARKETPLACE_ACTIONS = "export"
|
||||||
]
|
+]
|
||||||
|
+
|
||||||
DS_MAD_CONF = [
|
DS_MAD_CONF = [
|
||||||
NAME = "dev", REQUIRED_ATTRS = "DISK_TYPE", PERSISTENT_ONLY = "YES"
|
NAME = "dev", REQUIRED_ATTRS = "DISK_TYPE", PERSISTENT_ONLY = "YES"
|
||||||
]
|
]
|
||||||
|
|
|
@ -1,115 +0,0 @@
|
||||||
#!/usr/bin/env python3
|
|
||||||
# Patch /etc/one/oned.conf for Vitastor support
|
|
||||||
# -s = also enable save.vitastor/restore.vitastor overrides
|
|
||||||
|
|
||||||
import re
|
|
||||||
import os
|
|
||||||
import sys
|
|
||||||
|
|
||||||
class Fixer:
|
|
||||||
save_restore = 0
|
|
||||||
|
|
||||||
def require_sub_cb(self, m, cb):
|
|
||||||
self.found = 1
|
|
||||||
return cb(m)
|
|
||||||
|
|
||||||
def require_sub(self, regexp, cb, text, error):
|
|
||||||
self.found = 0
|
|
||||||
new_text = re.sub(regexp, lambda m: self.require_sub_cb(m, cb), text)
|
|
||||||
if not self.found and error:
|
|
||||||
self.errors.append(error)
|
|
||||||
return new_text
|
|
||||||
|
|
||||||
def fix(self, oned_conf):
|
|
||||||
self.errors = []
|
|
||||||
self.kvm_found = 0
|
|
||||||
oned_conf = self.require_sub(r'((?:^|\n)[ \t]*VM_MAD\s*=\s*\[)([^\]]+)\]', lambda m: m.group(1)+self.fix_vm_mad(m.group(2))+']', oned_conf, 'VM_MAD not found')
|
|
||||||
if not self.kvm_found:
|
|
||||||
self.errors.append("VM_MAD[NAME=kvm].ARGUMENTS not found")
|
|
||||||
oned_conf = self.require_sub(r'((?:^|\n)[ \t]*TM_MAD\s*=\s*\[)([^\]]+)\]', lambda m: m.group(1)+self.fix_tm_mad(m.group(2))+']', oned_conf, 'TM_MAD not found')
|
|
||||||
oned_conf = self.require_sub(r'((?:^|\n)[ \t]*DATASTORE_MAD\s*=\s*\[)([^\]]+)\]', lambda m: m.group(1)+self.fix_datastore_mad(m.group(2))+']', oned_conf, 'DATASTORE_MAD not found')
|
|
||||||
if oned_conf[-1:] != '\n':
|
|
||||||
oned_conf += '\n'
|
|
||||||
if not re.compile(r'(^|\n)[ \t]*INHERIT_DATASTORE_ATTR\s*=\s*"VITASTOR_CONF"').search(oned_conf):
|
|
||||||
oned_conf += '\nINHERIT_DATASTORE_ATTR="VITASTOR_CONF"\n'
|
|
||||||
if not re.compile(r'(^|\n)[ \t]*INHERIT_DATASTORE_ATTR\s*=\s*"IMAGE_PREFIX"').search(oned_conf):
|
|
||||||
oned_conf += '\nINHERIT_DATASTORE_ATTR="IMAGE_PREFIX"\n'
|
|
||||||
if not re.compile(r'(^|\n)[ \t]*TM_MAD_CONF\s*=\s*\[[^\]]*NAME\s*=\s*"vitastor"').search(oned_conf):
|
|
||||||
oned_conf += ('\nTM_MAD_CONF = [\n'+
|
|
||||||
' NAME = "vitastor", LN_TARGET = "NONE", CLONE_TARGET = "SELF", SHARED = "YES",\n'+
|
|
||||||
' DS_MIGRATE = "NO", DRIVER = "raw", ALLOW_ORPHANS="format",\n'+
|
|
||||||
' TM_MAD_SYSTEM = "ssh,shared", LN_TARGET_SSH = "SYSTEM", CLONE_TARGET_SSH = "SYSTEM",\n'+
|
|
||||||
' DISK_TYPE_SSH = "FILE", LN_TARGET_SHARED = "NONE",\n'+
|
|
||||||
' CLONE_TARGET_SHARED = "SELF", DISK_TYPE_SHARED = "FILE"\n'+
|
|
||||||
']\n')
|
|
||||||
if not re.compile(r'(^|\n)[ \t]*DS_MAD_CONF\s*=\s*\[[^\]]*NAME\s*=\s*"vitastor"').search(oned_conf):
|
|
||||||
oned_conf += ('\nDS_MAD_CONF = [\n'+
|
|
||||||
' NAME = "vitastor",\n'+
|
|
||||||
' REQUIRED_ATTRS = "DISK_TYPE,BRIDGE_LIST",\n'+
|
|
||||||
' PERSISTENT_ONLY = "NO",\n'+
|
|
||||||
' MARKETPLACE_ACTIONS = "export"\n'+
|
|
||||||
']\n')
|
|
||||||
return oned_conf
|
|
||||||
|
|
||||||
def fix_vm_mad(self, vm_mad_params):
|
|
||||||
if re.compile(r'\bNAME\s*=\s*"kvm"').search(vm_mad_params):
|
|
||||||
vm_mad_params = re.sub(r'\b(ARGUMENTS\s*=\s*")([^"]+)"', lambda m: m.group(1)+self.fix_vm_mad_args(m.group(2))+'"', vm_mad_params)
|
|
||||||
self.kvm_found = 1
|
|
||||||
return vm_mad_params
|
|
||||||
|
|
||||||
def fix_vm_mad_args(self, args):
|
|
||||||
args = self.fix_vm_mad_override(args, 'deploy')
|
|
||||||
if self.save_restore:
|
|
||||||
args = self.fix_vm_mad_override(args, 'save')
|
|
||||||
args = self.fix_vm_mad_override(args, 'restore')
|
|
||||||
return args
|
|
||||||
|
|
||||||
def fix_vm_mad_override(self, args, override):
|
|
||||||
m = re.compile(r'-l (\S+)').search(args)
|
|
||||||
if m and re.compile(override+'='+override+'.vitastor').search(m.group(1)):
|
|
||||||
return args
|
|
||||||
elif m and re.compile(override+'=').search(m.group(1)):
|
|
||||||
self.errors.append(override+"= is already overridden in -l option in VM_MAD[NAME=kvm].ARGUMENTS")
|
|
||||||
return args
|
|
||||||
elif m:
|
|
||||||
return self.require_sub(r'-l (\S+)', lambda m: '-l '+m.group(1)+','+override+'='+override+'.vitastor', args, '-l option not found in VM_MAD[NAME=kvm].ARGUMENTS')
|
|
||||||
else:
|
|
||||||
return args+' -l '+override+'='+override+'.vitastor'
|
|
||||||
|
|
||||||
def fix_tm_mad(self, params):
|
|
||||||
return self.require_sub(r'\b(ARGUMENTS\s*=\s*")([^"]+)"', lambda m: m.group(1)+self.fix_tm_mad_args('d', m.group(2), "TM_MAD")+'"', params, "TM_MAD.ARGUMENTS not found")
|
|
||||||
|
|
||||||
def fix_tm_mad_args(self, opt, args, v):
|
|
||||||
return self.require_sub('(-'+opt+r') (\S+)', lambda m: self.fix_tm_mad_arg(m), args, "-"+opt+" option not found in "+v+".ARGUMENTS")
|
|
||||||
|
|
||||||
def fix_tm_mad_arg(self, m):
|
|
||||||
a = m.group(2).split(',')
|
|
||||||
if 'vitastor' not in a:
|
|
||||||
a += [ 'vitastor' ]
|
|
||||||
return m.group(1)+' '+(','.join(a))
|
|
||||||
|
|
||||||
def fix_datastore_mad(self, params):
|
|
||||||
params = self.require_sub(r'\b(ARGUMENTS\s*=\s*")([^"]+)"', lambda m: m.group(1)+self.fix_tm_mad_args('d', m.group(2), "DATASTORE_MAD")+'"', params, "DATASTORE_MAD.ARGUMENTS not found")
|
|
||||||
return self.require_sub(r'\b(ARGUMENTS\s*=\s*")([^"]+)"', lambda m: m.group(1)+self.fix_tm_mad_args('s', m.group(2), "DATASTORE_MAD")+'"', params, "")
|
|
||||||
|
|
||||||
fixer = Fixer()
|
|
||||||
oned_conf_file = ''
|
|
||||||
for arg in sys.argv[1:]:
|
|
||||||
if arg == '-s':
|
|
||||||
fixer.save_restore = 1
|
|
||||||
else:
|
|
||||||
oned_conf_file = arg
|
|
||||||
break
|
|
||||||
if not oned_conf_file:
|
|
||||||
sys.stderr.write("USAGE: ./patch-oned-conf.py [-s] /etc/one/oned.conf\n-s means also enable save.vitastor/restore.vitastor overrides\n")
|
|
||||||
sys.exit(1)
|
|
||||||
with open(oned_conf_file, 'r') as fd:
|
|
||||||
oned_conf = fd.read()
|
|
||||||
new_conf = fixer.fix(oned_conf)
|
|
||||||
if new_conf != oned_conf:
|
|
||||||
os.rename(oned_conf_file, oned_conf_file+'.bak')
|
|
||||||
with open(oned_conf_file, 'w') as fd:
|
|
||||||
fd.write(new_conf)
|
|
||||||
if len(fixer.errors) > 0:
|
|
||||||
sys.stderr.write("ERROR: Failed to patch "+oned_conf_file+", patch it manually. Errors:\n- "+('\n- '.join(fixer.errors))+'\n')
|
|
||||||
sys.exit(1)
|
|
|
@ -4,15 +4,12 @@
|
||||||
# Copyright (c) Vitaliy Filippov, 2024+
|
# Copyright (c) Vitaliy Filippov, 2024+
|
||||||
# License: Apache-2.0 http://www.apache.org/licenses/LICENSE-2.0
|
# License: Apache-2.0 http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
|
||||||
set -e
|
|
||||||
|
|
||||||
DRIVER_PATH=$(dirname $0)
|
DRIVER_PATH=$(dirname $0)
|
||||||
DEP_FILE=$1
|
DEP_FILE=$1
|
||||||
DEP_FILE_LOCATION=$(dirname $DEP_FILE)
|
DEP_FILE_LOCATION=$(dirname $DEP_FILE)
|
||||||
HOST=$2
|
|
||||||
|
|
||||||
cat > $DEP_FILE
|
cat > $DEP_FILE
|
||||||
|
|
||||||
python3 $DRIVER_PATH/deploy_vitastor.py $DEP_FILE $DEP_FILE_LOCATION/vm.xml
|
python3 $DRIVER_PATH/deploy_vitastor.py $DEP_FILE $DEP_FILE_LOCATION/vm.xml
|
||||||
|
|
||||||
cat "$DEP_FILE" | ssh "$HOST" "'${SCRIPTS_REMOTE_DIR:-/var/tmp/one}/vmm/kvm/deploy' '$DEP_FILE'"
|
cat $DEP_FILE | $DRIVER_PATH/deploy $@
|
||||||
|
|
|
@ -54,4 +54,5 @@ for disk in dep.findall('./devices/disk[@type="file"]'):
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
print("Error: {}".format(e), file=stderr)
|
print("Error: {}".format(e), file=stderr)
|
||||||
|
|
||||||
ET.ElementTree(dep).write(dep_file)
|
if changed:
|
||||||
|
ET.ElementTree(dep).write(dep_file)
|
||||||
|
|
|
@ -10,7 +10,7 @@ source $DRIVER_PATH/../../etc/vmm/kvm/kvmrc
|
||||||
source $DRIVER_PATH/../../scripts_common.sh
|
source $DRIVER_PATH/../../scripts_common.sh
|
||||||
|
|
||||||
FILE=$1
|
FILE=$1
|
||||||
DST_HOST=$2
|
HOST=$2
|
||||||
DEPLOY_ID=$3
|
DEPLOY_ID=$3
|
||||||
VM_ID=$4
|
VM_ID=$4
|
||||||
DS_ID=$5
|
DS_ID=$5
|
||||||
|
@ -33,8 +33,7 @@ fi
|
||||||
|
|
||||||
SRC_IMAGE="${IMAGE_PREFIX}-sys-${VM_ID}-checkpoint"
|
SRC_IMAGE="${IMAGE_PREFIX}-sys-${VM_ID}-checkpoint"
|
||||||
|
|
||||||
ssh_exec_and_log "$DST_HOST" "$CLI dd iimg=$SRC_IMAGE of=$FILE" "Error exporting checkpoint into from $SRC_IMAGE to $FILE"
|
exec_and_log "$CLI dd iimg=$SRC_IMAGE of=$FILE" "Error exporting checkpoint into from $SRC_IMAGE to $FILE"
|
||||||
ssh_exec_and_log "$DST_HOST" "$CLI rm $SRC_IMAGE" "Error removing checkpoint $SRC_IMAGE"
|
exec_and_log "$CLI rm $SRC_IMAGE" "Error removing checkpoint $SRC_IMAGE"
|
||||||
|
|
||||||
set -e
|
"$DRIVER_PATH"/restore $@
|
||||||
ssh "$DST_HOST" "'${SCRIPTS_REMOTE_DIR:-/var/tmp/one}/vmm/kvm/restore' $@"
|
|
||||||
|
|
|
@ -11,14 +11,11 @@ source $DRIVER_PATH/../../scripts_common.sh
|
||||||
|
|
||||||
DEPLOY_ID=$1
|
DEPLOY_ID=$1
|
||||||
FILE=$2
|
FILE=$2
|
||||||
SRC_HOST=$3
|
|
||||||
VM_ID=$4
|
VM_ID=$4
|
||||||
DS_ID=$5
|
DS_ID=$5
|
||||||
|
|
||||||
set -e
|
rm -f "$FILE"
|
||||||
ssh "$SRC_HOST" 'rm -f "$FILE"'
|
"$DRIVER_PATH"/save $@
|
||||||
ssh "$SRC_HOST" "'${SCRIPTS_REMOTE_DIR:-/var/tmp/one}/vmm/kvm/save' $@"
|
|
||||||
set +e
|
|
||||||
|
|
||||||
XPATH="${DRIVER_PATH}/../../datastore/xpath.rb --stdin"
|
XPATH="${DRIVER_PATH}/../../datastore/xpath.rb --stdin"
|
||||||
|
|
||||||
|
@ -45,7 +42,7 @@ fi
|
||||||
|
|
||||||
DST_IMAGE="${IMAGE_PREFIX}-sys-${VM_ID}-checkpoint"
|
DST_IMAGE="${IMAGE_PREFIX}-sys-${VM_ID}-checkpoint"
|
||||||
|
|
||||||
ssh_exec_and_log "$SRC_HOST" "$CLI dd if=$FILE oimg=$DST_IMAGE conv=trunc" "Error importing checkpoint into $DST_IMAGE"
|
exec_and_log "$CLI dd if=$FILE oimg=$DST_IMAGE conv=trunc" "Error importing checkpoint into $DST_IMAGE"
|
||||||
ssh_exec_and_log "$SRC_HOST" "$RM -f $FILE" "Error removing checkpoint ($FILE)"
|
exec_and_log "$RM -f $FILE" "Error removing checkpoint ($FILE)"
|
||||||
|
|
||||||
exit 0
|
exit 0
|
||||||
|
|
|
@ -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
|
||||||
|
|
||||||
VITASTOR_VERSION = '1.9.3'
|
VITASTOR_VERSION = '1.8.0'
|
||||||
|
|
||||||
LOG = logging.getLogger(__name__)
|
LOG = logging.getLogger(__name__)
|
||||||
|
|
||||||
|
|
|
@ -306,7 +306,7 @@ index e5ff653a60..884ecc79ea 100644
|
||||||
+ etcd = virBufferContentAndReset(&buf);
|
+ etcd = virBufferContentAndReset(&buf);
|
||||||
+ }
|
+ }
|
||||||
+
|
+
|
||||||
+ if (virJSONValueObjectAdd(&ret,
|
+ if (virJSONValueObjectCreate(&ret,
|
||||||
+ "S:etcd-host", etcd,
|
+ "S:etcd-host", etcd,
|
||||||
+ "S:etcd-prefix", src->query,
|
+ "S:etcd-prefix", src->query,
|
||||||
+ "S:config-path", src->configFile,
|
+ "S:config-path", src->configFile,
|
||||||
|
|
|
@ -1,193 +0,0 @@
|
||||||
Index: pve-qemu-kvm-9.0.0/block/meson.build
|
|
||||||
===================================================================
|
|
||||||
--- pve-qemu-kvm-9.0.0.orig/block/meson.build
|
|
||||||
+++ pve-qemu-kvm-9.0.0/block/meson.build
|
|
||||||
@@ -126,6 +126,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-9.0.0/meson.build
|
|
||||||
===================================================================
|
|
||||||
--- pve-qemu-kvm-9.0.0.orig/meson.build
|
|
||||||
+++ pve-qemu-kvm-9.0.0/meson.build
|
|
||||||
@@ -1452,6 +1452,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'))
|
|
||||||
+ 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
|
|
||||||
@@ -2254,6 +2274,7 @@ endif
|
|
||||||
config_host_data.set('CONFIG_OPENGL', opengl.found())
|
|
||||||
config_host_data.set('CONFIG_PLUGIN', get_option('plugins'))
|
|
||||||
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_RELOCATABLE', get_option('relocatable'))
|
|
||||||
config_host_data.set('CONFIG_SAFESTACK', get_option('safe_stack'))
|
|
||||||
@@ -4454,6 +4475,7 @@ summary_info += {'fdt support': fd
|
|
||||||
summary_info += {'libcap-ng support': libcap_ng}
|
|
||||||
summary_info += {'bpf support': libbpf}
|
|
||||||
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-9.0.0/meson_options.txt
|
|
||||||
===================================================================
|
|
||||||
--- pve-qemu-kvm-9.0.0.orig/meson_options.txt
|
|
||||||
+++ pve-qemu-kvm-9.0.0/meson_options.txt
|
|
||||||
@@ -194,6 +194,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-9.0.0/qapi/block-core.json
|
|
||||||
===================================================================
|
|
||||||
--- pve-qemu-kvm-9.0.0.orig/qapi/block-core.json
|
|
||||||
+++ pve-qemu-kvm-9.0.0/qapi/block-core.json
|
|
||||||
@@ -3481,7 +3481,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' },
|
|
||||||
@@ -4591,6 +4591,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.
|
|
||||||
@@ -5053,6 +5075,7 @@
|
|
||||||
'throttle': 'BlockdevOptionsThrottle',
|
|
||||||
'vdi': 'BlockdevOptionsGenericFormat',
|
|
||||||
'vhdx': 'BlockdevOptionsGenericFormat',
|
|
||||||
+ 'vitastor': 'BlockdevOptionsVitastor',
|
|
||||||
'virtio-blk-vfio-pci':
|
|
||||||
{ 'type': 'BlockdevOptionsVirtioBlkVfioPci',
|
|
||||||
'if': 'CONFIG_BLKIO' },
|
|
||||||
@@ -5498,6 +5521,20 @@
|
|
||||||
'*encrypt' : 'RbdEncryptionCreateOptions' } }
|
|
||||||
|
|
||||||
##
|
|
||||||
+# @BlockdevCreateOptionsVitastor:
|
|
||||||
+#
|
|
||||||
+# Driver specific image creation options for Vitastor.
|
|
||||||
+#
|
|
||||||
+# @location: Where to store the new image file. This location cannot
|
|
||||||
+# point to a snapshot.
|
|
||||||
+#
|
|
||||||
+# @size: Size of the virtual disk in bytes
|
|
||||||
+##
|
|
||||||
+{ 'struct': 'BlockdevCreateOptionsVitastor',
|
|
||||||
+ 'data': { 'location': 'BlockdevOptionsVitastor',
|
|
||||||
+ 'size': 'size' } }
|
|
||||||
+
|
|
||||||
+##
|
|
||||||
# @BlockdevVmdkSubformat:
|
|
||||||
#
|
|
||||||
# Subformat options for VMDK images
|
|
||||||
@@ -5719,6 +5753,7 @@
|
|
||||||
'ssh': 'BlockdevCreateOptionsSsh',
|
|
||||||
'vdi': 'BlockdevCreateOptionsVdi',
|
|
||||||
'vhdx': 'BlockdevCreateOptionsVhdx',
|
|
||||||
+ 'vitastor': 'BlockdevCreateOptionsVitastor',
|
|
||||||
'vmdk': 'BlockdevCreateOptionsVmdk',
|
|
||||||
'vpc': 'BlockdevCreateOptionsVpc'
|
|
||||||
} }
|
|
||||||
Index: pve-qemu-kvm-9.0.0/scripts/ci/org.centos/stream/8/x86_64/configure
|
|
||||||
===================================================================
|
|
||||||
--- pve-qemu-kvm-9.0.0.orig/scripts/ci/org.centos/stream/8/x86_64/configure
|
|
||||||
+++ pve-qemu-kvm-9.0.0/scripts/ci/org.centos/stream/8/x86_64/configure
|
|
||||||
@@ -30,7 +30,7 @@
|
|
||||||
--with-suffix="qemu-kvm" \
|
|
||||||
--firmwarepath=/usr/share/qemu-firmware \
|
|
||||||
--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 \
|
|
||||||
@@ -176,6 +176,7 @@
|
|
||||||
--enable-opengl \
|
|
||||||
--enable-pie \
|
|
||||||
--enable-rbd \
|
|
||||||
+--enable-vitastor \
|
|
||||||
--enable-rdma \
|
|
||||||
--enable-seccomp \
|
|
||||||
--enable-snappy \
|
|
||||||
Index: pve-qemu-kvm-9.0.0/scripts/meson-buildoptions.sh
|
|
||||||
===================================================================
|
|
||||||
--- pve-qemu-kvm-9.0.0.orig/scripts/meson-buildoptions.sh
|
|
||||||
+++ pve-qemu-kvm-9.0.0/scripts/meson-buildoptions.sh
|
|
||||||
@@ -168,6 +168,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" ' rutabaga-gfx rutabaga_gfx support'
|
|
||||||
@@ -445,6 +446,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-relocatable) printf "%s" -Drelocatable=true ;;
|
|
|
@ -1,172 +0,0 @@
|
||||||
diff --git a/block/meson.build b/block/meson.build
|
|
||||||
index f1262ec2ba..3cf3e23f16 100644
|
|
||||||
--- a/block/meson.build
|
|
||||||
+++ b/block/meson.build
|
|
||||||
@@ -114,6 +114,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 fbda17c987..3edac22aff 100644
|
|
||||||
--- a/meson.build
|
|
||||||
+++ b/meson.build
|
|
||||||
@@ -1510,6 +1510,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'))
|
|
||||||
+ 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
|
|
||||||
@@ -2351,6 +2371,7 @@ endif
|
|
||||||
config_host_data.set('CONFIG_OPENGL', opengl.found())
|
|
||||||
config_host_data.set('CONFIG_PLUGIN', get_option('plugins'))
|
|
||||||
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_RELOCATABLE', get_option('relocatable'))
|
|
||||||
config_host_data.set('CONFIG_SAFESTACK', get_option('safe_stack'))
|
|
||||||
@@ -4510,6 +4531,7 @@ summary_info += {'fdt support': fdt_opt == 'internal' ? 'internal' : fdt}
|
|
||||||
summary_info += {'libcap-ng support': libcap_ng}
|
|
||||||
summary_info += {'bpf support': libbpf}
|
|
||||||
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 0269fa0f16..4740ffdc27 100644
|
|
||||||
--- a/meson_options.txt
|
|
||||||
+++ b/meson_options.txt
|
|
||||||
@@ -194,6 +194,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 aa40d44f1d..bbee6a0e9c 100644
|
|
||||||
--- a/qapi/block-core.json
|
|
||||||
+++ b/qapi/block-core.json
|
|
||||||
@@ -3203,7 +3203,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' },
|
|
||||||
@@ -4286,6 +4286,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:
|
|
||||||
#
|
|
||||||
@@ -4742,6 +4764,7 @@
|
|
||||||
'throttle': 'BlockdevOptionsThrottle',
|
|
||||||
'vdi': 'BlockdevOptionsGenericFormat',
|
|
||||||
'vhdx': 'BlockdevOptionsGenericFormat',
|
|
||||||
+ 'vitastor': 'BlockdevOptionsVitastor',
|
|
||||||
'virtio-blk-vfio-pci':
|
|
||||||
{ 'type': 'BlockdevOptionsVirtioBlkVfioPci',
|
|
||||||
'if': 'CONFIG_BLKIO' },
|
|
||||||
@@ -5183,6 +5206,20 @@
|
|
||||||
'*cluster-size' : 'size',
|
|
||||||
'*encrypt' : 'RbdEncryptionCreateOptions' } }
|
|
||||||
|
|
||||||
+##
|
|
||||||
+# @BlockdevCreateOptionsVitastor:
|
|
||||||
+#
|
|
||||||
+# Driver specific image creation options for Vitastor.
|
|
||||||
+#
|
|
||||||
+# @location: Where to store the new image file. This location cannot
|
|
||||||
+# point to a snapshot.
|
|
||||||
+#
|
|
||||||
+# @size: Size of the virtual disk in bytes
|
|
||||||
+##
|
|
||||||
+{ 'struct': 'BlockdevCreateOptionsVitastor',
|
|
||||||
+ 'data': { 'location': 'BlockdevOptionsVitastor',
|
|
||||||
+ 'size': 'size' } }
|
|
||||||
+
|
|
||||||
##
|
|
||||||
# @BlockdevVmdkSubformat:
|
|
||||||
#
|
|
||||||
@@ -5405,6 +5442,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 c97079a38c..4623f552ec 100644
|
|
||||||
--- a/scripts/meson-buildoptions.sh
|
|
||||||
+++ b/scripts/meson-buildoptions.sh
|
|
||||||
@@ -168,6 +168,7 @@ meson_options_help() {
|
|
||||||
printf "%s\n" ' qga-vss build QGA VSS support (broken with MinGW)'
|
|
||||||
printf "%s\n" ' qpl Query Processing Library support'
|
|
||||||
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" ' rutabaga-gfx rutabaga_gfx support'
|
|
||||||
@@ -444,6 +445,8 @@ _meson_option_parse() {
|
|
||||||
--disable-qpl) printf "%s" -Dqpl=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-rdma) printf "%s" -Drdma=enabled ;;
|
|
||||||
--disable-rdma) printf "%s" -Drdma=disabled ;;
|
|
||||||
--enable-relocatable) printf "%s" -Drelocatable=true ;;
|
|
|
@ -1,11 +1,11 @@
|
||||||
Name: vitastor
|
Name: vitastor
|
||||||
Version: 1.9.3
|
Version: 1.8.0
|
||||||
Release: 1%{?dist}
|
Release: 1%{?dist}
|
||||||
Summary: Vitastor, a fast software-defined clustered block storage
|
Summary: Vitastor, a fast software-defined clustered block storage
|
||||||
|
|
||||||
License: Vitastor Network Public License 1.1
|
License: Vitastor Network Public License 1.1
|
||||||
URL: https://vitastor.io/
|
URL: https://vitastor.io/
|
||||||
Source0: vitastor-1.9.3.el7.tar.gz
|
Source0: vitastor-1.8.0.el7.tar.gz
|
||||||
|
|
||||||
BuildRequires: liburing-devel >= 0.6
|
BuildRequires: liburing-devel >= 0.6
|
||||||
BuildRequires: gperftools-devel
|
BuildRequires: gperftools-devel
|
||||||
|
@ -202,8 +202,4 @@ chown vitastor:vitastor /var/lib/vitastor
|
||||||
/var/lib/one/remotes/datastore/vitastor/install.sh
|
/var/lib/one/remotes/datastore/vitastor/install.sh
|
||||||
|
|
||||||
|
|
||||||
# Turn off the brp-python-bytecompile script
|
|
||||||
%global __os_install_post %(echo '%{__os_install_post}' | sed -e 's!/usr/lib[^[:space:]]*/brp-python-bytecompile[[:space:]].*$!!g')
|
|
||||||
|
|
||||||
|
|
||||||
%changelog
|
%changelog
|
||||||
|
|
|
@ -1,11 +1,11 @@
|
||||||
Name: vitastor
|
Name: vitastor
|
||||||
Version: 1.9.3
|
Version: 1.8.0
|
||||||
Release: 1%{?dist}
|
Release: 1%{?dist}
|
||||||
Summary: Vitastor, a fast software-defined clustered block storage
|
Summary: Vitastor, a fast software-defined clustered block storage
|
||||||
|
|
||||||
License: Vitastor Network Public License 1.1
|
License: Vitastor Network Public License 1.1
|
||||||
URL: https://vitastor.io/
|
URL: https://vitastor.io/
|
||||||
Source0: vitastor-1.9.3.el8.tar.gz
|
Source0: vitastor-1.8.0.el8.tar.gz
|
||||||
|
|
||||||
BuildRequires: liburing-devel >= 0.6
|
BuildRequires: liburing-devel >= 0.6
|
||||||
BuildRequires: gperftools-devel
|
BuildRequires: gperftools-devel
|
||||||
|
@ -199,8 +199,4 @@ chown vitastor:vitastor /var/lib/vitastor
|
||||||
/var/lib/one/remotes/datastore/vitastor/install.sh
|
/var/lib/one/remotes/datastore/vitastor/install.sh
|
||||||
|
|
||||||
|
|
||||||
# Turn off the brp-python-bytecompile script
|
|
||||||
%global __os_install_post %(echo '%{__os_install_post}' | sed -e 's!/usr/lib[^[:space:]]*/brp-python-bytecompile[[:space:]].*$!!g')
|
|
||||||
|
|
||||||
|
|
||||||
%changelog
|
%changelog
|
||||||
|
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue