Устраняем проблему со снэпшотами диска в OpenNebula

Устраняем проблему со снэпшотами диска в OpenNebula

Roman Bogachev VMware Specialist | Drone Pilot | Traveler

Исправляем проблему после обновления OpenNebula с наследованием снэпшотов диска используя Ceph хранилище.

До версии ONe 5.4.х снэпшоты диска выполнялись с наследованием к родительскому снэпшоту, что несколько рушило логику и работу с ними.

В директиве TM_MAD_CONF конфигурационного файла oned.conf приходилось добавлять ALLOW_ORPHANS = YES для создания независимых друг от друга снэпшотов.

В версии 5.4 данный функционал был исправлен и соответственно включен по умолчанию, но при обновлении с 5.2 на 5.4 все же наблюдаются проблемы, поэтому все приходится доделывать руками.

Итак, проверяем, что для каждого хранилища в TM_MAD присутствует строка ALLOW_ORPHANS = YES. Это включит опцию для новых виртуальных серверов, которые будут созданы.

Для существующих виртуальных серверов снимаем XML-дамп командой onevm show $VMID --xml и проверяем значение /VM/SNAPSHOTS/ALLOW_ORPHANS, оно должно быть в значении YES.

Если это не так, то изменим данный параметр. (ВНИМАНИЕ! Сделайте бэкап базы данных прежде чем выполнять действия с виртуальными серверами!)

1
2
3
# For example to change ALLOW_ORPHANS=YES on DISK_ID=0 of VM_ID=23
# you should repeat for each disk in the VM metadata
onedb change-body vm --id 23 '/VM/SNAPSHOTS[DISK_ID=0]/ALLOW_ORPHANS' -- "YES"

Если на виртуальном сервере уже существовали снэпшоты, то необходимо выполнить flatten для каждого из них:

1
2
3
4
# change PARENT=-1 for snapshot 0 and 1 of disk 0 on VM 23
# you should repeat the step for all disk snapshots
onedb change-body vm --id 23 '/VM/SNAPSHOTS[DISK_ID=0]/SNAPSHOT[ID=0]/PARENT' -- "-1"
onedb change-body vm --id 23 '/VM/SNAPSHOTS[DISK_ID=0]/SNAPSHOT[ID=1]/PARENT' -- "-1"

Альтернативный вариант с установкой патча

Создаем файл allow_ophans.rb

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
# -------------------------------------------------------------------------- #
# Copyright 2002-2017, OpenNebula Project, OpenNebula Systems #
# #
# Licensed under the Apache License, Version 2.0 (the "License"); you may #
# not use this file except in compliance with the License. You may obtain #
# a copy of the License at #
# #
# http://www.apache.org/licenses/LICENSE-2.0 #
# #
# Unless required by applicable law or agreed to in writing, software #
# distributed under the License is distributed on an "AS IS" BASIS, #
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. #
# See the License for the specific language governing permissions and #
# limitations under the License. #
#--------------------------------------------------------------------------- #

if !ONE_LOCATION
LOG_LOCATION = "/var/log/one"
else
LOG_LOCATION = ONE_LOCATION + "/var"
end

LOG = LOG_LOCATION + "/onedb-allow_orphans.log"

require 'nokogiri'

module OneDBPatch
VERSION_MIN = "5.0.0"
VERSION_MAX = "5.5.0"

def is_hot_patch(ops)
return false
end

def check_db_version(ops)
db_version = read_db_version()

version = Gem::Version.new(db_version[:version])

if (version < Gem::Version.new(VERSION_MIN)) ||
(version >= Gem::Version.new(VERSION_MAX))
then
raise <<-EOT
Version mismatch: patch file is for version
Shared: #{VERSION_MIN} to #{VERSION_MAX} (excluding)

Current database is version
Shared: #{db_version[:version]}
EOT
end
end

def add_element(elem, name)
return elem.add_child(elem.document.create_element(name))
end

def add_cdata(elem, name, text)
# The cleaner doc.create_cdata(txt) is not supported in
# old versions of nokogiri
return add_element(elem, name).add_child(
Nokogiri::XML::CDATA.new(elem.document(), text))
end

def add_allow_orphans(ele, val, type)
did = ele.xpath("DISK_ID").text
if (did) then
ele.search("ALLOW_ORPHANS").remove
add_cdata(ele, "ALLOW_ORPHANS", val)
elem = ele.search("ALLOW_ORPHANS")
puts " #{type} DISK_ID:#{did} :: #{elem}"
end
end

def patch(ops)

init_log_time()

puts "This tool will convert the tree of disk snapshots to orphans."

@db.transaction do
@db.fetch("SELECT * FROM vm_pool") do |row|
doc = Nokogiri::XML(row[:body],nil,NOKOGIRI_ENCODING){|c| c.default_xml.noblanks}

next if row[:state] == 6 # skip VMs in state DONE

puts " VM_ID:#{row[:oid]} state:#{row[:state]} lcm_state:#{row[:lcm_state]}"

doc.xpath("/VM/TEMPLATE/DISK").each do |disk|
add_allow_orphans(disk, "YES", "DISKS")
end

doc.xpath("/VM/SNAPSHOTS").each do |snaps|
add_allow_orphans(snaps, "YES", "SNAPS")
snaps.xpath("SNAPSHOT").each do |snap|
snap.search("CHILDREN").remove
snap.search("PARENT").remove
add_cdata(snap, "PARENT", "-1")
parent_ele = snap.search("PARENT")
sid = snap.xpath("ID").text
puts " SNAPSHOT_ID:#{sid} :: #{parent_ele}"
end
end

body = doc.root.to_s
@db[:vm_pool].where(oid: row[:oid]).update(body: body)
end

log_time()
end
return true
end
end

Обязательно делаем бэкап базы данных и ставим патч.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
$ onedb patch -u oneadmin -d opennebula allow_orphans.rb   
MySQL Password:
MySQL dump stored in /var/lib/one/mysql_localhost_opennebula_2017-11-8_18:8:10.sql
Use 'onedb restore' or restore the DB using the mysql command:
mysql -u user -h server -P port db_name < backup_file

This tool will convert the tree of disk snapshots to orphans.
VM_ID:10 state:3 lcm_state:3
DISKS DISK_ID:0 :: <ALLOW_ORPHANS><![CDATA[YES]]></ALLOW_ORPHANS>
VM_ID:11 state:3 lcm_state:3
DISKS DISK_ID:0 :: <ALLOW_ORPHANS><![CDATA[YES]]></ALLOW_ORPHANS>
VM_ID:12 state:3 lcm_state:3
DISKS DISK_ID:0 :: <ALLOW_ORPHANS><![CDATA[YES]]></ALLOW_ORPHANS>
VM_ID:13 state:3 lcm_state:3
DISKS DISK_ID:0 :: <ALLOW_ORPHANS><![CDATA[YES]]></ALLOW_ORPHANS>
VM_ID:14 state:3 lcm_state:3
DISKS DISK_ID:0 :: <ALLOW_ORPHANS><![CDATA[YES]]></ALLOW_ORPHANS>
VM_ID:15 state:3 lcm_state:3
DISKS DISK_ID:0 :: <ALLOW_ORPHANS><![CDATA[YES]]></ALLOW_ORPHANS>
DISKS DISK_ID:2 :: <ALLOW_ORPHANS><![CDATA[YES]]></ALLOW_ORPHANS>
VM_ID:16 state:3 lcm_state:3
DISKS DISK_ID:0 :: <ALLOW_ORPHANS><![CDATA[YES]]></ALLOW_ORPHANS>
VM_ID:17 state:3 lcm_state:3
DISKS DISK_ID:0 :: <ALLOW_ORPHANS><![CDATA[YES]]></ALLOW_ORPHANS>
VM_ID:18 state:9 lcm_state:0
DISKS DISK_ID:0 :: <ALLOW_ORPHANS><![CDATA[YES]]></ALLOW_ORPHANS>
VM_ID:19 state:9 lcm_state:0
DISKS DISK_ID:0 :: <ALLOW_ORPHANS><![CDATA[YES]]></ALLOW_ORPHANS>
VM_ID:20 state:3 lcm_state:3
DISKS DISK_ID:2 :: <ALLOW_ORPHANS><![CDATA[YES]]></ALLOW_ORPHANS>
VM_ID:22 state:9 lcm_state:0
DISKS DISK_ID:0 :: <ALLOW_ORPHANS><![CDATA[YES]]></ALLOW_ORPHANS>
VM_ID:23 state:3 lcm_state:3
DISKS DISK_ID:0 :: <ALLOW_ORPHANS><![CDATA[YES]]></ALLOW_ORPHANS>
SNAPS DISK_ID:0 :: <ALLOW_ORPHANS><![CDATA[YES]]></ALLOW_ORPHANS>
SNAPSHOT_ID:0 :: <PARENT><![CDATA[-1]]></PARENT>
SNAPSHOT_ID:1 :: <PARENT><![CDATA[-1]]></PARENT>
.............................................

После указанных действий - перезапустим сервис OpenNebula.

Проверяем выполнение снэпшотов, а так же их наследование.

On this page