Бюджетное SAN-хранилище на LSI Syncro, часть 1

  • Tutorial

Вторая часть

Итак, продолжу свои редкие статьи на тему «как не платить HP/EMC/IBM многие кило-(или даже мега-) доллары и собрать своё хранилище не хуже». Прошлый цикл я до победного конца не довёл, но 90% мыслей всё же оформил в текст.

Нашей сегодняшней целью будет отказоустойчивое «All-Flash» (то есть — только из SSD, без жестких дисков, хотя это и не принципиально) хранилище для нужд кластера vSphere, в несколько раз дешевле брендовых аналогов и с очень неплохой производительностью. Подключаться к нему мы будем по Fibre Channel, но никто не мешает сделать iSCSI, FCoE или даже, о ужас, Infiniband.

Syncro


Как ясно из названия, основой всей этой богодельни станет достаточно уникальный на рынке продукт под названием Syncro CS от компании LSI (ныне Avago).

Что же оно такое есть и чем примечательно?

По сути, это комплект из двух обычных контроллеров LSI 9286-8e (либо 9271-8i, если нужны внутренние порты) и двух суперконденсаторов для сохранения кеш-памяти на флешку контроллера в случае потери питания. Стоимость комплекта при этом в несколько раз выше цены аналогичного комплекта без HA-функционала. Но, если сравнивать с решениями на базе DRBD, то эта разница с лихвой компенсируется отсутствием необходимости иметь двойной набор накопителей.

Но самое интересное кроется в прошивке. Благодаря ей, эти контроллеры, будучи подключенными к одной SAS-сети (например, дисковой корзине с экспандерами) устанавливают через неё связь друг с другом и работают в режиме отказоустойчивого кластера.

Для нас это интересно вот чем:
  • Возможность создавать RAID-массивы, доступные сразу на двух серверах
  • Отказоустойчивость на уровне контроллеров: при смерти одного из них (или целиком сервера) второй продолжит работать и обслуживать I/O

Через SAS-сеть эти контроллеры синхронизируют свои кеши записи (т.н. cache coherency), обмениваются Heartbeat-ами, сообщая друг другу что живы-здоровы, и так далее.

У них есть некоторые важные особенности, выясненные как потом и кровью опытным путём, так и вдумчивым чтением документации:
  • По причине отказоустойчивой натуры решения, LSI Syncro поддерживает только двухпортовые SAS диски. Так что никаких SATA SSD, к сожалению, что довольно сильно увеличивает стоимость хранилища.

  • Как я понял, контроллеры поддерживают не более 96 SAS-накопителей. В документации ещё фигурирует фраза Maximum of 120 dual-ported SAS devices in the HA storage domain, которая противоречит Up to 96 ea 6G SAS and/or NearLine-SAS dual-ported HDDs and SSDs двумя строчками выше там же. Так что будем считать по-минимуму.

  • При создании массива на одном из контроллеров этот контроллер становится его хозяином до тех пор пока не будет, к примеру, перезагружен сервер где он установлен. После этого роль хозяина переходит ко второму контроллеру.

  • После возвращения в строй первого контроллера роль хозяина массива ему не возвращается, а остаётся у второго.

  • Контроллеры используют механизм I/O Shipping: при приходе I/O-запроса на контроллер, который в данный момент не является хозяином массива, он переправляет этот запрос контроллеру-хозяину по SAS-шине, тот его исполняет и отправляет обратно.

  • В результате вышесказанного скорость работы подчиненного контроллера с массивом в несколько раз ниже (по линейной скорости — в 2 раза, по IOPSам — в 7(!) раз) чем скорость работы контроллера-хозяина массива.

  • На данный момент не существует способа заставить контроллер-хозяин добровольно передать владение массивом второму контроллеру, что очень странно. Особенно учитывая то, что при мягкой перезагрузке (Controlled failover) основного контроллера, в логах второго контроллера видны сообщения о том, что основной предупреждает о своём ребуте и просит забрать массивы. LSI что-то такое обещала добавить в свои утилиты, а пока… только перезагрузка, только хардкор.

  • ОС сервера, куда вставлен подчинённый (на данный момент времени) контроллер видит массивы контроллера-хозяина, но утилиты управления контроллером (StorCLI, MegaCLI, ...) массивов (и дисков, состоящих в этих массивах) показывать не будут. Как только владение массивами перейдёт этому контроллеру, то массивы и диски сразу появятся в выводе утилит и можно будет ими управлять

ALUA


Так как скорость работы с массивом у хозяина и подчинённого контроллеров разная, то нам придётся строить хранилище с парадигмой ALUA, которая как раз для таких случаев и была придумана. Там много всяких особенностей, но для нас смысл её в том, что можно часть портов на хранилищах пометить как Optimized (т.е. рекомендованные к использованию), а другие как Unoptimized (соответственно, не рекомендованные). Все эти порты могут обслуживать ввод-вывод в любой момент времени, но при наличии живых путей до Optimized портов инициатор будет использовать их, а остальные держать в запасе. Если же все Optimized порты откажут, то инициатор (ESXi в нашем случае), немного подумав, пустит I/O по Unoptimized портам.

С точки зрения VMWare ESXi это выглядит так:


Первая тройка путей ведёт нас к подчинённому хранилищу, а вторая тройка — к главному, которое может обслуживать I/O на полной скорости.

Если бы мы не использовали ALUA, то I/O запросы (в режиме Round-Robin) шли бы на оба хранилища, что привело бы к неравномерности задержек и скорости, по сути упираясь в производительность подчинённого хранилища.

Achtung!
Многие программы, работающие с SAN (например — Microsoft Cluster Services), опираются на SCSI Persistent Reservations, позволяющие блокировать LUN и производить с ним эксклюзивно всякие непотребства. Так вот, эти самые SCSI PR не будут реплицироваться на другой сервер.

То есть, если инициатор поставит блокировку на LUN через путь, ведущий на первый сервер, то через путь, ведущий на второй сервер, эта блокировка видна не будет. Для работы в режиме Round Robin это особенно важно, так как пути меняются постоянно и через какой путь будет установлена блокировка заранее неизвестно. В случае с VMWare ESXi это, в принципе, не проблема так как с версии VMFS5 не используются SCSI PR, а вместо них идёт в ход инструкция Atomic-Test-and-Set (которая, впрочем, тоже не реплицируется, но зато блокирует только нужную область на LUNе и на короткое время, а не весь LUN целиком), да и ALUA должен дать знать ESXi чтобы тот не использовал пути на второй сервер пока жив основной.

Есть какие-то коммерческие решения на базе SCST, реализующие синхронизацию SCSI PR, но я их не пробовал. И, по слухам, какое-то подобное решение будет, возможно, скоро открыто для публики.

Ладно, с теорией закончили, приступим к практике.

Hard & Soft


Железо


Серверы-контроллеры:
  • Комплект LSI Syncro CS 9286-8e x 1
    Нынче уже доступны Syncro со скоростью 12Gb/s, но я их не щупал. Плюс, там ещё больше порезаны фичи MegaRAID (убран Cachecade совсем, а в предыдущей версии был, хоть и только в режиме кеширования чтения).

  • Корпуса Supermicro SC216 2U x 2
    Можно было, конечно, использовать 1U, но у них очень туго со слотами расширения, да и место в стойке экономить особо не надо было.

  • МП Supermicro X10SRL-F x 2
    Выбрана за большое количество слотов PCI-E.

  • Процессор Intel Xeon E5-1650 v3 x 2
    Выбран за большую частоту.

  • Память DDR4-2133 16GB ECC Registered x 8
    Память нашим железкам почти не понадобится (хотя, если добавить корзину с жесткими дисками, то как кеш чтения вполне пригодится), поэтому можно брать поменьше, но с учетом 4-х канального контроллера памяти и возможности зеркалировать модули.

  • Двухпортовые Fibre Channel контроллеры QLogic 2562 x 4
    На эту номинацию проходили кастинг и 16Гбитные QLogic 2672, но там вылезли проблемы совместимости с драйвером, да и 16Гбит свичей у меня нет. Поэтому была применена волшебная палочка и они, до поры до времени, превратились в двухпортовые 10Гбит сетевые карты с космической стоимостью… :)

  • Intel DC S3500 80Gb x 4
    По паре в каждый сервер (RAID1) под ОС (да, можно было бы поставить на USB флешки или SATA DOM, но у первых плохая надежность (иногда отваливаются), а у вторых нет возможности Hot Swap).

Дисковая полка:
  • Корпус на 72 2.5" диска Supermicro SC417E26 x 1
    Внутри имеет три идентичных бэкплейна на 24 диска со двойными экспандерами для отказоустойчивости. У них есть ещё более монструозное решение — SC417E16-RJBOD1 — на 88 дисков, но там лишь одинарные экспандеры, что плохо скажется на надёжности, да и слотов расширения мало. А нам нужно, по хорошему, минимум три (для установки планок с внешними SAS портами — две для подключения к серверам и одна для каскадирования корзин).

  • Твердотельные SAS диски на 400Гбайт Hitachi S842E400M2 x 48
    На момент закупки это были одни из самых надёжных и недорогих на рынке (из списка совместимости Syncro). Производитель обещает износостойкость 30 Петабайт на запись или 40 полных перезаписей в день в течении 5 лет. Что ж, время покажет…

  • Всякая прочая мелочь вроде платы питания Supermicro CSE-PTJBOD-CB2 (чтобы корпус включался без М/П + мониторинг БП корпуса через I2C/SAS), провода SAS внутренние и внешние (для коммутации бэкплейнов между собой и подключения серверов к полке) и т.п.

FC-коммутаторы:
  • Cisco MDS9148 x 2
    Относительно недорогие и качественные девайсы (я брал с 16 активированными портами).
    Сейчас вроде уже end-of-sale, вместо них 9148S на 16Гбит.

Cost & Performance


Всё это счастье (вместе со свичами) на момент закупки (ноябрь 2014) стоило около 4 млн. рублей, что при «сырой емкости» в 19.2Тб флеша очень и очень недорого. Для сравнения: за low-end двухконтроллерную железяку MSA 2040 с 24 х 800GB SSD на борту компания HP сейчас хочет что-то около 18 млн (да, я знаю про всякие скидки, да и доллар подрос, но всё же порядок цен, думаю, примерно такой).

По скорости они обещают не более 85k IOPS, у нас же будет чуть побольше: с одной ноды я снимал 720k IOPS с 75% загрузкой CPU с бэкендом vdisk_nullio (при чтении выдаёт нули, записи же отбрасывает, эдакий аналог /dev/null).

Причём загрузка CPU, почему-то, скачкообразно нарастает при увеличении IOPS с 600k до 720k — с 40% до 75%, до этого же растёт равномерно. Линейная скорость ожидаемо упирается в FC интерфейсы — около 3Гбайт/c (4 порта по 800Мб/c в теории, учитывая 8b/10b кодирование у 8Gbit FC).

Из Syncro я смог выжать 420k IOPS, что близко к теоретическому пределу в 450k IOPS, которые обещает LSI. При работе с SSD очень важно отключать кеш записи на массиве (режим write-through) и включать Direct I/O, в противном случае производительность упирается в 150k IOPS даже при чтении. Это особенности технологии FastPath у LSI, она активируется только при соблюдении этих двух условий.
Линейная скорость чтения с массива достигает 3.8Гбайт/c. Тут, скорее всего, упираемся в производительность самого контроллера (шина PCI-E 3.0 x8 может прокачать 8Гбайт/c).

Более подробные бенчмарки, думаю, будут во второй части.

Сборка серверов


Тут особо рассказывать нечего.
В каждый сервер устанавливаем материнскую плату, процессор, память, два FC контроллера и один Syncro.
Я ещё установил в заднюю часть корпуса небольшую корзину (Supermicro MCP-220-82609-0N) на два диска и туда вставил SSD под ОСь. Основная корзина корпуса пока осталась незадействованной, но в будущем её можно будет тоже подключить к Syncro, хотя это и разрушит отказоустойчивую натуру решения (выключил одну ноду — заодно вырубил и бэкплейн).

Важный совет по надежности — выставить в биосе зеркалирование памяти, это эдакий RAID1 для DDR.
Мозгов станет вдвое меньше, зато надёжность резко повысится. Ну и погонять memtest-ом недельку, для верности. В логах биоса читать про ошибки ECC, если они есть — менять сбойный модуль и гонять заново. Ибо если пока это корректируемые ошибки, то потом могут стать фатальными, такие случаи были.

Схема подключения


SAS


Следующая схема нагло стырена из документации к Syncro:


Глубинный смысл такого подключения в том, что при отказе одной из дисковых полок
вторая продолжит работать. Если же подключать полки одну за другой (daisy chain),
то при отказе первой полки в цепочке связь со всеми остальными тоже будет потеряна.
А тут мы имеем что-то вроде топологии «кольцо», когда дополнительные полки подключаются
между этими двумя.

В нашем же случае полка одна (хоть в ней и три бэкплейна), так что подключать мы её будем
по-обычному, примерно так:

Внутри полки бэкплейны соединяем последовательно.

FC


Сервера подключаем к FC-коммутаторам так:

Таким образом, при отказе любой из HBA-карт и/или одного коммутатора у нас будет связность.

Вминание! Коммутаторы не следует соединять между собой транками и прочими ISL!
Это должны быть две независимые фабрики.
Ибо, если мы сделаем ошибку в настройке одного из них (или будет сбоить софт) — это не скажется на втором (в FC зонирование и прочие настройки распространяются по всем свичам фабрики).

Зонировал я по принципу «один порт инициатора и один порт хранилища».
При наличии большого количества инициаторов это трудоёмко, так как количество зон будет равно [кол-во портов инициаторов] X [кол-во портов хранилищ]. Но, имея список портов хранилищ и инициаторов зоны легко можно сгенерировать скриптом :) Лень — двигатель прогресса.

Программная часть


  • Debian Linux 7 x86-64
  • Kernel 3.14.xx LTS
    Если требуется крайне высокая производительность, то стоит обратить свой светлый взор на ядра 3.18+ так как в них была интегрирована поддержка SCSI-MQ, которая позволяет добиться 1млн+ IOPS на одном LUN.

    Но, в нашем случае, когда много инициаторов подключаются к нескольким LUN-ам, это даже вредно, ибо по бенчмарками в данном случае SCSI-MQ работает несколько медленнее обычного стека. Ещё один минус — SCSI-MQ не имеет планировщиков I/O (deadline, cfq), что, в общем-то логично — SSD планировщик не нужен, а для жёстких дисков толку от SCSI-MQ никакого, там IOPSам далеко до программных пределов. А вот в смешанных конфигурациях (SSD+HDD) это, скорее всего, негативно скажется на скорости работы массивов с HDD.
  • SCST Target Framework 3.0.1

Тут всё более или менее стандартно, ставим ОС на софтовый линуксовый рейд (mdraid) так как железного рейда в этих материнских платах не предусмотрено.

Далее настраиваем и собираем ядро.
Мой конфиг, может кому пригодится
CONFIG_64BIT=y
CONFIG_X86_64=y
CONFIG_X86=y
CONFIG_INSTRUCTION_DECODER=y
CONFIG_OUTPUT_FORMAT="elf64-x86-64"
CONFIG_ARCH_DEFCONFIG="arch/x86/configs/x86_64_defconfig"
CONFIG_LOCKDEP_SUPPORT=y
CONFIG_STACKTRACE_SUPPORT=y
CONFIG_HAVE_LATENCYTOP_SUPPORT=y
CONFIG_MMU=y
CONFIG_NEED_DMA_MAP_STATE=y
CONFIG_NEED_SG_DMA_LENGTH=y
CONFIG_GENERIC_ISA_DMA=y
CONFIG_GENERIC_BUG=y
CONFIG_GENERIC_BUG_RELATIVE_POINTERS=y
CONFIG_GENERIC_HWEIGHT=y
CONFIG_ARCH_MAY_HAVE_PC_FDC=y
CONFIG_RWSEM_XCHGADD_ALGORITHM=y
CONFIG_GENERIC_CALIBRATE_DELAY=y
CONFIG_ARCH_HAS_CPU_RELAX=y
CONFIG_ARCH_HAS_CACHE_LINE_SIZE=y
CONFIG_ARCH_HAS_CPU_AUTOPROBE=y
CONFIG_HAVE_SETUP_PER_CPU_AREA=y
CONFIG_NEED_PER_CPU_EMBED_FIRST_CHUNK=y
CONFIG_NEED_PER_CPU_PAGE_FIRST_CHUNK=y
CONFIG_ARCH_HIBERNATION_POSSIBLE=y
CONFIG_ARCH_SUSPEND_POSSIBLE=y
CONFIG_ARCH_WANT_HUGE_PMD_SHARE=y
CONFIG_ARCH_WANT_GENERAL_HUGETLB=y
CONFIG_ZONE_DMA32=y
CONFIG_AUDIT_ARCH=y
CONFIG_ARCH_SUPPORTS_OPTIMIZED_INLINING=y
CONFIG_ARCH_SUPPORTS_DEBUG_PAGEALLOC=y
CONFIG_X86_64_SMP=y
CONFIG_X86_HT=y
CONFIG_ARCH_HWEIGHT_CFLAGS="-fcall-saved-rdi -fcall-saved-rsi -fcall-saved-rdx -fcall-saved-rcx -fcall-saved-r8 -fcall-saved-r9 -fcall-saved-r10 -fcall-saved-r11"
CONFIG_ARCH_SUPPORTS_UPROBES=y
CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config"
CONFIG_IRQ_WORK=y
CONFIG_BUILDTIME_EXTABLE_SORT=y
CONFIG_INIT_ENV_ARG_LIMIT=32
CONFIG_CROSS_COMPILE=""
CONFIG_LOCALVERSION=""
CONFIG_HAVE_KERNEL_GZIP=y
CONFIG_HAVE_KERNEL_BZIP2=y
CONFIG_HAVE_KERNEL_LZMA=y
CONFIG_HAVE_KERNEL_XZ=y
CONFIG_HAVE_KERNEL_LZO=y
CONFIG_HAVE_KERNEL_LZ4=y
CONFIG_KERNEL_XZ=y
CONFIG_DEFAULT_HOSTNAME="(none)"
CONFIG_SYSVIPC=y
CONFIG_SYSVIPC_SYSCTL=y
CONFIG_POSIX_MQUEUE=y
CONFIG_POSIX_MQUEUE_SYSCTL=y
CONFIG_FHANDLE=y
CONFIG_GENERIC_IRQ_PROBE=y
CONFIG_GENERIC_IRQ_SHOW=y
CONFIG_GENERIC_PENDING_IRQ=y
CONFIG_IRQ_FORCED_THREADING=y
CONFIG_SPARSE_IRQ=y
CONFIG_CLOCKSOURCE_WATCHDOG=y
CONFIG_ARCH_CLOCKSOURCE_DATA=y
CONFIG_GENERIC_TIME_VSYSCALL=y
CONFIG_GENERIC_CLOCKEVENTS=y
CONFIG_GENERIC_CLOCKEVENTS_BUILD=y
CONFIG_GENERIC_CLOCKEVENTS_BROADCAST=y
CONFIG_GENERIC_CLOCKEVENTS_MIN_ADJUST=y
CONFIG_GENERIC_CMOS_UPDATE=y
CONFIG_TICK_ONESHOT=y
CONFIG_NO_HZ_COMMON=y
CONFIG_NO_HZ_IDLE=y
CONFIG_HIGH_RES_TIMERS=y
CONFIG_TICK_CPU_ACCOUNTING=y
CONFIG_TASKSTATS=y
CONFIG_TASK_DELAY_ACCT=y
CONFIG_TASK_XACCT=y
CONFIG_TASK_IO_ACCOUNTING=y
CONFIG_TREE_RCU=y
CONFIG_RCU_STALL_COMMON=y
CONFIG_RCU_FANOUT=64
CONFIG_RCU_FANOUT_LEAF=16
CONFIG_IKCONFIG=y
CONFIG_IKCONFIG_PROC=y
CONFIG_LOG_BUF_SHIFT=18
CONFIG_HAVE_UNSTABLE_SCHED_CLOCK=y
CONFIG_ARCH_SUPPORTS_NUMA_BALANCING=y
CONFIG_ARCH_SUPPORTS_INT128=y
CONFIG_ARCH_WANTS_PROT_NUMA_PROT_NONE=y
CONFIG_ARCH_USES_NUMA_PROT_NONE=y
CONFIG_NUMA_BALANCING_DEFAULT_ENABLED=y
CONFIG_NUMA_BALANCING=y
CONFIG_CGROUPS=y
CONFIG_CGROUP_SCHED=y
CONFIG_FAIR_GROUP_SCHED=y
CONFIG_CFS_BANDWIDTH=y
CONFIG_RT_GROUP_SCHED=y
CONFIG_BLK_CGROUP=y
CONFIG_NAMESPACES=y
CONFIG_SCHED_AUTOGROUP=y
CONFIG_SYSCTL=y
CONFIG_ANON_INODES=y
CONFIG_HAVE_UID16=y
CONFIG_SYSCTL_EXCEPTION_TRACE=y
CONFIG_HAVE_PCSPKR_PLATFORM=y
CONFIG_UID16=y
CONFIG_KALLSYMS=y
CONFIG_PRINTK=y
CONFIG_BUG=y
CONFIG_ELF_CORE=y
CONFIG_PCSPKR_PLATFORM=y
CONFIG_BASE_FULL=y
CONFIG_FUTEX=y
CONFIG_EPOLL=y
CONFIG_SIGNALFD=y
CONFIG_TIMERFD=y
CONFIG_EVENTFD=y
CONFIG_SHMEM=y
CONFIG_AIO=y
CONFIG_PCI_QUIRKS=y
CONFIG_HAVE_PERF_EVENTS=y
CONFIG_PERF_EVENTS=y
CONFIG_VM_EVENT_COUNTERS=y
CONFIG_SLUB_DEBUG=y
CONFIG_SLUB=y
CONFIG_SLUB_CPU_PARTIAL=y
CONFIG_HAVE_OPROFILE=y
CONFIG_OPROFILE_NMI_TIMER=y
CONFIG_JUMP_LABEL=y
CONFIG_HAVE_EFFICIENT_UNALIGNED_ACCESS=y
CONFIG_ARCH_USE_BUILTIN_BSWAP=y
CONFIG_HAVE_IOREMAP_PROT=y
CONFIG_HAVE_KPROBES=y
CONFIG_HAVE_KRETPROBES=y
CONFIG_HAVE_OPTPROBES=y
CONFIG_HAVE_KPROBES_ON_FTRACE=y
CONFIG_HAVE_ARCH_TRACEHOOK=y
CONFIG_HAVE_DMA_ATTRS=y
CONFIG_GENERIC_SMP_IDLE_THREAD=y
CONFIG_HAVE_REGS_AND_STACK_ACCESS_API=y
CONFIG_HAVE_DMA_API_DEBUG=y
CONFIG_HAVE_HW_BREAKPOINT=y
CONFIG_HAVE_MIXED_BREAKPOINTS_REGS=y
CONFIG_HAVE_USER_RETURN_NOTIFIER=y
CONFIG_HAVE_PERF_EVENTS_NMI=y
CONFIG_HAVE_PERF_REGS=y
CONFIG_HAVE_PERF_USER_STACK_DUMP=y
CONFIG_HAVE_ARCH_JUMP_LABEL=y
CONFIG_ARCH_HAVE_NMI_SAFE_CMPXCHG=y
CONFIG_HAVE_ALIGNED_STRUCT_PAGE=y
CONFIG_HAVE_CMPXCHG_LOCAL=y
CONFIG_HAVE_CMPXCHG_DOUBLE=y
CONFIG_ARCH_WANT_COMPAT_IPC_PARSE_VERSION=y
CONFIG_ARCH_WANT_OLD_COMPAT_IPC=y
CONFIG_HAVE_ARCH_SECCOMP_FILTER=y
CONFIG_SECCOMP_FILTER=y
CONFIG_HAVE_CC_STACKPROTECTOR=y
CONFIG_CC_STACKPROTECTOR_NONE=y
CONFIG_HAVE_CONTEXT_TRACKING=y
CONFIG_HAVE_VIRT_CPU_ACCOUNTING_GEN=y
CONFIG_HAVE_IRQ_TIME_ACCOUNTING=y
CONFIG_HAVE_ARCH_TRANSPARENT_HUGEPAGE=y
CONFIG_HAVE_ARCH_SOFT_DIRTY=y
CONFIG_MODULES_USE_ELF_RELA=y
CONFIG_HAVE_IRQ_EXIT_ON_IRQ_STACK=y
CONFIG_OLD_SIGSUSPEND3=y
CONFIG_COMPAT_OLD_SIGACTION=y
CONFIG_SLABINFO=y
CONFIG_RT_MUTEXES=y
CONFIG_BASE_SMALL=0
CONFIG_MODULES=y
CONFIG_MODULE_UNLOAD=y
CONFIG_STOP_MACHINE=y
CONFIG_BLOCK=y
CONFIG_BLK_DEV_BSG=y
CONFIG_PARTITION_ADVANCED=y
CONFIG_MSDOS_PARTITION=y
CONFIG_EFI_PARTITION=y
CONFIG_BLOCK_COMPAT=y
CONFIG_IOSCHED_NOOP=y
CONFIG_IOSCHED_DEADLINE=y
CONFIG_IOSCHED_CFQ=y
CONFIG_CFQ_GROUP_IOSCHED=y
CONFIG_DEFAULT_DEADLINE=y
CONFIG_DEFAULT_IOSCHED="deadline"
CONFIG_PADATA=y
CONFIG_INLINE_SPIN_UNLOCK_IRQ=y
CONFIG_INLINE_READ_UNLOCK=y
CONFIG_INLINE_READ_UNLOCK_IRQ=y
CONFIG_INLINE_WRITE_UNLOCK=y
CONFIG_INLINE_WRITE_UNLOCK_IRQ=y
CONFIG_ARCH_SUPPORTS_ATOMIC_RMW=y
CONFIG_MUTEX_SPIN_ON_OWNER=y
CONFIG_ZONE_DMA=y
CONFIG_SMP=y
CONFIG_X86_SUPPORTS_MEMORY_FAILURE=y
CONFIG_SCHED_OMIT_FRAME_POINTER=y
CONFIG_NO_BOOTMEM=y
CONFIG_MCORE2=y
CONFIG_X86_INTERNODE_CACHE_SHIFT=6
CONFIG_X86_L1_CACHE_SHIFT=6
CONFIG_X86_INTEL_USERCOPY=y
CONFIG_X86_USE_PPRO_CHECKSUM=y
CONFIG_X86_P6_NOP=y
CONFIG_X86_TSC=y
CONFIG_X86_CMPXCHG64=y
CONFIG_X86_CMOV=y
CONFIG_X86_MINIMUM_CPU_FAMILY=64
CONFIG_X86_DEBUGCTLMSR=y
CONFIG_CPU_SUP_INTEL=y
CONFIG_CPU_SUP_AMD=y
CONFIG_CPU_SUP_CENTAUR=y
CONFIG_HPET_TIMER=y
CONFIG_HPET_EMULATE_RTC=y
CONFIG_DMI=y
CONFIG_SWIOTLB=y
CONFIG_IOMMU_HELPER=y
CONFIG_NR_CPUS=32
CONFIG_SCHED_SMT=y
CONFIG_SCHED_MC=y
CONFIG_PREEMPT_NONE=y
CONFIG_X86_UP_APIC_MSI=y
CONFIG_X86_LOCAL_APIC=y
CONFIG_X86_IO_APIC=y
CONFIG_X86_MCE=y
CONFIG_X86_MCE_INTEL=y
CONFIG_X86_MCE_THRESHOLD=y
CONFIG_X86_THERMAL_VECTOR=y
CONFIG_X86_16BIT=y
CONFIG_X86_ESPFIX64=y
CONFIG_MICROCODE=y
CONFIG_MICROCODE_INTEL=y
CONFIG_MICROCODE_OLD_INTERFACE=y
CONFIG_X86_MSR=y
CONFIG_X86_CPUID=y
CONFIG_ARCH_PHYS_ADDR_T_64BIT=y
CONFIG_ARCH_DMA_ADDR_T_64BIT=y
CONFIG_DIRECT_GBPAGES=y
CONFIG_NUMA=y
CONFIG_X86_64_ACPI_NUMA=y
CONFIG_NODES_SPAN_OTHER_NODES=y
CONFIG_NODES_SHIFT=2
CONFIG_ARCH_SPARSEMEM_ENABLE=y
CONFIG_ARCH_SPARSEMEM_DEFAULT=y
CONFIG_ARCH_SELECT_MEMORY_MODEL=y
CONFIG_ILLEGAL_POINTER_VALUE=0xdead000000000000
CONFIG_SELECT_MEMORY_MODEL=y
CONFIG_SPARSEMEM_MANUAL=y
CONFIG_SPARSEMEM=y
CONFIG_NEED_MULTIPLE_NODES=y
CONFIG_HAVE_MEMORY_PRESENT=y
CONFIG_SPARSEMEM_EXTREME=y
CONFIG_SPARSEMEM_VMEMMAP_ENABLE=y
CONFIG_SPARSEMEM_ALLOC_MEM_MAP_TOGETHER=y
CONFIG_SPARSEMEM_VMEMMAP=y
CONFIG_HAVE_MEMBLOCK=y
CONFIG_HAVE_MEMBLOCK_NODE_MAP=y
CONFIG_ARCH_DISCARD_MEMBLOCK=y
CONFIG_MEMORY_ISOLATION=y
CONFIG_PAGEFLAGS_EXTENDED=y
CONFIG_SPLIT_PTLOCK_CPUS=4
CONFIG_ARCH_ENABLE_SPLIT_PMD_PTLOCK=y
CONFIG_COMPACTION=y
CONFIG_MIGRATION=y
CONFIG_ARCH_ENABLE_HUGEPAGE_MIGRATION=y
CONFIG_PHYS_ADDR_T_64BIT=y
CONFIG_ZONE_DMA_FLAG=1
CONFIG_BOUNCE=y
CONFIG_VIRT_TO_BUS=y
CONFIG_DEFAULT_MMAP_MIN_ADDR=0
CONFIG_ARCH_SUPPORTS_MEMORY_FAILURE=y
CONFIG_MEMORY_FAILURE=y
CONFIG_TRANSPARENT_HUGEPAGE=y
CONFIG_TRANSPARENT_HUGEPAGE_ALWAYS=y
CONFIG_CROSS_MEMORY_ATTACH=y
CONFIG_X86_RESERVE_LOW=64
CONFIG_MTRR=y
CONFIG_MTRR_SANITIZER=y
CONFIG_MTRR_SANITIZER_ENABLE_DEFAULT=1
CONFIG_MTRR_SANITIZER_SPARE_REG_NR_DEFAULT=1
CONFIG_X86_PAT=y
CONFIG_ARCH_USES_PG_UNCACHED=y
CONFIG_ARCH_RANDOM=y
CONFIG_X86_SMAP=y
CONFIG_SECCOMP=y
CONFIG_HZ_100=y
CONFIG_HZ=100
CONFIG_SCHED_HRTICK=y
CONFIG_PHYSICAL_START=0x1000000
CONFIG_PHYSICAL_ALIGN=0x1000000
CONFIG_ARCH_ENABLE_MEMORY_HOTPLUG=y
CONFIG_USE_PERCPU_NUMA_NODE_ID=y
CONFIG_ACPI=y
CONFIG_ACPI_FAN=y
CONFIG_ACPI_PROCESSOR=y
CONFIG_ACPI_THERMAL=y
CONFIG_ACPI_NUMA=y
CONFIG_X86_PM_TIMER=y
CONFIG_ACPI_HED=y
CONFIG_ACPI_APEI=y
CONFIG_ACPI_APEI_GHES=y
CONFIG_ACPI_APEI_PCIEAER=y
CONFIG_ACPI_APEI_MEMORY_FAILURE=y
CONFIG_ACPI_EXTLOG=y
CONFIG_CPU_FREQ=y
CONFIG_CPU_FREQ_GOV_COMMON=y
CONFIG_CPU_FREQ_DEFAULT_GOV_PERFORMANCE=y
CONFIG_CPU_FREQ_GOV_PERFORMANCE=y
CONFIG_CPU_FREQ_GOV_ONDEMAND=y
CONFIG_X86_ACPI_CPUFREQ=y
CONFIG_CPU_IDLE=y
CONFIG_CPU_IDLE_MULTIPLE_DRIVERS=y
CONFIG_CPU_IDLE_GOV_LADDER=y
CONFIG_CPU_IDLE_GOV_MENU=y
CONFIG_INTEL_IDLE=y
CONFIG_PCI=y
CONFIG_PCI_DIRECT=y
CONFIG_PCI_MMCONFIG=y
CONFIG_PCI_DOMAINS=y
CONFIG_PCIEPORTBUS=y
CONFIG_PCIEAER=y
CONFIG_PCIEASPM=y
CONFIG_PCIEASPM_PERFORMANCE=y
CONFIG_PCI_MSI=y
CONFIG_PCI_LABEL=y
CONFIG_ISA_DMA_API=y
CONFIG_AMD_NB=y
CONFIG_BINFMT_ELF=y
CONFIG_COMPAT_BINFMT_ELF=y
CONFIG_ARCH_BINFMT_ELF_RANDOMIZE_PIE=y
CONFIG_BINFMT_SCRIPT=y
CONFIG_COREDUMP=y
CONFIG_IA32_EMULATION=y
CONFIG_X86_X32=y
CONFIG_COMPAT=y
CONFIG_COMPAT_FOR_U64_ALIGNMENT=y
CONFIG_SYSVIPC_COMPAT=y
CONFIG_X86_DEV_DMA_OPS=y
CONFIG_IOSF_MBI=m
CONFIG_NET=y
CONFIG_PACKET=y
CONFIG_PACKET_DIAG=y
CONFIG_UNIX=y
CONFIG_UNIX_DIAG=y
CONFIG_INET=y
CONFIG_TCP_ZERO_COPY_TRANSFER_COMPLETION_NOTIFICATION=y
CONFIG_IP_MULTICAST=y
CONFIG_NET_IPIP=y
CONFIG_NET_IPGRE_DEMUX=y
CONFIG_NET_IP_TUNNEL=y
CONFIG_NET_IPGRE=y
CONFIG_NET_IPGRE_BROADCAST=y
CONFIG_INET_TUNNEL=y
CONFIG_INET_LRO=y
CONFIG_INET_DIAG=y
CONFIG_INET_TCP_DIAG=y
CONFIG_INET_UDP_DIAG=y
CONFIG_TCP_CONG_ADVANCED=y
CONFIG_TCP_CONG_HTCP=y
CONFIG_DEFAULT_HTCP=y
CONFIG_DEFAULT_TCP_CONG="htcp"
CONFIG_STP=y
CONFIG_BRIDGE=y
CONFIG_HAVE_NET_DSA=y
CONFIG_VLAN_8021Q=y
CONFIG_LLC=y
CONFIG_NETLINK_MMAP=y
CONFIG_NETLINK_DIAG=y
CONFIG_RPS=y
CONFIG_RFS_ACCEL=y
CONFIG_XPS=y
CONFIG_NET_RX_BUSY_POLL=y
CONFIG_BQL=y
CONFIG_NET_FLOW_LIMIT=y
CONFIG_HAVE_BPF_JIT=y
CONFIG_UEVENT_HELPER_PATH="/sbin/hotplug"
CONFIG_DEVTMPFS=y
CONFIG_DEVTMPFS_MOUNT=y
CONFIG_STANDALONE=y
CONFIG_PREVENT_FIRMWARE_BUILD=y
CONFIG_FW_LOADER=y
CONFIG_FIRMWARE_IN_KERNEL=y
CONFIG_EXTRA_FIRMWARE=""
CONFIG_FW_LOADER_USER_HELPER=y
CONFIG_CONNECTOR=y
CONFIG_PROC_EVENTS=y
CONFIG_ARCH_MIGHT_HAVE_PC_PARPORT=y
CONFIG_PNP=y
CONFIG_PNPACPI=y
CONFIG_BLK_DEV=y
CONFIG_BLK_DEV_LOOP=y
CONFIG_BLK_DEV_LOOP_MIN_COUNT=8
CONFIG_HAVE_IDE=y
CONFIG_SCSI_MOD=y
CONFIG_RAID_ATTRS=y
CONFIG_SCSI=y
CONFIG_SCSI_DMA=y
CONFIG_SCSI_NETLINK=y
CONFIG_BLK_DEV_SD=y
CONFIG_CHR_DEV_SG=y
CONFIG_SCSI_MULTI_LUN=y
CONFIG_SCSI_CONSTANTS=y
CONFIG_SCSI_SCAN_ASYNC=y
CONFIG_SCSI_FC_ATTRS=y
CONFIG_SCSI_SAS_ATTRS=y
CONFIG_SCSI_LOWLEVEL=y
CONFIG_MEGARAID_SAS=y
CONFIG_ATA=y
CONFIG_ATA_VERBOSE_ERROR=y
CONFIG_ATA_ACPI=y
CONFIG_SATA_PMP=y
CONFIG_SATA_AHCI=y
CONFIG_SATA_AHCI_PLATFORM=y
CONFIG_MD=y
CONFIG_BLK_DEV_MD=y
CONFIG_MD_AUTODETECT=y
CONFIG_MD_RAID0=y
CONFIG_MD_RAID1=y
CONFIG_MD_RAID10=y
CONFIG_MD_RAID456=y
CONFIG_BLK_DEV_DM_BUILTIN=y
CONFIG_BLK_DEV_DM=y
CONFIG_DM_CRYPT=y
CONFIG_DM_ZERO=y
CONFIG_DM_UEVENT=y
CONFIG_NETDEVICES=y
CONFIG_NET_CORE=y
CONFIG_BONDING=y
CONFIG_NET_FC=y
CONFIG_NETCONSOLE=y
CONFIG_NETCONSOLE_DYNAMIC=y
CONFIG_NETPOLL=y
CONFIG_NETPOLL_TRAP=y
CONFIG_NET_POLL_CONTROLLER=y
CONFIG_TUN=y
CONFIG_ETHERNET=y
CONFIG_MDIO=y
CONFIG_NET_VENDOR_INTEL=y
CONFIG_E1000E=y
CONFIG_IGB=y
CONFIG_IGB_HWMON=y
CONFIG_IGB_DCA=y
CONFIG_IXGBE=y
CONFIG_IXGBE_HWMON=y
CONFIG_IXGBE_DCA=y
CONFIG_PPP=y
CONFIG_PPP_DEFLATE=y
CONFIG_PPP_FILTER=y
CONFIG_PPP_MULTILINK=y
CONFIG_PPPOE=y
CONFIG_PPP_ASYNC=y
CONFIG_PPP_SYNC_TTY=y
CONFIG_SLHC=y
CONFIG_INPUT=y
CONFIG_INPUT_MOUSEDEV=y
CONFIG_INPUT_MOUSEDEV_PSAUX=y
CONFIG_INPUT_MOUSEDEV_SCREEN_X=1024
CONFIG_INPUT_MOUSEDEV_SCREEN_Y=768
CONFIG_INPUT_KEYBOARD=y
CONFIG_KEYBOARD_ATKBD=y
CONFIG_SERIO=y
CONFIG_ARCH_MIGHT_HAVE_PC_SERIO=y
CONFIG_SERIO_I8042=y
CONFIG_SERIO_SERPORT=y
CONFIG_SERIO_LIBPS2=y
CONFIG_TTY=y
CONFIG_VT=y
CONFIG_CONSOLE_TRANSLATIONS=y
CONFIG_VT_CONSOLE=y
CONFIG_HW_CONSOLE=y
CONFIG_VT_HW_CONSOLE_BINDING=y
CONFIG_UNIX98_PTYS=y
CONFIG_SERIAL_8250=y
CONFIG_SERIAL_8250_DEPRECATED_OPTIONS=y
CONFIG_SERIAL_8250_PNP=y
CONFIG_SERIAL_8250_CONSOLE=y
CONFIG_FIX_EARLYCON_MEM=y
CONFIG_SERIAL_8250_DMA=y
CONFIG_SERIAL_8250_PCI=y
CONFIG_SERIAL_8250_NR_UARTS=2
CONFIG_SERIAL_8250_RUNTIME_UARTS=2
CONFIG_SERIAL_CORE=y
CONFIG_SERIAL_CORE_CONSOLE=y
CONFIG_HPET=y
CONFIG_HPET_MMAP=y
CONFIG_HPET_MMAP_DEFAULT=y
CONFIG_DEVPORT=y
CONFIG_I2C=y
CONFIG_I2C_BOARDINFO=y
CONFIG_I2C_CHARDEV=y
CONFIG_I2C_HELPER_AUTO=y
CONFIG_I2C_ALGOBIT=y
CONFIG_I2C_I801=y
CONFIG_I2C_SCMI=y
CONFIG_PPS=y
CONFIG_PTP_1588_CLOCK=y
CONFIG_ARCH_WANT_OPTIONAL_GPIOLIB=y
CONFIG_HWMON=y
CONFIG_HWMON_VID=y
CONFIG_SENSORS_CORETEMP=y
CONFIG_SENSORS_JC42=y
CONFIG_SENSORS_W83627EHF=y
CONFIG_SENSORS_ACPI_POWER=y
CONFIG_THERMAL=y
CONFIG_THERMAL_HWMON=y
CONFIG_THERMAL_DEFAULT_GOV_STEP_WISE=y
CONFIG_THERMAL_GOV_STEP_WISE=y
CONFIG_SSB_POSSIBLE=y
CONFIG_BCMA_POSSIBLE=y
CONFIG_VGA_ARB=y
CONFIG_VGA_ARB_MAX_GPUS=16
CONFIG_VGA_CONSOLE=y
CONFIG_DUMMY_CONSOLE=y
CONFIG_HID=y
CONFIG_HIDRAW=y
CONFIG_HID_GENERIC=y
CONFIG_HID_A4TECH=y
CONFIG_HID_APPLE=y
CONFIG_HID_BELKIN=y
CONFIG_HID_CHERRY=y
CONFIG_HID_CHICONY=y
CONFIG_HID_CYPRESS=y
CONFIG_HID_EZKEY=y
CONFIG_HID_KENSINGTON=y
CONFIG_HID_LOGITECH=y
CONFIG_HID_MICROSOFT=y
CONFIG_HID_MONTEREY=y
CONFIG_USB_HID=y
CONFIG_USB_HIDDEV=y
CONFIG_USB_OHCI_LITTLE_ENDIAN=y
CONFIG_USB_SUPPORT=y
CONFIG_USB_COMMON=y
CONFIG_USB_ARCH_HAS_HCD=y
CONFIG_USB=y
CONFIG_USB_DEFAULT_PERSIST=y
CONFIG_USB_XHCI_HCD=y
CONFIG_USB_EHCI_HCD=y
CONFIG_USB_EHCI_ROOT_HUB_TT=y
CONFIG_USB_EHCI_TT_NEWSCHED=y
CONFIG_USB_EHCI_PCI=y
CONFIG_USB_EHCI_HCD_PLATFORM=y
CONFIG_USB_UHCI_HCD=y
CONFIG_USB_ACM=y
CONFIG_USB_WDM=y
CONFIG_USB_STORAGE=y
CONFIG_USB_SERIAL=y
CONFIG_USB_SERIAL_CONSOLE=y
CONFIG_USB_SERIAL_GENERIC=y
CONFIG_USB_SERIAL_FTDI_SIO=y
CONFIG_USB_SERIAL_PL2303=y
CONFIG_USB_SERIAL_WWAN=y
CONFIG_USB_SERIAL_OPTION=y
CONFIG_EDAC=y
CONFIG_EDAC_MM_EDAC=y
CONFIG_EDAC_GHES=y
CONFIG_EDAC_I7CORE=y
CONFIG_EDAC_SBRIDGE=y
CONFIG_RTC_LIB=y
CONFIG_RTC_CLASS=y
CONFIG_RTC_HCTOSYS=y
CONFIG_RTC_SYSTOHC=y
CONFIG_RTC_HCTOSYS_DEVICE="rtc0"
CONFIG_RTC_INTF_SYSFS=y
CONFIG_RTC_INTF_PROC=y
CONFIG_RTC_INTF_DEV=y
CONFIG_RTC_DRV_CMOS=y
CONFIG_DMADEVICES=y
CONFIG_INTEL_IOATDMA=y
CONFIG_DMA_ENGINE=y
CONFIG_DMA_ACPI=y
CONFIG_ASYNC_TX_DMA=y
CONFIG_DMA_ENGINE_RAID=y
CONFIG_DCA=y
CONFIG_CLKEVT_I8253=y
CONFIG_I8253_LOCK=y
CONFIG_CLKBLD_I8253=y
CONFIG_FIRMWARE_MEMMAP=y
CONFIG_DMIID=y
CONFIG_DMI_SCAN_MACHINE_NON_EFI_FALLBACK=y
CONFIG_UEFI_CPER=y
CONFIG_DCACHE_WORD_ACCESS=y
CONFIG_EXT4_FS=y
CONFIG_EXT4_USE_FOR_EXT23=y
CONFIG_JBD2=y
CONFIG_FS_MBCACHE=y
CONFIG_EXPORTFS=y
CONFIG_FILE_LOCKING=y
CONFIG_FSNOTIFY=y
CONFIG_INOTIFY_USER=y
CONFIG_FANOTIFY=y
CONFIG_FUSE_FS=y
CONFIG_CUSE=y
CONFIG_ISO9660_FS=y
CONFIG_JOLIET=y
CONFIG_ZISOFS=y
CONFIG_UDF_FS=y
CONFIG_UDF_NLS=y
CONFIG_FAT_FS=y
CONFIG_MSDOS_FS=y
CONFIG_VFAT_FS=y
CONFIG_FAT_DEFAULT_CODEPAGE=437
CONFIG_FAT_DEFAULT_IOCHARSET="iso8859-1"
CONFIG_PROC_FS=y
CONFIG_PROC_SYSCTL=y
CONFIG_PROC_PAGE_MONITOR=y
CONFIG_SYSFS=y
CONFIG_TMPFS=y
CONFIG_HUGETLBFS=y
CONFIG_HUGETLB_PAGE=y
CONFIG_CONFIGFS_FS=y
CONFIG_MISC_FILESYSTEMS=y
CONFIG_PSTORE=y
CONFIG_NLS=y
CONFIG_NLS_DEFAULT="utf8"
CONFIG_NLS_CODEPAGE_437=y
CONFIG_NLS_CODEPAGE_855=y
CONFIG_NLS_CODEPAGE_866=y
CONFIG_NLS_CODEPAGE_1251=y
CONFIG_NLS_ASCII=y
CONFIG_NLS_ISO8859_1=y
CONFIG_NLS_ISO8859_5=y
CONFIG_NLS_ISO8859_15=y
CONFIG_NLS_KOI8_R=y
CONFIG_NLS_UTF8=y
CONFIG_TRACE_IRQFLAGS_SUPPORT=y
CONFIG_PRINTK_TIME=y
CONFIG_DEFAULT_MESSAGE_LOGLEVEL=4
CONFIG_FRAME_WARN=1024
CONFIG_STRIP_ASM_SYMS=y
CONFIG_ARCH_WANT_FRAME_POINTERS=y
CONFIG_MAGIC_SYSRQ=y
CONFIG_MAGIC_SYSRQ_DEFAULT_ENABLE=0x1
CONFIG_HAVE_DEBUG_KMEMLEAK=y
CONFIG_DEBUG_MEMORY_INIT=y
CONFIG_HAVE_DEBUG_STACKOVERFLOW=y
CONFIG_HAVE_ARCH_KMEMCHECK=y
CONFIG_PANIC_ON_OOPS_VALUE=0
CONFIG_PANIC_TIMEOUT=0
CONFIG_DEBUG_BUGVERBOSE=y
CONFIG_RCU_CPU_STALL_TIMEOUT=60
CONFIG_ARCH_HAS_DEBUG_STRICT_USER_COPY_CHECKS=y
CONFIG_USER_STACKTRACE_SUPPORT=y
CONFIG_HAVE_FUNCTION_TRACER=y
CONFIG_HAVE_FUNCTION_GRAPH_TRACER=y
CONFIG_HAVE_FUNCTION_GRAPH_FP_TEST=y
CONFIG_HAVE_FUNCTION_TRACE_MCOUNT_TEST=y
CONFIG_HAVE_DYNAMIC_FTRACE=y
CONFIG_HAVE_DYNAMIC_FTRACE_WITH_REGS=y
CONFIG_HAVE_FTRACE_MCOUNT_RECORD=y
CONFIG_HAVE_SYSCALL_TRACEPOINTS=y
CONFIG_HAVE_FENTRY=y
CONFIG_HAVE_C_RECORDMCOUNT=y
CONFIG_TRACING_SUPPORT=y
CONFIG_HAVE_ARCH_KGDB=y
CONFIG_STRICT_DEVMEM=y
CONFIG_X86_VERBOSE_BOOTUP=y
CONFIG_EARLY_PRINTK=y
CONFIG_DOUBLEFAULT=y
CONFIG_HAVE_MMIOTRACE_SUPPORT=y
CONFIG_IO_DELAY_TYPE_0X80=0
CONFIG_IO_DELAY_TYPE_0XED=1
CONFIG_IO_DELAY_TYPE_UDELAY=2
CONFIG_IO_DELAY_TYPE_NONE=3
CONFIG_IO_DELAY_0X80=y
CONFIG_DEFAULT_IO_DELAY_TYPE=0
CONFIG_OPTIMIZE_INLINING=y
CONFIG_DEFAULT_SECURITY_DAC=y
CONFIG_DEFAULT_SECURITY=""
CONFIG_XOR_BLOCKS=y
CONFIG_ASYNC_CORE=y
CONFIG_ASYNC_MEMCPY=y
CONFIG_ASYNC_XOR=y
CONFIG_ASYNC_PQ=y
CONFIG_ASYNC_RAID6_RECOV=y
CONFIG_CRYPTO=y
CONFIG_CRYPTO_ALGAPI=y
CONFIG_CRYPTO_ALGAPI2=y
CONFIG_CRYPTO_AEAD=y
CONFIG_CRYPTO_AEAD2=y
CONFIG_CRYPTO_BLKCIPHER=y
CONFIG_CRYPTO_BLKCIPHER2=y
CONFIG_CRYPTO_HASH=y
CONFIG_CRYPTO_HASH2=y
CONFIG_CRYPTO_RNG2=y
CONFIG_CRYPTO_PCOMP2=y
CONFIG_CRYPTO_MANAGER=y
CONFIG_CRYPTO_MANAGER2=y
CONFIG_CRYPTO_USER=y
CONFIG_CRYPTO_GF128MUL=y
CONFIG_CRYPTO_PCRYPT=y
CONFIG_CRYPTO_WORKQUEUE=y
CONFIG_CRYPTO_CRYPTD=y
CONFIG_CRYPTO_ABLK_HELPER=y
CONFIG_CRYPTO_GLUE_HELPER_X86=y
CONFIG_CRYPTO_CBC=y
CONFIG_CRYPTO_LRW=y
CONFIG_CRYPTO_XTS=y
CONFIG_CRYPTO_CMAC=y
CONFIG_CRYPTO_HMAC=y
CONFIG_CRYPTO_XCBC=y
CONFIG_CRYPTO_VMAC=y
CONFIG_CRYPTO_CRC32C=y
CONFIG_CRYPTO_CRC32C_INTEL=y
CONFIG_CRYPTO_CRC32=y
CONFIG_CRYPTO_CRC32_PCLMUL=y
CONFIG_CRYPTO_CRCT10DIF=y
CONFIG_CRYPTO_CRCT10DIF_PCLMUL=y
CONFIG_CRYPTO_SHA1=y
CONFIG_CRYPTO_SHA1_SSSE3=y
CONFIG_CRYPTO_SHA256_SSSE3=y
CONFIG_CRYPTO_SHA512_SSSE3=y
CONFIG_CRYPTO_SHA256=y
CONFIG_CRYPTO_SHA512=y
CONFIG_CRYPTO_GHASH_CLMUL_NI_INTEL=y
CONFIG_CRYPTO_AES=y
CONFIG_CRYPTO_AES_X86_64=y
CONFIG_CRYPTO_AES_NI_INTEL=y
CONFIG_HAVE_KVM=y
CONFIG_RAID6_PQ=y
CONFIG_BITREVERSE=y
CONFIG_GENERIC_STRNCPY_FROM_USER=y
CONFIG_GENERIC_STRNLEN_USER=y
CONFIG_GENERIC_NET_UTILS=y
CONFIG_GENERIC_FIND_FIRST_BIT=y
CONFIG_GENERIC_PCI_IOMAP=y
CONFIG_GENERIC_IOMAP=y
CONFIG_GENERIC_IO=y
CONFIG_ARCH_USE_CMPXCHG_LOCKREF=y
CONFIG_CRC_CCITT=y
CONFIG_CRC16=y
CONFIG_CRC_T10DIF=y
CONFIG_CRC_ITU_T=y
CONFIG_CRC32=y
CONFIG_CRC32_SLICEBY8=y
CONFIG_LIBCRC32C=y
CONFIG_ZLIB_INFLATE=y
CONFIG_ZLIB_DEFLATE=y
CONFIG_GENERIC_ALLOCATOR=y
CONFIG_HAS_IOMEM=y
CONFIG_HAS_IOPORT=y
CONFIG_HAS_DMA=y
CONFIG_CHECK_SIGNATURE=y
CONFIG_CPU_RMAP=y
CONFIG_DQL=y
CONFIG_NLATTR=y
CONFIG_ARCH_HAS_ATOMIC64_DEC_IF_POSITIVE=y
CONFIG_DDR=y


Запускаем компиляцию и сборку в deb-пакет:
# cd /usr/src/linux-3.14.xx
# fakeroot make-kpkg clean
# CONCURRENCY_LEVEL=12 fakeroot make-kpkg --us --uc --jobs 12 --stem=kernel-scst --revision=1 kernel_image

Затем выкачиваем SCST, собираем и устанавливаем (указываем путь к исходникам ядра):
# svn checkout svn://svn.code.sf.net/p/scst/svn/branches/3.0.x scst-svn
# cd scst-svn
# BUILD_2X_MODULE=y CONFIG_SCSI_QLA_FC=y CONFIG_SCSI_QLA2XXX_TARGET=y KDIR="/usr/src/linux-3.14.xx" make all install

Более развёрнутую инструкцию по установке SCST с драйвером под QLogic можно найти на сайте проекта (но там собирается драйвер QLogic из их GIT дерева, который мне не показался особо стабильным. Мы же возьмём драйвер из комплекта SCST).

В результате мы получили пакет с ядром + директорию /lib/modules/3.14.xx/extra с модулями SCST, которые нужно будет скопировать вручную на сервера. Можно, конечно, придумать способ интеграции их прямо в .deb пакет, но мне было лень.

Для работы FC карт также нужна прошивка, которую можно как залить в адаптер (точнее — обновить, ибо какая-то там уже есть), так и просто положить в /lib/firmware и драйвер при загрузке её оттуда подтянет. Я, для верности, да и производитель рекомендует, сделал и то и то. Прошить можно либо через линуксовую утилиту от QLogic — qaucli, либо из под FreeDOS (или EFI) их же софтом с сайта.

Качаем прошивку (в нашем случае это ql2500_fw.bin) и кладём на место:
# mkdir -p /lib/firmware
# cd /lib/firmware
# wget http://ldriver.qlogic.com/firmware/ql2500_fw.bin

Далее нам понадобится утилита управления SCST под ёмким названием scstadmin и библиотеки, ей используемые. Саму утилиту берём в дереве исходников SCST: scstadmin/scstadmin.sysfs/scstadmin и кладём её на наши сервера куда-нибудь в /usr/bin, чтобы всем видно было. Затем берём директорию scstadmin/scstadmin.sysfs/scst-0.9.10/lib/SCST и кладём её в /usr/lib/perl/<версия Perl>.

Затем устанавливаем Pacemaker чтобы рулить нашим кластером и генерируем ключ авторизации.
Pacemaker будет переключать режимы ALUA в зависимости от состояния нод.

# apt-get -t wheezy-backports install pacemaker
# corosync-keygen

Файл-ключ /etc/corosync/authkey переносим на второй сервер в то же место.

Для управления SCST через Pacemaker нам понадобится «ресурс», который я утащил из проекта ESOS и подкрутил под себя.
Ресурс
#! /bin/sh
#
# $Id$

#
#   Resource Agent for managing the Generic SCSI Target Subsystem
#   for Linux (SCST) and related daemons.
#
#   License: GNU General Public License (GPL)
#   (c) 2012-2014 Marc A. Smith
#

# Initialization
: ${OCF_FUNCTIONS_DIR=${OCF_ROOT}/lib/heartbeat}
. ${OCF_FUNCTIONS_DIR}/ocf-shellfuncs
MODULES="scst scst_vdisk qla2x00tgt"
SCST_CFG="/etc/scst.conf"
PRE_SCST_CONF="/etc/pre-scst_xtra_conf"
POST_SCST_CONF="/etc/post-scst_xtra_conf"
SCST_SYSFS="/sys/kernel/scst_tgt"
ALUA_STATES="active nonoptimized standby unavailable offline transitioning"
NO_CLOBBER="/tmp/scst_ra-no_clobber"

# For optional SCST modules
if [ -f "/lib/modules/$(uname -r)/extra/ocs_fc_scst.ko" ]; then
    MODULES="${MODULES} ocs_fc_scst"
fi
if [ -f "/lib/modules/$(uname -r)/extra/chfcoe.ko" ]; then
    MODULES="${MODULES} chfcoe"
fi


scst_start() {
    # Exit immediately if configuration is not valid
    scst_validate_all || exit ${?}

    # If resource is already running, bail out early
    if scst_monitor; then
        ocf_log info "Resource is already running."
        return ${OCF_SUCCESS}
    fi

    # If our pre-SCST file exists, run it
    if [ -f "${PRE_SCST_CONF}" ]; then
        ocf_log info "Pre-SCST user config. file found; running..."
        ocf_run -warn sh "${PRE_SCST_CONF}"
    fi

    # Load all modules
    ocf_log info "Loading kernel modules..."
    for i in ${MODULES}; do
        ocf_log debug "scst_start() -> Module: ${i}"
        if [ -d /sys/module/${i} ]; then
            ocf_log warn "The ${i} module is already loaded!"
        else
            ocf_run modprobe ${i} || exit ${OCF_ERR_GENERIC}
        fi
    done

    # Configure SCST
    if [ -f "${SCST_CFG}" ]; then
        ocf_log info "Applying SCST configuration..."
        ocf_run scstadmin -config "${SCST_CFG}"
        # Prevent scst_stop() from clobbering the configuration file
        if [ ${?} -ne 0 ]; then
            ocf_log err "Something is wrong with the SCST configuration!"
            ocf_run touch "${NO_CLOBBER}"
            exit ${OCF_ERR_GENERIC}
        else
            if [ -f "${NO_CLOBBER}" ]; then
                ocf_run rm -f "${NO_CLOBBER}"
            fi
        fi
    fi

    # If our post-SCST file exists, run it
    if [ -f "${POST_SCST_CONF}" ]; then
        ocf_log info "Post-SCST user config. file found; running..."
        ocf_run -warn sh "${POST_SCST_CONF}"
    fi

    # If we are using ALUA, be sure we are using the "Slave" state initially
    if ocf_is_true ${OCF_RESKEY_alua}; then
        check_alua
        # Set the local target group ALUA state
        ocf_log debug "scst_start() -> Setting target group" \
            "'${OCF_RESKEY_local_tgt_grp}' ALUA state to" \
            "'${OCF_RESKEY_s_alua_state}'..."
        ocf_run scstadmin -noprompt -set_tgrp_attr \
            ${OCF_RESKEY_local_tgt_grp} -dev_group \
            ${OCF_RESKEY_device_group} -attributes \
            state\=${OCF_RESKEY_s_alua_state} || exit ${OCF_ERR_GENERIC}
        # For now, we simply assume the other node is the Master
        ocf_log debug "scst_start() -> Setting target group" \
            "'${OCF_RESKEY_remote_tgt_grp}' ALUA state to" \
            "'${OCF_RESKEY_m_alua_state}'..."
        ocf_run scstadmin -noprompt -set_tgrp_attr \
            ${OCF_RESKEY_remote_tgt_grp} -dev_group \
            ${OCF_RESKEY_device_group} -attributes \
            state\=${OCF_RESKEY_m_alua_state} || exit ${OCF_ERR_GENERIC}
    fi

    # Make sure the resource started correctly
    while ! scst_monitor; do
        ocf_log debug "scst_start() -> Resource has not started yet, waiting..."
        sleep 1
    done

    # Only return $OCF_SUCCESS if _everything_ succeeded as expected
    return ${OCF_SUCCESS}
}


scst_stop() {
    # Exit immediately if configuration is not valid
    scst_validate_all || exit ${?}

    # Check the current resource state
    scst_monitor
    local rc=${?}
    case "${rc}" in
    "${OCF_SUCCESS}")
        # Currently running; normal, expected behavior
        ocf_log info "Resource is currently running."
        ;;
    "${OCF_RUNNING_MASTER}")
        # Running as a Master; need to demote before stopping
        ocf_log info "Resource is currently running as Master."
        scst_demote || ocf_log warn "Demote failed, trying to stop anyway..."
        ;;
    "${OCF_NOT_RUNNING}")
        # Currently not running; nothing to do
        ocf_log info "Resource is already stopped."
        return ${OCF_SUCCESS}
        ;;
    esac

    # Unload the modules (in reverse)
    ocf_log info "Unloading kernel modules..."
    for i in $(echo ${MODULES} | tr ' ' '\n' | tac | tr '\n' ' '); do
        ocf_log debug "scst_stop() -> Module: ${i}"
        if [ -d /sys/module/${i} ]; then
            ocf_run rmmod -w ${i} || exit ${OCF_ERR_GENERIC}
        else
            ocf_log warn "The ${i} module is not loaded!"
        fi
    done

    # Make sure the resource stopped correctly
    while scst_monitor; do
        ocf_log info "scst_stop() -> Resource has not stopped yet, waiting..."
        sleep 1
    done

    # Only return $OCF_SUCCESS if _everything_ succeeded as expected
    return ${OCF_SUCCESS}
}


scst_monitor() {
    # Exit immediately if configuration is not valid
    scst_validate_all || exit ${?}

    # Check if SCST is loaded
    local rc
    if [ -e "${SCST_SYSFS}/version" ]; then
        ocf_log debug "scst_monitor() -> SCST version:" \
            "$(cat ${SCST_SYSFS}/version)"
        ocf_log debug "scst_monitor() -> Resource is running."
        crm_master -l reboot -v 100
        rc=${OCF_SUCCESS}
    else
        ocf_log debug "scst_monitor() -> Resource is not running."
        crm_master -l reboot -D
        rc=${OCF_NOT_RUNNING}
        return ${rc}
    fi

    # If we are using ALUA, then we can test if we are Master or not
    if ocf_is_true ${OCF_RESKEY_alua}; then
        dev_grp_path="${SCST_SYSFS}/device_groups/${OCF_RESKEY_device_group}"
        tgt_grp_path="${dev_grp_path}/target_groups/${OCF_RESKEY_local_tgt_grp}"
        tgt_grp_state="$(head -1 ${tgt_grp_path}/state)"
        ocf_log debug "scst_monitor() -> SCST local target" \
            "group state: ${tgt_grp_state}"
        if [ "x${tgt_grp_state}" = "x${OCF_RESKEY_m_alua_state}" ]; then
            rc=${OCF_RUNNING_MASTER}
        fi
    fi

    return ${rc}
}


scst_validate_all() {
    # Test for required binaries
    check_binary scstadmin

    # There can only be one instance of SCST running per node
    if [ ! -z "${OCF_RESKEY_CRM_meta_clone_node_max}" ] &&
        [ "${OCF_RESKEY_CRM_meta_clone_node_max}" -ne 1 ]; then
        ocf_log err "The 'clone-node-max' parameter must equal '1'."
        exit ${OCF_ERR_CONFIGURED}
    fi

    # If ALUA support is enabled, we need to check the parameters
    if ocf_is_true ${OCF_RESKEY_alua}; then
        # Make sure they are set to something
        if [ -z "${OCF_RESKEY_device_group}" ]; then
            ocf_log err "The 'device_group' parameter is not set!"
            exit ${OCF_ERR_CONFIGURED}
        fi
        if [ -z "${OCF_RESKEY_local_tgt_grp}" ]; then
            ocf_log err "The 'local_tgt_grp' parameter is not set!"
            exit ${OCF_ERR_CONFIGURED}
        fi
        if [ -z "${OCF_RESKEY_remote_tgt_grp}" ]; then
            ocf_log err "The 'remote_tgt_grp' parameter is not set!"
            exit ${OCF_ERR_CONFIGURED}
        fi
        if [ -z "${OCF_RESKEY_m_alua_state}" ]; then
            ocf_log err "The 'm_alua_state' parameter is not set!"
            exit ${OCF_ERR_CONFIGURED}
        fi
        if [ -z "${OCF_RESKEY_s_alua_state}" ]; then
            ocf_log err "The 's_alua_state' parameter is not set!"
            exit ${OCF_ERR_CONFIGURED}
        fi
        #  Currently, we only support using one Master with this RA
        if [ ! -z "${OCF_RESKEY_CRM_meta_master_max}" ] &&
            [ "${OCF_RESKEY_CRM_meta_master_max}" -ne 1 ]; then
            ocf_log err "The 'master-max' parameter must equal '1'."
            exit ${OCF_ERR_CONFIGURED}
        fi
        if [ ! -z "${OCF_RESKEY_CRM_meta_master_node_max}" ] &&
            [ "${OCF_RESKEY_CRM_meta_master_node_max}" -ne 1 ]; then
            ocf_log err "The 'master-node-max' parameter must equal '1'."
            exit ${OCF_ERR_CONFIGURED}
        fi
    fi

    return ${OCF_SUCCESS}
}


scst_meta_data() {
	cat <<-EOF
	<?xml version="1.0"?>
	<!DOCTYPE resource-agent SYSTEM "ra-api-1.dtd">
	<resource-agent name="scst" version="0.1">
	  <version>0.1</version>
	  <longdesc lang="en">The SCST OCF resource agent for ESOS; includes SCST ALUA support.</longdesc>
	  <shortdesc lang="en">SCST OCF RA script for ESOS.</shortdesc>
	  <parameters>
	    <parameter name="alua" unique="0" required="0">
	      <longdesc lang="en">Use to enable/disable updating ALUA status in SCST.</longdesc>
	      <shortdesc lang="en">The 'alua' parameter.</shortdesc>
	      <content type="boolean" default="false" />
	    </parameter>
	    <parameter name="device_group" unique="0" required="0">
	      <longdesc lang="en">The name of the SCST device group (used with ALUA support).</longdesc>
	      <shortdesc lang="en">The 'device_group' parameter.</shortdesc>
	      <content type="string" default="" />
	    </parameter>
	    <parameter name="local_tgt_grp" unique="0" required="0">
	      <longdesc lang="en">The name of the SCST local target group (used with ALUA support).</longdesc>
	      <shortdesc lang="en">The 'local_tgt_grp' parameter.</shortdesc>
	      <content type="string" default="" />
	    </parameter>
	    <parameter name="remote_tgt_grp" unique="0" required="0">
	      <longdesc lang="en">The name of the SCST remote target group (used with ALUA support).</longdesc>
	      <shortdesc lang="en">The 'remote_tgt_grp' parameter.</shortdesc>
	      <content type="string" default="" />
	    </parameter>
	    <parameter name="m_alua_state" unique="0" required="0">
	      <longdesc lang="en">The ALUA state (eg, active) for a Master node (used with ALUA support).</longdesc>
	      <shortdesc lang="en">The 'm_alua_state' parameter.</shortdesc>
	      <content type="string" default="active" />
	    </parameter>
	    <parameter name="s_alua_state" unique="0" required="0">
	      <longdesc lang="en">The ALUA state (eg, nonoptimized) for a Slave node (used with ALUA support).</longdesc>
	      <shortdesc lang="en">The 's_alua_state' parameter.</shortdesc>
	      <content type="string" default="nonoptimized" />
	    </parameter>
	  </parameters>
	  <actions>
	    <action name="meta-data" timeout="5" />
	    <action name="start" timeout="120" />
	    <action name="stop" timeout="60" />
	    <action name="monitor" timeout="20" depth="0" interval="10" role="Master" />
	    <action name="monitor" timeout="20" depth="0" interval="20" role="Slave" />
	    <action name="notify" timeout="20" />
	    <action name="promote" timeout="20" />
	    <action name="demote" timeout="20" />
	    <action name="reload" timeout="20" />
	    <action name="validate-all" timeout="20" />
	  </actions>
	</resource-agent>
	EOF
}


scst_usage() {
    echo "usage: ${0} {start|stop|monitor|validate-all|promote|demote|reload|notify|meta-data}"
    echo ""
    echo "Expects to have a fully populated OCF RA-compliant environment set."
}


scst_promote() {
    # Exit immediately if configuration is not valid
    scst_validate_all || exit ${?}

    # Test the resource's current state
    scst_monitor
    local rc=${?}
    case "${rc}" in
    "${OCF_SUCCESS}")
        # Running as Slave; normal, expected behavior
        ocf_log debug "scst_promote() -> Resource is" \
            "currently running as Slave."
        ;;
    "${OCF_RUNNING_MASTER}")
        # Already a Master; unexpected, but not a problem
        ocf_log info "Resource is already running as Master."
        return ${OCF_SUCCESS}
        ;;
    "${OCF_NOT_RUNNING}")
        # Currently not running; need to start before promoting
        ocf_log info "Resource is currently not running."
        scst_start
        ;;
    *)
        # Failed resource; let the cluster manager recover
        ocf_log err "Unexpected error, cannot promote."
        exit ${rc}
        ;;
    esac

    # Promote only makes sense if we are using ALUA
    if ocf_is_true ${OCF_RESKEY_alua}; then
        check_alua
        # Set the local target group to the "Master" ALUA state
        ocf_log debug "scst_promote() -> Setting target group" \
            "'${OCF_RESKEY_local_tgt_grp}' ALUA state to" \
            "'${OCF_RESKEY_m_alua_state}'..."
        ocf_run scstadmin -noprompt -set_tgrp_attr \
            ${OCF_RESKEY_local_tgt_grp} -dev_group \
            ${OCF_RESKEY_device_group} -attributes \
            state\=${OCF_RESKEY_m_alua_state} || exit ${OCF_ERR_GENERIC}
        # Since there can only be one Master, set the remote target group
        ocf_log debug "scst_promote() -> Setting target group" \
            "'${OCF_RESKEY_remote_tgt_grp}' ALUA state to" \
            "'${OCF_RESKEY_s_alua_state}'..."
        ocf_run scstadmin -noprompt -set_tgrp_attr \
            ${OCF_RESKEY_remote_tgt_grp} -dev_group \
            ${OCF_RESKEY_device_group} -attributes \
            state\=${OCF_RESKEY_s_alua_state} || exit ${OCF_ERR_GENERIC}
    else
        ocf_log err "The ALUA parameters need to be configured before using MS."
        exit ${OCF_ERR_CONFIGURED}
    fi

    # After the resource has been promoted, check whether the promotion worked
    while true; do
        scst_monitor
        if [ ${?} -eq ${OCF_RUNNING_MASTER} ]; then
            ocf_log info "Resource was promoted successfully."
            break
        else
            ocf_log debug "scst_promote() -> Resource still" \
                "awaiting promotion."
            sleep 1
        fi
    done

    # Only return $OCF_SUCCESS if _everything_ succeeded as expected
    return ${OCF_SUCCESS}
}


scst_demote() {
    # Exit immediately if configuration is not valid
    scst_validate_all || exit ${?}

    # Test the resource's current state
    scst_monitor
    local rc=${?}
    case "${rc}" in
    "${OCF_RUNNING_MASTER}")
        # Running as Master; normal, expected behavior
        ocf_log debug "scst_demote() -> Resource is" \
            "currently running as Master."
        ;;
    "${OCF_SUCCESS}")
        # Already running as Slave; nothing to do
        ocf_log debug "scst_demote() -> Resource is" \
            "currently running as Slave."
        return ${OCF_SUCCESS}
        ;;
    "${OCF_NOT_RUNNING}")
        # Not running; getting a demote action in this state is unexpected
        ocf_log err "Resource is currently not running."
        exit ${OCF_ERR_GENERIC}
        ;;
    *)
        # Failed resource; let the cluster manager recover
        ocf_log err "Unexpected error, cannot demote."
        exit ${rc}
        ;;
    esac

    # Demote only makes sense if we are using ALUA
    if ocf_is_true ${OCF_RESKEY_alua}; then
        check_alua
        # Set the local target group to the "Slave" ALUA state
        ocf_log debug "scst_demote() -> Setting target group" \
            "'${OCF_RESKEY_local_tgt_grp}' ALUA state to" \
            "'${OCF_RESKEY_s_alua_state}'..."
        ocf_run scstadmin -noprompt -set_tgrp_attr \
            ${OCF_RESKEY_local_tgt_grp} -dev_group \
            ${OCF_RESKEY_device_group} -attributes \
            state\=${OCF_RESKEY_s_alua_state} || exit ${OCF_ERR_GENERIC}
        # If we're a Slave, we assume the remote side is the Master
        ocf_log debug "scst_demote() -> Setting target group" \
            "'${OCF_RESKEY_remote_tgt_grp}' ALUA state to" \
            "'${OCF_RESKEY_m_alua_state}'..."
        ocf_run scstadmin -noprompt -set_tgrp_attr \
            ${OCF_RESKEY_remote_tgt_grp} -dev_group \
            ${OCF_RESKEY_device_group} -attributes \
            state\=${OCF_RESKEY_m_alua_state} || exit ${OCF_ERR_GENERIC}
    else
        ocf_log err "The ALUA parameters need to be configured before using MS."
        exit ${OCF_ERR_CONFIGURED}
    fi

    # After the resource has been demoted, check whether the demotion worked
    while true; do
        scst_monitor
        if [ ${?} -eq ${OCF_RUNNING_MASTER} ]; then
            ocf_log debug "scst_demote() -> Resource still" \
                "awaiting demotion."
            sleep 1
        else
            ocf_log info "Resource was demoted successfully."
            break
        fi
    done

    # Only return $OCF_SUCCESS if _everything_ succeeded as expected
    return ${OCF_SUCCESS}
}


scst_notify() {
    # We're currently not using this
    ocf_log debug "scst_notify() -> Received a" \
        "'${OCF_RESKEY_CRM_meta_notify_type}' /" \
        "'${OCF_RESKEY_CRM_meta_notify_operation}' notification."

    return ${OCF_SUCCESS}
}


check_alua() {
    # Make sure the directories exist in the SCST sysfs structure
    if [ ! -d "${SCST_SYSFS}/device_groups/${OCF_RESKEY_device_group}" ]; then
        ocf_log err "The '${OCF_RESKEY_device_group}' device group does not exist!"
        exit ${OCF_ERR_INSTALLED}
    fi
    target_groups="${SCST_SYSFS}/device_groups/${OCF_RESKEY_device_group}/target_groups"
    if [ ! -d "${target_groups}/${OCF_RESKEY_local_tgt_grp}" ]; then
        ocf_log err "The '${OCF_RESKEY_local_tgt_grp}' target group does not exist!"
        exit ${OCF_ERR_INSTALLED}
    fi
    if [ ! -d "${target_groups}/${OCF_RESKEY_remote_tgt_grp}" ]; then
        ocf_log err "The '${OCF_RESKEY_remote_tgt_grp}' target group does not exist!"
        exit ${OCF_ERR_INSTALLED}
    fi

    # Check that the given ALUA states are valid
    local valid_m_alua_state=0
    local valid_s_alua_state=0
    for i in ${ALUA_STATES}; do
        if [ "x${OCF_RESKEY_m_alua_state}" = "x${i}" ]; then
            valid_m_alua_state=1
        fi
        if [ "x${OCF_RESKEY_s_alua_state}" = "x${i}" ]; then
            valid_s_alua_state=1
        fi
    done
    if [ ${valid_m_alua_state} -eq 0 ]; then
        ocf_log err "The 'm_alua_state' value is not valid: ${OCF_RESKEY_m_alua_state}"
        exit ${OCF_ERR_INSTALLED}
    fi
    if [ ${valid_s_alua_state} -eq 0 ]; then
        ocf_log err "The 's_alua_state' value is not valid: ${OCF_RESKEY_s_alua_state}"
        exit ${OCF_ERR_INSTALLED}
    fi
}


# Make sure meta-data and usage always succeed
case ${__OCF_ACTION} in
meta-data)
    scst_meta_data
    exit ${OCF_SUCCESS}
    ;;
usage|help)
    scst_usage
    exit ${OCF_SUCCESS}
    ;;
esac

# Anything other than meta-data and usage must pass validation
scst_validate_all || exit ${?}

# Translate each action into the appropriate function call
case ${__OCF_ACTION} in
start)
    scst_start
    ;;
stop)
    scst_stop
    ;;
status|monitor)
    scst_monitor
    ;;
notify)
    scst_notify
    ;;
promote)
    scst_promote
    ;;
demote)
    scst_demote
    ;;
reload)
    ocf_log info "Reloading..."
    scst_start
    ;;
validate-all)
    ;;
migrate_to|migrate_from)
    scst_usage
    exit ${OCF_ERR_UNIMPLEMENTED}
    ;;
*)
    scst_usage
    exit ${OCF_ERR_UNIMPLEMENTED}
    ;;
esac

# Log a debug message and exit
rc=${?}
ocf_log debug "${OCF_RESOURCE_INSTANCE} ${__OCF_ACTION} returned: ${rc}"
exit ${rc}


Сей файл нужно положить под именем /usr/lib/ocf/resource.d/esos/scst и сделать исполняемым.

Так как для устойчивости кластера двух нод мало (будет Split-Brain если связность нарушится), то у нас будет ещё третья нода, которая будет создавать кворум, но никаких ресурсов исполнять не будет. Тут вступает в игру такая особенность Pacemaker, что «здоровье» ресурсов проверяется на всех нодах кластера вне зависимости от того может ли там исполняться этот ресурс вообще или нет (в новых версиях вроде добавили какой-то признак, отключающий эту фичу, но в версии из репозитория Debian такого счастья еще вроде нет). Поэтому для кворум-ноды нам понадобится фейковый ресурс который будет просто говорить «в Багдаде всё спокойно».
Фейковый ресурс
#! /bin/sh
#
# $Id$

#
#   Resource Agent for managing the Generic SCSI Target Subsystem
#   for Linux (SCST) and related daemons.
#
#   License: GNU General Public License (GPL)
#   (c) 2012-2014 Marc A. Smith
#

# Initialization
: ${OCF_FUNCTIONS_DIR=${OCF_ROOT}/lib/heartbeat}
. ${OCF_FUNCTIONS_DIR}/ocf-shellfuncs
MODULES="scst scst_vdisk qla2x00tgt"
SCST_CFG="/etc/scst.conf"
PRE_SCST_CONF="/etc/pre-scst_xtra_conf"
POST_SCST_CONF="/etc/post-scst_xtra_conf"
SCST_SYSFS="/sys/kernel/scst_tgt"
ALUA_STATES="active nonoptimized standby unavailable offline transitioning"
NO_CLOBBER="/tmp/scst_ra-no_clobber"

scst_monitor() {
    return ${OCF_NOT_RUNNING}
}

scst_meta_data() {
	cat <<-EOF
	<?xml version="1.0"?>
	<!DOCTYPE resource-agent SYSTEM "ra-api-1.dtd">
	<resource-agent name="scst" version="0.1">
	  <version>0.1</version>
	  <longdesc lang="en">The SCST OCF resource agent for ESOS; includes SCST ALUA support.</longdesc>
	  <shortdesc lang="en">SCST OCF RA script for ESOS.</shortdesc>
	  <parameters>
	    <parameter name="alua" unique="0" required="0">
	      <longdesc lang="en">Use to enable/disable updating ALUA status in SCST.</longdesc>
	      <shortdesc lang="en">The 'alua' parameter.</shortdesc>
	      <content type="boolean" default="false" />
	    </parameter>
	    <parameter name="device_group" unique="0" required="0">
	      <longdesc lang="en">The name of the SCST device group (used with ALUA support).</longdesc>
	      <shortdesc lang="en">The 'device_group' parameter.</shortdesc>
	      <content type="string" default="" />
	    </parameter>
	    <parameter name="local_tgt_grp" unique="0" required="0">
	      <longdesc lang="en">The name of the SCST local target group (used with ALUA support).</longdesc>
	      <shortdesc lang="en">The 'local_tgt_grp' parameter.</shortdesc>
	      <content type="string" default="" />
	    </parameter>
	    <parameter name="remote_tgt_grp" unique="0" required="0">
	      <longdesc lang="en">The name of the SCST remote target group (used with ALUA support).</longdesc>
	      <shortdesc lang="en">The 'remote_tgt_grp' parameter.</shortdesc>
	      <content type="string" default="" />
	    </parameter>
	    <parameter name="m_alua_state" unique="0" required="0">
	      <longdesc lang="en">The ALUA state (eg, active) for a Master node (used with ALUA support).</longdesc>
	      <shortdesc lang="en">The 'm_alua_state' parameter.</shortdesc>
	      <content type="string" default="active" />
	    </parameter>
	    <parameter name="s_alua_state" unique="0" required="0">
	      <longdesc lang="en">The ALUA state (eg, nonoptimized) for a Slave node (used with ALUA support).</longdesc>
	      <shortdesc lang="en">The 's_alua_state' parameter.</shortdesc>
	      <content type="string" default="nonoptimized" />
	    </parameter>
	  </parameters>
	  <actions>
	    <action name="meta-data" timeout="5" />
	    <action name="start" timeout="120" />
	    <action name="stop" timeout="60" />
	    <action name="monitor" timeout="20" depth="0" interval="10" role="Master" />
	    <action name="monitor" timeout="20" depth="0" interval="20" role="Slave" />
	    <action name="notify" timeout="20" />
	    <action name="promote" timeout="20" />
	    <action name="demote" timeout="20" />
	    <action name="reload" timeout="20" />
	    <action name="validate-all" timeout="20" />
	  </actions>
	</resource-agent>
	EOF
}

scst_usage() {
    echo "usage: ${0} {start|stop|monitor|validate-all|promote|demote|reload|notify|meta-data}"
    echo ""
    echo "Expects to have a fully populated OCF RA-compliant environment set."
}

# Make sure meta-data and usage always succeed
case ${__OCF_ACTION} in
meta-data)
    scst_meta_data
    exit ${OCF_SUCCESS}
    ;;
usage|help)
    scst_usage
    exit ${OCF_SUCCESS}
    ;;
esac

# Translate each action into the appropriate function call
case ${__OCF_ACTION} in
start)
    ;;
stop)
    ;;
status|monitor)
    scst_monitor
    ;;
notify)
    ;;
promote)
    ;;
demote)
    ;;
reload)
    ocf_log info "Reloading..."
    ;;
validate-all)
    ;;
migrate_to|migrate_from)
    scst_usage
    exit ${OCF_ERR_UNIMPLEMENTED}
    ;;
*)
    scst_usage
    exit ${OCF_ERR_UNIMPLEMENTED}
    ;;
esac

# Log a debug message and exit
rc=${?}
ocf_log debug "${OCF_RESOURCE_INSTANCE} ${__OCF_ACTION} returned: ${rc}"
exit ${rc}



Его положить на кворум-ноду аналогично основным нодам.

Так, напоследок создадим массивы и настроим конфигурацию SCST.
Для первой части, наверное, хватит.

Поглядим какие девайсы у нас есть:
storcli64 /c0/eall/sall show
Controller = 0
Status = Success
Description = Show Drive Information Succeeded.


Drive Information :
=================

-------------------------------------------------------------------------
EID:Slt DID State DG       Size Intf Med SED PI SeSz Model            Sp 
-------------------------------------------------------------------------
37:0     61 UGood   - 372.093 GB SAS  SSD N   N  512B S842E400M2       U  
37:1     62 UGood   - 372.093 GB SAS  SSD N   N  512B S842E400M2       U  
37:2     63 UGood   - 372.093 GB SAS  SSD N   N  512B S842E400M2       U  
37:3     64 UGood   - 372.093 GB SAS  SSD N   N  512B S842E400M2       U  
37:4     65 UGood   - 372.093 GB SAS  SSD N   N  512B S842E400M2       U  
37:5     66 UGood   - 372.093 GB SAS  SSD N   N  512B S842E400M2       U  
37:6     67 UGood   - 372.093 GB SAS  SSD N   N  512B S842E400M2       U  
37:7     68 UGood   - 372.093 GB SAS  SSD N   N  512B S842E400M2       U  
37:8     69 UGood   - 372.093 GB SAS  SSD N   N  512B S842E400M2       U  
37:9     70 UGood   - 372.093 GB SAS  SSD N   N  512B S842E400M2       U  
37:10    71 UGood   - 372.093 GB SAS  SSD N   N  512B S842E400M2       U  
37:11    72 UGood   - 372.093 GB SAS  SSD N   N  512B S842E400M2       U  
37:12    73 UGood   - 372.093 GB SAS  SSD N   N  512B S842E400M2       U  
37:13    74 UGood   - 372.093 GB SAS  SSD N   N  512B S842E400M2       U  
37:14    75 UGood   - 372.093 GB SAS  SSD N   N  512B S842E400M2       U  
37:15    76 UGood   - 372.093 GB SAS  SSD N   N  512B S842E400M2       U  
37:16    77 UGood   - 372.093 GB SAS  SSD N   N  512B S842E400M2       U  
37:17    78 UGood   - 372.093 GB SAS  SSD N   N  512B S842E400M2       U  
37:18    15 UGood   - 372.093 GB SAS  SSD N   N  512B S842E400M2       U  
37:19    19 UGood   - 372.093 GB SAS  SSD N   N  512B S842E400M2       U  
37:20    79 UGood   - 372.093 GB SAS  SSD N   N  512B S842E400M2       U  
37:21    80 UGood   - 372.093 GB SAS  SSD N   N  512B S842E400M2       U  
37:22    81 UGood   - 372.093 GB SAS  SSD N   N  512B S842E400M2       U  
37:23    82 UGood   - 372.093 GB SAS  SSD N   N  512B S842E400M2       U  
59:0      8 UGood   - 372.093 GB SAS  SSD N   N  512B S842E400M2       U  
59:1      9 UGood   - 372.093 GB SAS  SSD N   N  512B S842E400M2       U  
59:2     10 UGood   - 372.093 GB SAS  SSD N   N  512B S842E400M2       U  
59:3     11 UGood   - 372.093 GB SAS  SSD N   N  512B S842E400M2       U  
59:4     12 UGood   - 372.093 GB SAS  SSD N   N  512B S842E400M2       U  
59:5     14 UGood   - 372.093 GB SAS  SSD N   N  512B S842E400M2       U  
59:6     21 UGood   - 372.093 GB SAS  SSD N   N  512B S842E400M2       U  
59:7     22 UGood   - 372.093 GB SAS  SSD N   N  512B S842E400M2       U  
59:8     23 UGood   - 372.093 GB SAS  SSD N   N  512B S842E400M2       U  
59:9     24 UGood   - 372.093 GB SAS  SSD N   N  512B S842E400M2       U  
59:10    18 UGood   - 372.093 GB SAS  SSD N   N  512B S842E400M2       U  
59:11    17 UGood   - 372.093 GB SAS  SSD N   N  512B S842E400M2       U  
59:12    25 UGood   - 372.093 GB SAS  SSD N   N  512B S842E400M2       U  
59:13    26 UGood   - 372.093 GB SAS  SSD N   N  512B S842E400M2       U  
59:14    16 UGood   - 372.093 GB SAS  SSD N   N  512B S842E400M2       U  
59:15    27 UGood   - 372.093 GB SAS  SSD N   N  512B S842E400M2       U  
59:16    28 UGood   - 372.093 GB SAS  SSD N   N  512B S842E400M2       U  
59:17    29 UGood   - 372.093 GB SAS  SSD N   N  512B S842E400M2       U  
59:18    30 UGood   - 372.093 GB SAS  SSD N   N  512B S842E400M2       U  
59:19    31 UGood   - 372.093 GB SAS  SSD N   N  512B S842E400M2       U  
59:20    32 UGood   - 372.093 GB SAS  SSD N   N  512B S842E400M2       U  
59:21    33 UGood   - 372.093 GB SAS  SSD N   N  512B S842E400M2       U  
59:22    34 UGood   - 372.093 GB SAS  SSD N   N  512B S842E400M2       U  
59:23    35 UGood   - 372.093 GB SAS  SSD N   N  512B S842E400M2       U  
-------------------------------------------------------------------------


Понятно, значит будем созавать два RAID6 массива (23 + 1 Hot Spare), по одному на каждом бэкплейне:
# storcli /c0 add vd r6 name=SSD-RAID6-1 drives=37:0-22 WT nora direct Strip=64
# storcli /c0 add vd r6 name=SSD-RAID6-2 drives=59:0-22 WT nora direct Strip=64

Это рекомендованные параметры LSI для SSD. Судя по моим тестам размер страйпа от 8Кб до 128Кб почти никак не влияет на скорость работы.

Конфигурация SCST: /etc/scst.conf
Сервер-1 (с комментариями)
# Перечисляем устройства
## Режим blockio работает с устройствами минуя ядерный Page Cache, для SSD самое то
HANDLER vdisk_blockio {
        ## Нужно иметь в виду, что исходя из имени устройства SCST генерирует поля t10_dev_id и usn
        ## по которым ESXi идентифицирует LUN.
        DEVICE SSD-RAID6-1 {
                ## Уникальный путь к устройству (отвязываемся от именования /dev/sdX)
                filename /dev/disk/by-id/scsi-3600605b008b4be401c91ac4abce21c9b
                ## Отключаем кеш записи
                write_through 1
                ## Говорим что это SSD
                rotational 0
        }

        DEVICE SSD-RAID6-2 {
                filename /dev/disk/by-id/scsi-3600605b008b4be401c91ac53bd668eda
                write_through 1
                rotational 0
        }
}

# Настройка таргетов
TARGET_DRIVER qla2x00t {
        ## WWN порта, свои смотреть в /sys/kernel/scst_tgt/targets/qla2x00t
        TARGET 21:00:00:24:ff:54:09:32 {
                HW_TARGET

                enabled 1
                # Порядковый номер в ALUA группе (1-4 у первого сервера и 5-8 у второго)
                rel_tgt_id 1
                
                ## Добавляем в него наши девайсы
                LUN 0 SSD-RAID6-1
                LUN 1 SSD-RAID6-2
        }

        TARGET 21:00:00:24:ff:54:09:33 {
                HW_TARGET

                enabled 1
                rel_tgt_id 2

                LUN 0 SSD-RAID6-1
                LUN 1 SSD-RAID6-2
        }

        TARGET 21:00:00:24:ff:54:09:80 {
                HW_TARGET

                enabled 1
                rel_tgt_id 3

                LUN 0 SSD-RAID6-1
                LUN 1 SSD-RAID6-2
        }

        TARGET 21:00:00:24:ff:54:09:81 {
                HW_TARGET

                enabled 1
                rel_tgt_id 4

                LUN 0 SSD-RAID6-1
                LUN 1 SSD-RAID6-2
        }
}


# Группа ALUA, имя произвольное
DEVICE_GROUP default {
        ## Добавляем устройства в группу
        DEVICE SSD-RAID6-1
        DEVICE SSD-RAID6-2
        
        ## Группа портов в Сервере-1, имя произвольное
        TARGET_GROUP local {
                ## ID группы, произвольное
                group_id 256

                ## ALUA статус
                state active

                ## Порты Сервера-1
                TARGET 21:00:00:24:ff:54:09:32
                TARGET 21:00:00:24:ff:54:09:33
                TARGET 21:00:00:24:ff:54:09:80
                TARGET 21:00:00:24:ff:54:09:81
        }

        ## Группа портов Сервера-2
        TARGET_GROUP remote {
                group_id 257

                ## ALUA статус
                state nonoptimized
                
                ## Порты Сервера-2 и их порядковые номера
                TARGET 21:00:00:24:ff:4a:af:b2 {
                        rel_tgt_id 5
                }
                TARGET 21:00:00:24:ff:4a:af:b3 {
                        rel_tgt_id 6
                }
                TARGET 21:00:00:24:ff:54:09:06 {
                        rel_tgt_id 7
                }
                TARGET 21:00:00:24:ff:54:09:07 {
                        rel_tgt_id 8
                }
        }
}


Сервер-2 (симметрично)
HANDLER vdisk_blockio {
        DEVICE SSD-RAID6-1 {
                filename /dev/disk/by-id/scsi-3600605b008b4be401c91ac4abce21c9b
                write_through 1
                rotational 0
        }

        DEVICE SSD-RAID6-2 {
                filename /dev/disk/by-id/scsi-3600605b008b4be401c91ac53bd668eda
                write_through 1
                rotational 0
        }
}

TARGET_DRIVER qla2x00t {
        TARGET 21:00:00:24:ff:4a:af:b2 {
                HW_TARGET

                enabled 1
                rel_tgt_id 5

                LUN 0 SSD-RAID6-1
                LUN 1 SSD-RAID6-2
        }

        TARGET 21:00:00:24:ff:4a:af:b3 {
                HW_TARGET

                enabled 1
                rel_tgt_id 6

                LUN 0 SSD-RAID6-1
                LUN 1 SSD-RAID6-2
        }

        TARGET 21:00:00:24:ff:54:09:06 {
                HW_TARGET

                enabled 1
                rel_tgt_id 7

                LUN 0 SSD-RAID6-1
                LUN 1 SSD-RAID6-2
        }

        TARGET 21:00:00:24:ff:54:09:07 {
                HW_TARGET

                enabled 1
                rel_tgt_id 8

                LUN 0 SSD-RAID6-1
                LUN 1 SSD-RAID6-2
        }
}

DEVICE_GROUP default {
        DEVICE SSD-RAID6-1
        DEVICE SSD-RAID6-2

        TARGET_GROUP local {
                group_id 257
                state nonoptimized

                TARGET 21:00:00:24:ff:4a:af:b2
                TARGET 21:00:00:24:ff:4a:af:b3
                TARGET 21:00:00:24:ff:54:09:06
                TARGET 21:00:00:24:ff:54:09:07
        }

        TARGET_GROUP remote {
                group_id 256
                state active

                TARGET 21:00:00:24:ff:54:09:32 {
                        rel_tgt_id 1
                }
                TARGET 21:00:00:24:ff:54:09:33 {
                        rel_tgt_id 2
                }
                TARGET 21:00:00:24:ff:54:09:80 {
                        rel_tgt_id 3
                }
                TARGET 21:00:00:24:ff:54:09:81 {
                        rel_tgt_id 4
                }
        }
}



Всё, для первой части, думаю, достаточно. Надеюсь, что скоро осилю вторую :)
Share post

Similar posts

Comments 27

    +1
    Пара контроллеров в наших краях влетает уже в четверть ляма.
    Шасси, диски и прочее — еще поллляма.
    Не спорю что ниша своя должна быть, но есть от тех же LSI сбагренная в NetApp Е-серия, которая стоит так же, и расширяется недорого и занимает меньше места.
    Есть еще чисто софтовое решение из СПб под названием Raidix.
    В общем вы предлагаете не платить мегадоллары HP/EMC/IBM — Ок. Но вы предлагаете занести столько же в LSI и еще основательно по@#$@#$тся с обеспечением например балансировки каналов, настройкой корректного отстрела узла в случае изоляции, попыткой засунуть тиринг туда где для него и крепежных мест то нет.
    Тоже самое в режиме active-passive (что не снижает надежность решения) делается на двух обычных LSI SAS HBA и том же всем остальном (два сервака, двухэкспандерная полка с возможностью каскадирования). Работает так же, но дешевле. И цепляется к WSS 2012 за 10 минут, благо поддержка storage pool/ storage spaces — позволяет спокойно с этим работать в кластерном режиме, причем в этом случае возможно даже active/active.
      0
      Есть еще чисто софтовое решение из СПб под названием Raidix.

      Слышал, но не трогал. И отзывов мало пока, в отличии от пиарящегося Нутаникса. Да и цена, опять же.

      Не спорю что ниша своя должна быть, но есть от тех же LSI сбагренная в NetApp Е-серия, которая стоит так же, и расширяется недорого и занимает меньше места.

      Да, нетапп это вариант, но он всё же дороже получается. Проблема брендовых СХД именно в цене на диски, а не сами коробки. Вот тут за 12х4Тб хотят 23k$, а вот сколько будут стоить SSD…

      Плюс, у меня были ещё специфические требования вроде полнодискового шифрования на самом хранилище.
      но вы предлагаете занести столько же в LSI и еще основательно по@#$@#$тся с обеспечением например балансировки каналов, настройкой корректного отстрела узла в случае изоляции

      Ну, зачем @#$@#$тся-то? Эти вопросы давно решены в менеджерах кластера, в виде разных STONITH-хэндлеров. Да и изолировать ноду в данном случае практически нет необходимости.

      Про балансировку каналов проблем не вижу, всё используется на полную.

      попыткой засунуть тиринг туда где для него и крепежных мест то нет

      Не понял о чём речь. О каком тиринге идёт речь?

      Тоже самое в режиме active-passive (что не снижает надежность решения) делается на двух обычных LSI SAS HBA и том же всем остальном (два сервака, двухэкспандерная полка с возможностью каскадирования)

      Насчёт надёжности решения как-то сомневаюсь — детектировать отключение второго хоста, дать приказ своему контроллеру импортировать Foreign конфигурации… Это может занять продолжительное время, я такой вариант не рассматривал даже. Да и экономия на Syncro в общем бюджете решения растворится.

      И цепляется к WSS 2012 за 10 минут, благо поддержка storage pool/ storage spaces — позволяет спокойно с этим работать в кластерном режиме, причем в этом случае возможно даже active/active.

      Винду не рассматривал, да и каким образом там будет active/active если железо не позволяет — не очень понимаю.
        0
        Ответы на вопросы:
        1. Raidix умеет в cluster, unified storage и infiniband. В целом если Вам хочется платить своим людям за разработку своего решения и в результате его продавать еще комуто и внедрять или у Вас игра в импортозамещение, то я Вас понимаю. одно могу сказать: после тогоа как Вы это у себя внедрите — Вас еще долго не уволят :)
        2. Вы хотите быстро и дешево? нетапп на самом деле лишнее берет за сущую мелочь. 20 часов разнорежимной работы диска на стенде, что исключает стартовый отказ диска после установки (как известно — бОльшая часть отказов любого оборудования происходит непосредственно после начала эксплуатации). Потоковое шифрование к сожалению изза бугра нам не продают. Даже адаптеки свои мегашифрующие хбашки не продают.
        3. Sync работает в режиме active-passive (один массив в один момент обслуживается одним контроллером). Единственный плюс втыкания пары контроллеров за 10 штук баксов (за сайте ценник посмотрел, икском оказывается за копейки продает) это отзеркалированный на соседе кэш защищенный батарейкой.
        4. Про тиринг: Tiered storage is the assignment of different categories of data to different types of storage media in order to reduce total storage cost.
        5. Тут вы рассуждаете о том что решение должно быть быстрым и надежным. Я понимаю, курс рубля, санкции, шифрование, дорого, но напишите хотя бы в личку сколько и какой скорости вы хотите и для чего? А то ССД и 12 *4ТБ это непонятно. Обработка видео?
        6. Скажу по чести. Чистого Active/active в жизни не видел. Весь А/А когда его начинаешь ковырять сразу же палится и выясняется что это А/Р но с очередной хитрой схемой обмана покупателя. Пока только очень близко лежат ONTAP Cluster mode и 3-PAR — мне не дают их подержать до полного раскрытия заговора :). Hitachi я правда не ковырял. Таже E-series меня вообще поразила коварством. Работа внешне выглядит как А/А, но по факту один контроллер просто замыкает запросы записи на owner'а, а тот уже транслирует запросы к дискам. Чтение честное А/А, а запись А/Р. Ну маркетинг и пишет что А/А. :)
        О моей возне с этим: Меня в этом решении смущает то что оно полкозависимое. Прямого контакта у контроллеров друг с другом нет. SAS expander животное тупое (не все, но...), порты как встали в режим таргета, так и стоят, то есть контроллеры по SAS друг друга не видят, что непонятно — тут надо или кольцо замкнуть во втором контроллере, или сразу звезду строить на свитче (кстати гляньте в сторону LSI 6160). Изначально у них был план одну SAS четверку использовать для синхронизации кэшей контроллеров, но сейчас КЭШи несиннхронизированные получаются. А несинхренный кэш это потеря консистентности или отказ от кэша. В общем мне слишком уж костылисто показалось.
          0
          >>«Прямого контакта у контроллеров друг с другом нет. SAS expander животное тупое (не все, но...), порты как встали в режим таргета, так и стоят, то есть контроллеры по SAS друг друга не видят»
          Вот именно что видят и кэши синхронизируют по SAS. В обоих SAS-доменах присутствуют оба контроллера. Работает всё только в связке с экспандерами LSI.
            0
            >> SAS expander животное тупое (не все, но...)
            Для описанного вами функционала экспандер должен уметь держать порт в гибридном режиме target/initiator — иначе синхриться будут через метаданные на жестких дисках.
              0
              С этим, как видно, проблем нет. Контроллеры друг друга отлично видят даже без дисков в полке вообще.
            0
            5. Я не про 12х4Тб SSD, а про цены на SSD у них вообще
            О моей возне с этим: Меня в этом решении смущает то что оно полкозависимое

            Разве это проблема? Полка — это, по сути, сдвоенный SAS-коммутатор со сдвоенными блоками питания. Всё зарезервировано. Отказов платы распределения питания (в которую втыкаются БП) или бэкплейна (куска текстолита куда подключаться два экспандера и диски) на моей памяти не было. Да и у всех двухконтроллерных хранилок брендовых (лоу-энд) те же проблемы, в общем, ибо та же архитектура.

            то есть контроллеры по SAS друг друга не видят, что непонятно — тут надо или кольцо замкнуть во втором контроллере, или сразу звезду строить на свитче

            одну SAS четверку использовать для синхронизации кэшей контроллеров, но сейчас КЭШи несиннхронизированные получаются

            Вы невнимательно читали статью, либо её вообще не читали.
            1. Контроллеры друг друга видят как раз через SAS и только через него. Причём видят по двум независимым путям (при правильном подключении)
            2. Кеши синхронизированы
              0
              Я внимательно смотрел схему:
              Для описанного вами функционала экспандер должен уметь держать порт в гибридном режиме target/initiator — иначе синхриться будут через метаданные на жестких дисках. Данные всегда идут от target к initiator. Отсюда и следствие — или звезда или кольцо. На схеме ни то ни другое. Порты в контроллере могут быть умными, но тупые экспандеры в полке запорют всю идею. Тот же х36.
              Вы какой backplane в полке используете, с какими экспандерами??
              Для работы:
              1. Контроллеры должны друг друга видеть как раз через SAS и только через него. Причём видят по двум независимым путям (при правильном подключении)
              2. Кеши должны быть синхронизированы
              Но с такой схемой (как на картинке — ни кольцо — ни звезда) экспандер на полке может запороть всю малину (что у меня успешно получилось).
              Сравните кстати с нетапповским крассическим SAS кольцом и прочувствуйте разницу (на АСР не смотрите):
              image
              Здесь есть SAS соединение между контроллерами.
                0
                Экспандеры в полке — 2 штуки SAS2X36 в каждом из 3 бэкплейнов, прошивка 55.14.18.0

                А схема нетаппа, в принципе, аналогична первой схеме SAS из статьи, разницу особо не прочуствовал.
                  0
                  Для аналогичности надо DE(В)E(B)1 переткнуть в DE(В)E(B)2 и соответственно с другой стороны. Но это требует межэкспандерного интерконнекта внутри полки.
                  В общем, не сочтите за комплимент, это Вы сделали и сделали для себя. В широких массах нет достаточного количестваквалифицированных специалистов для самостоятельного внеджрения таких решений.
                    0
                    Вы сделали и сделали для себя.

                    В широких массах нет достаточного количестваквалифицированных специалистов для самостоятельного внеджрения таких решений.

                    Ну так не для себя же (хотя и это, конечно, тоже — опыт никогда не помешает), туториал как раз и нужен для того, чтобы всё более широкие массы могли научиться делать что-то подобное.
                      0
                      Всё верно. Коллега сделал all-flash/full-flash ALUA массив своими руками. Но.

                      Это нужно обслуживать. Для такого решения потребуются высококвалифицированные инженеры. Это сразу дорого в долгосрочной перспективе. Документация решения — хорошо, если она уже есть в какой-то внутренней базе знаний компании.

                      Следует понимать, стоимость классических СХД состоит не только из стоимости оборудования, но и технологий за этим оборудованием, а также заложенной технической поддержки и гарантий со стороны вендора.

                      Перед реализацией решения надо было посчитайте совокупную стоимость владения, а не только внедрения. Автор же посчитал только стоимость решения.

                      Более того, автор пишет про VMware Horizon. Здесь вновь надо было остановиться и посчитать. Что вышло бы дешевле: использовать нативный VMware VSAN на SSD в хостах-машинах или строить собственный «дешевый» массив.

                      В своё время мы считали несколько VDI-решений для наших немаленьких Call-центров и были очень удивлены, когда самым дешёвым оказалось решение на контейнерной Windows виртуализации Parallels с использованием их аналога VSAN — Parallels Cloud Storage. Нет, это не реклама :)

                      Бизнес всегда любит считать деньги. И это правильный подход.

                      Не удивлюсь, если через некоторое время автора схантят в какую-нибудь СХД-производящую/продающую компанию :)
            0
            Storage Spaces — это конечно хорошо, если обойти его слабые стороны (беда с записью на parity/dual parity пулы без SSD в качестве WB-кэша и быстрого яруса), но:
            1) Автору нужен был FC таргет и/или (даже если бы устроил iSCSI) больше опыта с кластеризацией в Linux.
            2) Откуда там Active-Active? Storage Spaces выступает в качестве основы для обычного MS Failover Cluster, а на нём iSCSI-таргет — ЕМНИП, вот так это выглядит.
            3) Как Storage Spaces масштабируется на большое кол-во SSD? Есть ли у Вас опыт? Есть подозрение, что весьма неплохо, если не забывать про правильное кол-во столбцов, но просто не было возможности измерить.
              0
              1) Пардон пропустил.
              2) Я сам фанат SAS топологии ^_^/ Сейчас WSS весьма подрос над собой. Может на Storage Spaces изображать A/A c CIFS шарой (ну или iSCSI 3.0)
              3) Надо брать задачу и под неё считать, тестировать и снова считать. С ССД на серверных платформах надо осторожнее — можно в ширину шины PCI упереться. У автора две фибры на ноду, даже если 8-ка (а не 16) это пиковая отдача в прыжке с табуретки — 8*4=32, учитывая что контроллер не напрямую в FC адаптер воткнут и там еще процессор и ОС периодически хотят с ними пообщаться, да и шифрование еще — как бы шина не лопнула. В хранилках как никак SAS чуть ли не сразу в порт выводят (благо у них система команд одна и таже — много переделывать не надо)
              Я просто не могу понять для чего это. Да еще и с шифрованием на дисковом уровне.
                0
                В хранилках как никак SAS чуть ли не сразу в порт выводят (благо у них система команд одна и таже — много переделывать не надо)

                Там всё примерно так же, благо хранилки нынче построены на той же архитектуре (x86, low-voltage Xeon какой-нибудь). Так что путь данных от диска до порта внешнего там такой же: SAS контроллер -> память/CPU -> FC/SAS контроллер-таргет.

                Я просто не могу понять для чего это. Да еще и с шифрованием на дисковом уровне

                У меня конкретно эта система будет обслуживать в основном большой VDI на базе VMWare View.
                Шифрование на IOPS влияет слабо, в отличии от последовательных операций.
            0
            У меня вопрос к автору сколько миллионов руб. бюджет расмотренного решения на дату 16.03.2015?
              0
              Сложно сказать. Я практически полный перечень компонентов написал — закиньте поставщикам. Но думаю на 1.5 можно умножать смело, как минимум.
                0
                я примерную сумму спрашиваю…
                ясно что не для каждого это будет «бюджетным» )))
                уже 48 данных SSD = минимум 2.5 млн.
                Не обязательно же абсолютно все покупать, тем более, что существуют например схемы «лизинга»… и т.д.
                  0
                  Ну, бюджетность тут в самом принципе построения хранилища и самый дорогой элемент, если экономить на остальном — сам Syncro.
                  В принципе, если брать диски SATA и дисков будет не очень много, то выгоднее строить на основе DRBD с двойным набором дисков.

                  Примерную — не знаю, я прикинул выше что на 1.5 умножить надо. SSD мне при закупке как раз обошлись примерно в 2.3млн, Syncro — 160т, остальное ещё сколько-то. В статье я указал 4млн стоимость, но в эту сумму, как я уже потом вспомнил, помимо коммутаторов вошёл UPS Symmetra с акксуссуарами ценой больше 400т.р., так что общая цена меньше 3.5млн.
                    0
                    меньше 3.5млн.

                    Цена вполне «бюджетная» для корпоративного уровня.
              +1
              Отличная статья по применению SyncroCS. Не каждый день можно встретить человека, умеющего правильно готовить SCST + Pacemaker. Несколько моментов:
              1) В готовом коммерчески поддерживаемом виде такая связка реализована в Open-E (http://www.open-e.com/about-us/news/newsletters/product-information-open-e-dss-v7-with-avago-syncro-solution-users-en/)
              2) >>«По причине отказоустойчивой натуры решения, LSI Syncro поддерживает только двухпортовые SAS диски.»
              Не просто 2-портовые, а ещё и поддерживающие SCSI PR (т.е. не совсем древние). Я когда первый раз пробовал прототип Syncro CS, то со старыми 36ГБ Fujitsu ничего не завелось по этой причине.
              3) >>«SC417E16-RJBOD1 — на 88 дисков, но там лишь одинарные экспандеры, что плохо скажется на надёжности, да и слотов расширения мало.»
              Хм, я действительно не задумывался, будет ли Syncro работать через 1 экспандер. Официально вроде как нет?
              Технически, думаю, возможно, просто теряем пропускную способность (входов не хватит, чтобы подключить оба порта с двух контроллеров и ещё каскадировать) и надёжность при каскадировании.
              4) Я недавно считал стоимость нескольких бюджетных решений для СХД с тирингом. У меня получалось, что Infortrend 3024 обходится всего на 10% дороже Syncro CS. Обещанные 1,3 мегаиопса (с двух контроллеров) проверить не мог в своё время из-за отсутствия достаточного кол-ва SSD, но 200k получил, как и пропускную способность > 3ГБ/с. В качестве плюса помимо поддержки и всяких других фич получаем VAAI.
                0
                Спасибо!

                1) Да, интересно, они там ещё и ZFS прикрутили. Но почитав какие-то обзоры Нексенты и какие там бывают просадки скорости решил с ним не связываться до поры до времени.
                2) Угу, я на это не указывал т.к. вряд-ли кто-то будет городить такую систему с дисками 5-7 летней давности :)
                3) Работать будет, я подключал только 1 проводом каждый контроллер только к 1 экспандеру, но смысла в такой конфигурации не очень много
                4) Да, наверное mid-tier вендоры уже могут тягаться с самосборными решениями, но у меня с ними опыта работы не было. Да и при сравнимой цене я лучше соберу что-то своё, где смогу найти проблемы если таковые будут, чем насиловать техподдержку, которая не всегда адекватна.
                  +1
                  1) Не, на ZFS у них совсем другой, отдельный продукт — Jovian DSS. В обычном Open-E единственный плюс — простой web-интерфейс, те же самые 2-узла с drbd или Syncro CS там может поднять даже неподготовленный человек относительно быстро. А вот дальше начинаются проблемы, связанные с тем, что Linux там со всех сторон огорожен, ни логи нормально посмотреть, ни производительность помониторить (те графики, что есть — ни о чём). Еще, ЕМНИП, там проблема с PR'ами при переезде решена.
                  4) Это, как и Open-E на тот случай, если корпоративными стандартами не предусмотрен полный самосбор с самоподдержкой.
                  0
                  По поводу правильно готовить я тут уже написал: одно могу сказать: после того, как Вы это у себя внедрите — Вас еще долго не уволят
                  :)
                  Open-E уже сильно отстал. Его бы нексента давно вытеснила, но она стоит как крыло от самолета.
                  Четвертый пункт у вас получилось объяснить лучше чем у меня. Не только косноязычие у меня, но и косноклавиатурие видимо.
                  0
                  Положу в копилку… Много чего считать приходится по работе :). Особенно аналоги тяжелого оборудования. Попозже сделаю расчет твоей конфигурации.
                    0
                    Труд ваш достоин самой высокой оценки, но смущает вот этот момент:

                    То есть, если инициатор поставит блокировку на LUN через путь, ведущий на первый сервер, то через путь, ведущий на второй сервер, эта блокировка видна не будет. Для работы в режиме Round Robin это особенно важно, так как пути меняются постоянно и через какой путь будет установлена блокировка заранее неизвестно. В случае с VMWare ESXi это, в принципе, не проблема так как с версии VMFS5 не используются SCSI PR, а вместо них идёт в ход инструкция Atomic-Test-and-Set (которая, впрочем, тоже не реплицируется, но зато блокирует только нужную область на LUNе и на короткое время, а не весь LUN целиком), да и ALUA должен дать знать ESXi чтобы тот не использовал пути на второй сервер пока жив основной.


                    То есть если один из хостов ESXi в случае ошибки пойдет по неоптимальному пути, при определенном стечении обстоятельств возможно разрушение данных?
                      0
                      В каких-то очень редких случаях, думаю, что-то подобное возможно, но крайне маловероятно.
                      Да и SCSI PR используются только при операциях с метаданными (вкл-выкл ВМ, изменение конфигурации, снапшоты и т.п.) и если нет ATS.
                      Ну и шанс что один хост пойдёт по оптимальному пути, а другой — нет крайне мал. Для этого нужно будет что-то очень хорошо испортить.

                      Плюс, недавно вышел пре-релиз SCST 3.1, в котором уже добавлена поддержка репликации SCSI PR:
                      Highlights for this release:

                      — Cluster support for SCSI reservations. This feature is essential for initiator-side
                      clustering approaches based on persistent reservations, e.g. the quorum disk
                      implementation in Windows Clustering.

                      — Full support for VAAI or vStorage API for Array Integration: Extended Copy command
                      support has been added as well as performance of WRITE SAME and of Atomic Test & Set,
                      also known as COMPARE AND WRITE, has been improved.

                      — T10-PI support has been added.

                      — ALUA support has been improved: explicit ALUA (SET TARGET PORT GROUPS command) has
                      been added and DRBD compatibility has been improved.

                      — SCST events user space infrastructure has been added, so now SCST can notify a user
                      space agent about important internal and fabric events.

                      — QLogic target driver has been significantly improved.

                    Only users with full accounts can post comments. Log in, please.