Compare commits

...

3 Commits

Author SHA1 Message Date
Vitaliy Filippov e732cbea2d WIP Architecture in english
Test / test_dd (push) Successful in 11s Details
Test / test_root_node (push) Successful in 7s Details
Test / test_rebalance_verify_ec (push) Successful in 1m52s Details
Test / test_rebalance_verify_ec_imm (push) Successful in 1m53s Details
Test / test_write_no_same (push) Successful in 8s Details
Test / test_switch_primary (push) Successful in 34s Details
Test / test_write (push) Successful in 30s Details
Test / test_write_xor (push) Successful in 34s Details
Test / test_heal_pg_size_2 (push) Successful in 2m16s Details
Test / test_heal_ec (push) Successful in 2m15s Details
Test / test_heal_antietcd (push) Successful in 2m16s Details
Test / test_heal_csum_32k_dmj (push) Successful in 2m21s Details
Test / test_heal_csum_32k_dj (push) Successful in 2m16s Details
Test / test_heal_csum_4k_dmj (push) Successful in 2m12s Details
Test / test_heal_csum_32k (push) Successful in 2m17s Details
Test / test_heal_csum_4k_dj (push) Successful in 2m10s Details
Test / test_osd_tags (push) Successful in 7s Details
Test / test_snapshot_pool2 (push) Successful in 13s Details
Test / test_enospc (push) Successful in 9s Details
Test / test_enospc_xor (push) Successful in 13s Details
Test / test_enospc_imm (push) Successful in 10s Details
Test / test_enospc_imm_xor (push) Successful in 13s Details
Test / test_scrub (push) Successful in 13s Details
Test / test_scrub_zero_osd_2 (push) Successful in 13s Details
Test / test_scrub_xor (push) Successful in 13s Details
Test / test_scrub_pg_size_3 (push) Successful in 16s Details
Test / test_scrub_pg_size_6_pg_minsize_4_osd_count_6_ec (push) Successful in 15s Details
Test / test_scrub_ec (push) Successful in 13s Details
Test / test_nfs (push) Successful in 13s Details
Test / test_heal_csum_4k (push) Successful in 2m17s Details
2024-11-05 02:43:55 +03:00
Vitaliy Filippov c72e8e649e Support test mode for vitastor-disk
Test / test_dd (push) Successful in 11s Details
Test / test_rebalance_verify_ec (push) Successful in 1m51s Details
Test / test_root_node (push) Successful in 10s Details
Test / test_rebalance_verify_ec_imm (push) Successful in 1m54s Details
Test / test_write_no_same (push) Successful in 7s Details
Test / test_switch_primary (push) Successful in 32s Details
Test / test_write (push) Successful in 32s Details
Test / test_write_xor (push) Successful in 33s Details
Test / test_heal_pg_size_2 (push) Successful in 2m15s Details
Test / test_heal_ec (push) Successful in 2m21s Details
Test / test_heal_antietcd (push) Successful in 2m16s Details
Test / test_heal_csum_32k_dmj (push) Successful in 2m23s Details
Test / test_heal_csum_32k_dj (push) Successful in 2m18s Details
Test / test_heal_csum_32k (push) Successful in 2m18s Details
Test / test_heal_csum_4k_dmj (push) Successful in 2m18s Details
Test / test_osd_tags (push) Successful in 7s Details
Test / test_heal_csum_4k_dj (push) Successful in 2m18s Details
Test / test_snapshot_pool2 (push) Successful in 15s Details
Test / test_enospc (push) Successful in 10s Details
Test / test_enospc_imm (push) Successful in 10s Details
Test / test_enospc_xor (push) Successful in 13s Details
Test / test_enospc_imm_xor (push) Successful in 12s Details
Test / test_scrub (push) Successful in 12s Details
Test / test_scrub_zero_osd_2 (push) Successful in 13s Details
Test / test_scrub_xor (push) Successful in 14s Details
Test / test_scrub_pg_size_3 (push) Successful in 16s Details
Test / test_scrub_pg_size_6_pg_minsize_4_osd_count_6_ec (push) Successful in 14s Details
Test / test_scrub_ec (push) Successful in 14s Details
Test / test_nfs (push) Successful in 12s Details
Test / test_heal_csum_4k (push) Successful in 2m19s Details
2024-11-05 02:43:55 +03:00
Vitaliy Filippov 8bdb3e8786 Write meta/journal to correct device when used in superblock mode 2024-11-05 02:43:55 +03:00
6 changed files with 196 additions and 33 deletions

View File

@ -11,14 +11,136 @@
- [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
- OSD (Object Storage Daemon) is a process that stores data and serves read/write requests. - **Pool** is a container for data that has equal redundancy scheme and disk placement rules.
- PG (Placement Group) is a "shard" of the cluster, group of data stored on one set of replicas. - **PG (Placement Group)** is a "shard" of the cluster, subdivision unit that has its own
- Pool is a container for data that has equal redundancy scheme and placement rules. set of OSDs for data storage.
- Monitor is a separate daemon that watches cluster state and handles failures. - **Failure Domain** is a group of OSDs, from the simultaneous failure of which you are
- Failure Domain is a group of OSDs that you allow to fail. It's "host" by default. protected by Vitastor. Default failure domain is "host" (server), but you choose a
- Placement Tree groups OSDs in a hierarchy to later split them into Failure Domains. larger (for example, a rack of servers) or smaller (a single drive) failure domain
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** incapsulates 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 knows where each data block is stored and connects 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** — утилита для разметки дисков под Vitastor OSD. С её помощью можно
создавать, удалять, менять размеры или перемещать разделы OSD.
## Общий процесс записи и чтения
- В Vitastor хранятся виртуальные диски, также называемые "образы" или "иноды".
- Каждый образ хранится в определённом пуле. Пул определяет параметры хранения образов в нём,
такие, как схему избыточности (репликация или EC — коды коррекции ошибок), домен отказа
и ограничения по выбору OSD для размещения данных образов. См. [Конфигурация пулов](../config/pool.ru.md).
- Каждый образ разбивается на объекты фиксированного размера, равного [block_size](../config/layout-cluster.ru.md#block_size)
(по умолчанию 128 КБ), умноженному на число частей данных для EC или на 1 для реплик.
То есть, например, если в пуле используется схема кодирования 4+2 (4 части данных + 2 чётности),
то при стандартном block_size образы разбиваются на части по 512 КБ.
- Клиентские запросы чтения/записи разделяются на части, соответствующие этим объектам.
- Для каждого объекта определяется номер PG, которой он принадлежит, путём простого взятия
остатка от деления ID образа и смещения на число PG в пуле, которому принадлежит образ.
- Клиент читает информацию о первичном OSD всех PG из etcd. Первичный OSD каждой PG назначается
монитором в процессе работы кластера, вместе с текущим целевым набором OSD этой PG.
- Клиент соединяется (если ещё не соединён) с первичными OSD всех PG, объекты которых участвуют
в запросе и одновременно отправляет им запросы чтения/записи частей.
- Если какие-то из первичных OSD недоступны, клиент повторяет попытки соединения бесконечно до
тех пор, пока они не станут доступны или пока PG не будут назначены другие первичные OSD.
- Клиент также повторяет запросы, если первичные OSD отвечают кодом ошибки EPIPE, означающим,
что запрос не может быть обработан в данный момент. Это происходит, если PG либо не активна
вообще, либо не активна на данном OSD в данный момент (например, если в этот момент меняется
её первичный OSD) или если в процессе обработки запроса сам первичный OSD теряет подключение
к репликам.
- Первичный OSD определяет, на каких OSD находятся части объекта. По умолчанию все объекты
считаются находящимися на текущем целевом наборе OSD соответствующей PG, но какие-то могут
находиться на других OSD, если эти объекты деградированы или перемещены, или идёт процесс
ребаланса. Запросы для проверки по сети не отправляются, информация о местоположении всех
объектов рассчитывается первичным OSD при активации PG и хранится в памяти.
- Первичный OSD соединяется (если ещё не соединён) с вторичными OSD, на которых располагаются
части объекта, и отправляет им запросы чтения/записи, а также читает/пишет из/в своё локальное
хранилище, если сам входит в набор.
- После завершения всех вторичных операций чтения/записи первичный OSD отправляет ответ клиенту.
### Особенности обработки запросов
- Если в пуле используются коды коррекции ошибок и при этом часть OSD недоступна, первичный
OSD при чтении восстанавливает данные из оставшихся частей.
- Каждый объект имеет номер версии. При записи объекта первичный OSD сначала читает из номер
версии объекта. Так как первичный OSD обычно сам хранит копию или часть объекта, номер
версии обычно читается из памяти самого OSD. Однако, если ни одна часть обновляемого объекта
не находится на первичном OSD, для получения номера версии он обращается к одному из вторичных
OSD, на которых копия объекта есть. Обращения к диску при этом всё равно не происходит,
так как метаданные объектов, включая номер версии, все OSD хранят в памяти.
- Если в пуле используются коды коррекции ошибок, перед частичной записью объекта для вычисления
чётности зачастую требуется чтение частей объекта с вторичных OSD или с локального диска
самого первичного OSD.
- Также, если в пуле используются коды коррекции ошибок, для закрытия Write Hole применяется
двухфазный алгоритм записи: сначала на все вторичные OSD записывается новая версия частей
объекта, но при этом старая версия не удаляется, а потом, после получения подтверждения
успешной записи от всех вторичных OSD, новая версия фиксируется и разрешается удаление старой.
- Если в кластере не включён режим immediate_commit, то запросы записи, отправляемые клиентами,
не считаются зафиксированными на физических накопителях сразу. Для фиксации данных клиенты
должны отдельно отправлять запросы SYNC (отдельный от чтения и записи вид запроса),
а пока такой запрос не отправлен, считается, что записанные данные могут исчезнуть,
если соответствующий OSD упадёт. Поэтому, когда режим immediate_commit отключён, все
запросы записи клиенты копируют в памяти и при потере соединения и повторном соединении
с OSD повторяют из памяти. Скопированные в память данные удаляются при успешном fsync,
а чтобы хранение этих данных не приводило к чрезмерному потреблению памяти, клиенты
автоматически выполняют fsync каждые [client_dirty_limit](../config/network.ru.md#client_dirty_limit)
записанных байт.
## Similarities to Ceph ## Similarities to Ceph

View File

@ -11,6 +11,7 @@
- [Серверные компоненты](#серверные-компоненты) - [Серверные компоненты](#серверные-компоненты)
- [Базовые понятия](#базовые-понятия) - [Базовые понятия](#базовые-понятия)
- [Клиентские компоненты](#клиентские-компоненты) - [Клиентские компоненты](#клиентские-компоненты)
- [Дополнительные утилиты](#дополнительные-утилиты)
- [Общий процесс записи и чтения](#общий-процесс-записи-и-чтения) - [Общий процесс записи и чтения](#общий-процесс-записи-и-чтения)
- [Особенности обработки запросов](#особенности-обработки-запросов) - [Особенности обработки запросов](#особенности-обработки-запросов)
- [Схожесть с Ceph](#схожесть-с-ceph) - [Схожесть с Ceph](#схожесть-с-ceph)
@ -34,8 +35,9 @@
- **Пул (Pool)** — контейнер для данных, имеющих одну и ту же схему избыточности и правила распределения по OSD. - **Пул (Pool)** — контейнер для данных, имеющих одну и ту же схему избыточности и правила распределения по OSD.
- **PG (Placement Group)** — "шард", единица деления пулов в кластере, которой назначается свой набор - **PG (Placement Group)** — "шард", единица деления пулов в кластере, которой назначается свой набор
OSD для хранения данных (копий или частей объектов). OSD для хранения данных (копий или частей объектов).
- **Домен отказа (Failure Domain)** — группа OSD, одновременное падение которых рассматривается - **Домен отказа (Failure Domain)** — группа OSD, от одновременного падения которых должен защищать
как вероятное. По умолчанию это "host" (сервер). Vitastor. По умолчанию домен отказа — "host" (сервер), но вы можете установить для пула как больший
домен отказа (например, стойку серверов), так и меньший (например, отдельный диск).
- **Дерево распределения** (Placement Tree, в Ceph CRUSH Tree) — иерархическая группировка OSD - **Дерево распределения** (Placement Tree, в Ceph CRUSH Tree) — иерархическая группировка OSD
в узлы, которые далее можно использовать как домены отказа. в узлы, которые далее можно использовать как домены отказа.
@ -49,25 +51,39 @@
На базе клиентской библиотеки реализованы все остальные клиенты: На базе клиентской библиотеки реализованы все остальные клиенты:
- **vitastor-cli** — утилита командной строки для управления кластером. В данный момент позволяет - **[vitastor-cli](../usage/cli.ru.md)** — утилита командной строки для управления кластером.
просматривать общее состояние кластера и управлять образами — т.е. создавать, менять и удалять Позволяет просматривать общее состояние кластера, управлять пулами и образами — то есть
виртуальные диски, их снимки и клоны. создавать, менять и удалять виртуальные диски, их снимки и клоны.
- **Драйвер QEMU** — подключаемый модуль QEMU, позволяющий QEMU/KVM виртуальным машинам работать - **[Драйвер QEMU](../usage/qemu.ru.md)** — подключаемый модуль QEMU, позволяющий QEMU/KVM
с виртуальными дисками Vitastor напрямую из пространства пользователя с помощью клиентской виртуальным машинам работать с виртуальными дисками Vitastor напрямую из пространства пользователя
библиотеки, без необходимости отображения дисков в виде блочных устройств. Тот же драйвер с помощью клиентской библиотеки, без необходимости подключения дисков в виде блочных устройств
позволяет подключать диски в систему через [VDUSE](../usage/qemu.ru.md#vduse). Linux. Если, однако, вы хотите подключать диски в виде блочных устройств, то вы тоже можете
- **vitastor-nbd** — утилита, позволяющая монтировать образы Vitastor в виде блочных устройств сделать это с помощью того же самого драйвера и [VDUSE](../usage/qemu.ru.md#vduse).
с помощью NBD (Network Block Device), на самом деле скорее работающего как "BUSE" - **[vitastor-nbd](../usage/nbd.ru.md)** — утилита, позволяющая монтировать образы Vitastor
(Block Device In Userspace). Модуля ядра Linux для выполнения той же задачи в Vitastor нет в виде блочных устройств с помощью NBD (Network Block Device), на самом деле скорее работающего
(по крайней мере, пока). как "BUSE" (Block Device In Userspace). Модуля ядра Linux для выполнения той же задачи в
- **CSI драйвер** — драйвер для подключения Vitastor-образов в виде персистентных томов (PV) Kubernetes. Vitastor нет (по крайней мере, пока). NBD — более старый и нерекомендуемый способ подключения
Работает через vitastor-nbd — образы отражаются в виде блочных устройств и монтируются дисков — вам следует использовать VDUSE всегда, когда это возможно.
в контейнеры. - **[CSI драйвер](../installation/kubernetes.ru.md)** — драйвер для подключения Vitastor-образов
в виде персистентных томов (PV) Kubernetes. Работает через VDUSE (если доступно) или через
NBD — образы отражаются в виде блочных устройств и монтируются в контейнеры.
- **Драйвера Proxmox, OpenStack и т.п.** — подключаемые модули для соответствующих систем, - **Драйвера Proxmox, OpenStack и т.п.** — подключаемые модули для соответствующих систем,
позволяющие использовать Vitastor как хранилище в оных. позволяющие использовать Vitastor как хранилище в оных.
- **vitastor-nfs** — утилита, предоставляющая файловый доступ к образам в кластере Vitastor - **[vitastor-nfs](../usage/nfs.ru.md)** — NFS 3.0 сервер, предоставляющий два варианта файловой системы:
по протоколу NFS 3.0. Предназначена для гипервизоров, не основанных на QEMU и Linux, но при первая — упрощённая для файлового доступа к блочным образам (для не-QEMU гипервизоров, поддерживающих NFS),
этом поддерживающих NFS. вторая — VitastorFS, полноценная кластерная POSIX ФС. Оба варианта поддерживают параллельный
доступ с нескольких 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.
## Общий процесс записи и чтения ## Общий процесс записи и чтения

View File

@ -224,6 +224,10 @@ int main(int argc, char *argv[])
cmd.push_back((char*)"dump-journal"); cmd.push_back((char*)"dump-journal");
aliased = true; aliased = true;
} }
else if (!strcmp(exe_name, "vitastor-disk-test"))
{
self.test_mode = true;
}
for (int i = 1; i < argc; i++) for (int i = 1; i < argc; i++)
{ {
if (!strcmp(argv[i], "--all")) if (!strcmp(argv[i], "--all"))
@ -318,6 +322,7 @@ int main(int argc, char *argv[])
// First argument is an OSD device - take metadata layout parameters from it // First argument is an OSD device - take metadata layout parameters from it
if (self.dump_load_check_superblock(self.new_journal_device)) if (self.dump_load_check_superblock(self.new_journal_device))
return 1; return 1;
self.new_journal_device = self.dsk.journal_device;
self.new_journal_offset = self.dsk.journal_offset; self.new_journal_offset = self.dsk.journal_offset;
self.new_journal_len = self.dsk.journal_len; self.new_journal_len = self.dsk.journal_len;
} }
@ -383,6 +388,7 @@ int main(int argc, char *argv[])
// First argument is an OSD device - take metadata layout parameters from it // First argument is an OSD device - take metadata layout parameters from it
if (self.dump_load_check_superblock(self.new_meta_device)) if (self.dump_load_check_superblock(self.new_meta_device))
return 1; return 1;
self.new_meta_device = self.dsk.meta_device;
self.new_meta_offset = self.dsk.meta_offset; self.new_meta_offset = self.dsk.meta_offset;
self.new_meta_len = self.dsk.meta_len; self.new_meta_len = self.dsk.meta_len;
} }

View File

@ -41,6 +41,7 @@ struct disk_tool_t
/**** Parameters ****/ /**** Parameters ****/
std::map<std::string, std::string> options; std::map<std::string, std::string> options;
bool test_mode = false;
bool all, json, now; bool all, json, now;
bool dump_with_blocks, dump_with_data; bool dump_with_blocks, dump_with_data;
blockstore_disk_t dsk; blockstore_disk_t dsk;
@ -128,6 +129,7 @@ struct disk_tool_t
int prepare_one(std::map<std::string, std::string> options, int is_hdd = -1); int prepare_one(std::map<std::string, std::string> options, int is_hdd = -1);
int check_existing_partition(const std::string & dev); int check_existing_partition(const std::string & dev);
int fix_partition_type(const std::string & dev_by_uuid);
int prepare(std::vector<std::string> devices); int prepare(std::vector<std::string> devices);
std::vector<vitastor_dev_info_t> collect_devices(const std::vector<std::string> & devices); std::vector<vitastor_dev_info_t> collect_devices(const std::vector<std::string> & devices);
json11::Json add_partitions(vitastor_dev_info_t & devinfo, std::vector<std::string> sizes); json11::Json add_partitions(vitastor_dev_info_t & devinfo, std::vector<std::string> sizes);
@ -149,6 +151,6 @@ int write_zero(int fd, uint64_t offset, uint64_t size);
json11::Json read_parttable(std::string dev); json11::Json read_parttable(std::string dev);
uint64_t dev_size_from_parttable(json11::Json pt); uint64_t dev_size_from_parttable(json11::Json pt);
uint64_t free_from_parttable(json11::Json pt); uint64_t free_from_parttable(json11::Json pt);
int fix_partition_type(std::string dev_by_uuid); int fix_partition_type_uuid(std::string dev_by_uuid, const std::string & type_uuid);
std::string csum_type_str(uint32_t data_csum_type); std::string csum_type_str(uint32_t data_csum_type);
uint32_t csum_type_from_str(std::string data_csum_type); uint32_t csum_type_from_str(std::string data_csum_type);

View File

@ -159,7 +159,11 @@ int disk_tool_t::prepare_one(std::map<std::string, std::string> options, int is_
return 1; return 1;
} }
std::string osd_num_str; std::string osd_num_str;
if (shell_exec({ "vitastor-cli", "alloc-osd" }, "", &osd_num_str, NULL) != 0) if (test_mode && options.find("osd_num") != options.end())
{
osd_num_str = options["osd_num"];
}
else if (shell_exec({ "vitastor-cli", "alloc-osd" }, "", &osd_num_str, NULL) != 0)
{ {
dsk.close_all(); dsk.close_all();
return 1; return 1;
@ -199,10 +203,13 @@ int disk_tool_t::prepare_one(std::map<std::string, std::string> options, int is_
if (sep_j) if (sep_j)
desc += (sep_m ? " and journal on " : " with journal on ") + realpath_str(options["journal_device"]); desc += (sep_m ? " and journal on " : " with journal on ") + realpath_str(options["journal_device"]);
fprintf(stderr, "Initialized OSD %ju on %s\n", osd_num, desc.c_str()); fprintf(stderr, "Initialized OSD %ju on %s\n", osd_num, desc.c_str());
if (shell_exec({ "systemctl", "enable", "--now", "vitastor-osd@"+std::to_string(osd_num) }, "", NULL, NULL) != 0) if (!test_mode || options.find("no_init") == options.end())
{ {
fprintf(stderr, "Failed to enable systemd unit vitastor-osd@%ju\n", osd_num); if (shell_exec({ "systemctl", "enable", "--now", "vitastor-osd@"+std::to_string(osd_num) }, "", NULL, NULL) != 0)
return 1; {
fprintf(stderr, "Failed to enable systemd unit vitastor-osd@%ju\n", osd_num);
return 1;
}
} }
return 0; return 0;
} }
@ -229,6 +236,16 @@ int disk_tool_t::check_existing_partition(const std::string & dev)
return 0; return 0;
} }
int disk_tool_t::fix_partition_type(const std::string & dev)
{
std::string type_uuid = VITASTOR_PART_TYPE;
if (test_mode && options.find("part_type_uuid") != options.end())
{
type_uuid = options["part_type_uuid"];
}
return fix_partition_type_uuid(dev, type_uuid);
}
std::vector<vitastor_dev_info_t> disk_tool_t::collect_devices(const std::vector<std::string> & devices) std::vector<vitastor_dev_info_t> disk_tool_t::collect_devices(const std::vector<std::string> & devices)
{ {
std::vector<vitastor_dev_info_t> devinfo; std::vector<vitastor_dev_info_t> devinfo;

View File

@ -343,7 +343,7 @@ uint64_t free_from_parttable(json11::Json pt)
return free; return free;
} }
int fix_partition_type(std::string dev_by_uuid) int fix_partition_type_uuid(std::string dev_by_uuid, const std::string & type_uuid)
{ {
auto uuid = strtolower(dev_by_uuid.substr(dev_by_uuid.rfind('/')+1)); auto uuid = strtolower(dev_by_uuid.substr(dev_by_uuid.rfind('/')+1));
std::string parent_dev = get_parent_device(realpath_str(dev_by_uuid, false)); std::string parent_dev = get_parent_device(realpath_str(dev_by_uuid, false));
@ -356,7 +356,7 @@ int fix_partition_type(std::string dev_by_uuid)
for (const auto & part: pt["partitions"].array_items()) for (const auto & part: pt["partitions"].array_items())
{ {
bool this_part = (strtolower(part["uuid"].string_value()) == uuid); bool this_part = (strtolower(part["uuid"].string_value()) == uuid);
if (this_part && strtolower(part["type"].string_value()) == "e7009fac-a5a1-4d72-af72-53de13059903") if (this_part && strtolower(part["type"].string_value()) == type_uuid)
{ {
// Already correct type // Already correct type
return 0; return 0;
@ -369,7 +369,7 @@ int fix_partition_type(std::string dev_by_uuid)
{ {
script += (first ? "" : ", ")+kv.first+"="+ script += (first ? "" : ", ")+kv.first+"="+
(kv.first == "type" && this_part (kv.first == "type" && this_part
? "e7009fac-a5a1-4d72-af72-53de13059903" ? type_uuid
: (kv.second.is_string() ? kv.second.string_value() : kv.second.dump())); : (kv.second.is_string() ? kv.second.string_value() : kv.second.dump()));
first = false; first = false;
} }