1
0
mirror of https://github.com/OpenNebula/one.git synced 2025-03-21 14:50:08 +03:00

F #1684: LXD fixes path checks

This commit is contained in:
Daniel Clavijo Coca 2018-12-17 08:52:55 -06:00 committed by Ruben S. Montero
parent df85e16c75
commit d746dded35
7 changed files with 62 additions and 71 deletions

View File

@ -21,6 +21,7 @@ require 'open3'
# This module can be used to execute commands. It wraps popen3 and provides
# locking capabilites using flock
module Command
LOCK_FILE = '/tmp/onelxd-lock'
def self.execute(cmd, block)
@ -31,7 +32,7 @@ module Command
begin
fd = lock if block
Open3.popen3(cmd) { |i, o, e, t|
Open3.popen3(cmd) {|i, o, e, t|
rc = t.value.exitstatus
stdout = o.read
@ -41,7 +42,6 @@ module Command
e.close
}
rescue
ensure
unlock(fd) if block
end
@ -67,11 +67,11 @@ module Command
lfd = File.open(LOCK_FILE,"w")
lfd.flock(File::LOCK_EX)
return lfd
lfd
end
def self.unlock(lfd)
lfd.close
end
end
end

View File

@ -236,7 +236,7 @@ class Container
rc, _o, e = Command.execute(create_context_dir, false)
if rc != 0
OpenNebula.log_error("setup_storage: #{e}")
OpenNebula.log_error("#{__method__}: #{e}")
return
end
@ -360,8 +360,8 @@ class Container
rc, _o, e = Command.execute_once(server, true)
if rc != 0
OpenNebula.log_error("do_map: #{e}")
unless [nil, 0].include?(rc)
OpenNebula.log_error("#{__method__}: #{e}\nFailed to start vnc")
return
end
@ -370,7 +370,6 @@ class Container
File.open(pipe, 'a') do |f|
f.write command
end
ensure
Command.unlock(lfd) if lfd
end
@ -403,28 +402,29 @@ class Container
def new_disk_mapper(disk)
case disk['TYPE']
when 'FILE'
ds = "#{@one.sysds_path}/#{@one.vm_id}/disk.#{disk['DISK_ID']}"
rc, out, err = Command.execute("#{Mapper::COMMANDS[:file]} #{ds}", false)
unless rc.zero?
OpenNebula.log_error("do_map: #{err}")
OpenNebula.log_error("#{__method__} #{err}")
return
end
case out
when /.*QEMU QCOW.*/
OpenNebula.log "Using qcow2 mapper for #{ds}"
return Qcow2Mapper.new
Qcow2Mapper.new
when /.*filesystem.*/
OpenNebula.log "Using raw filesystem mapper for #{ds}"
return FSRawMapper.new
FSRawMapper.new
when /.*boot sector.*/
OpenNebula.log "Using raw disk mapper for #{ds}"
return DiskRawMapper.new
DiskRawMapper.new
else
OpenNebula.log("Unknown #{out} image format, trying raw filesystem mapper")
return FSRawMapper.new
FSRawMapper.new
end
when 'RBD'
OpenNebula.log "Using rbd disk mapper for #{ds}"

View File

@ -185,40 +185,42 @@ class Mapper
sys_parts = lsblk('')
return false unless sys_parts
partitions = []
device = ''
real_path = directory
dir_ok = directory.dup.gsub('//', '/')
real_path = dir_ok
ds = one_vm.sysds_path
if File.symlink?(ds)
real_ds = File.readlink(ds)
real_path = real_ds + directory.split(ds)[-1] if directory.include?(ds)
real_path = real_ds + dir_ok.split(ds)[-1] if dir_ok.include?(ds)
end
sys_parts.each { |d|
sys_parts.each {|d|
if d['mountpoint'] == real_path
partitions = [d]
device = d['path']
break
end
d['children'].each { |c|
if c['mountpoint'] == real_path
partitions = d['children']
device = d['path']
break
end
} if d['children']
break if !partitions.empty?
}
partitions.delete_if { |p| !p['mountpoint'] }
partitions.sort! { |a,b|
b['mountpoint'].length <=> a['mountpoint'].length
}
next unless c['mountpoint'] == real_path
partitions = d['children']
device = d['path']
break
} if d['children']
break if !partitions.empty?
}
partitions.delete_if {|p| !p['mountpoint'] }
partitions.sort! {|a, b|
b['mountpoint'].length <=> a['mountpoint'].length
}
if device.empty?
OpenNebula.log_error("Failed to detect block device from #{directory}")

View File

@ -21,6 +21,7 @@ $LOAD_PATH.unshift File.dirname(__FILE__)
require 'mapper'
class Qcow2Mapper < Mapper
# Max number of block devices. This should be set to the parameter used
# to load the nbd kernel module (default in kernel is 16)
NBDS_MAX = 256
@ -38,7 +39,7 @@ class Qcow2Mapper < Mapper
rc, _out, err = Command.execute(cmd, true)
if rc != 0
OpenNebula.log_error("do_map: #{err}")
OpenNebula.log_error("#{__method__}: #{err}")
return
end
@ -54,7 +55,7 @@ class Qcow2Mapper < Mapper
return true if rc.zero?
OpenNebula.log_error("do_unmap: #{err}")
OpenNebula.log_error("#{__method__}: #{err}")
nil
end
@ -76,8 +77,9 @@ class Qcow2Mapper < Mapper
return "/dev/nbd#{i}" unless nbds.include?(i)
}
OpenNebula.log_error("nbd_device: Cannot find free nbd device")
OpenNebula.log_error("#{__method__}: Cannot find free nbd device")
''
end
end

View File

@ -25,7 +25,7 @@ require 'mapper'
#-------------------------------------------------------------------------------
class FSRawMapper < Mapper
def do_map(one_vm, disk, directory)
def do_map(one_vm, disk, _directory)
dsrc = disk_source(one_vm, disk)
cmd = "#{COMMANDS[:losetup]} -f --show #{dsrc}"
@ -33,23 +33,25 @@ class FSRawMapper < Mapper
return out.chomp unless rc != 0 || out.empty?
OpenNebula.log_error("do_map: #{err}")
OpenNebula.log_error("#{__method__}: #{err}")
nil
end
def do_unmap(device, one_vm, disk, directory)
def do_unmap(device, _one_vm, _disk, _directory)
cmd = "#{COMMANDS[:losetup]} -d #{device}"
rc, _out, err = Command.execute(cmd, true)
return true if rc.zero?
OpenNebula.log_error("do_unmap: #{err}") if rc != 0
OpenNebula.log_error("#{__method__}: #{err}") if rc != 0
nil
end
end
class DiskRawMapper < Mapper
# Maps the whole file using kpartx. The output should be something like:
# $ sudo kpartx -av /var/lib/one/datastores/100/0/disk.0
# add map loop3p1 (253:0): 0 204800 linear 7:3 2048
@ -63,8 +65,8 @@ class DiskRawMapper < Mapper
rc, out, err = Command.execute(cmd, true)
if rc != 0 || out.empty?
OpenNebula.log_error("do_map: #{err}")
return nil
OpenNebula.log_error("#{__method__}: #{err}")
return
end
loopdev = out.lines[0].match(/.*add map loop(\d+)p\d+.*/)
@ -83,7 +85,8 @@ class DiskRawMapper < Mapper
return true if rc.zero?
OpenNebula.log_error("do_unmap: #{err}")
OpenNebula.log_error("#{__method__}: #{err}")
nil
end
end

View File

@ -30,6 +30,8 @@ class RBDMapper < Mapper
def disk_source(vm_id, disk)
src = disk['SOURCE']
return "#{src}-#{vm_id}-#{disk['DISK_ID']}" if disk['CLONE'] == 'YES'
src
end
def do_map(one_vm, disk, _directory)
@ -41,18 +43,19 @@ class RBDMapper < Mapper
return out.chomp if rc.zero?
OpenNebula.log_error("do_map: #{err}")
OpenNebula.log_error("#{__method__}: #{err}")
nil
end
def do_unmap(device, one_vm, disk, directory)
def do_unmap(device, _one_vm, _disk, _directory)
cmd = "#{COMMANDS[:rbd]} #{@ceph_user} unmap #{device}"
rc, _out, err = Command.execute(cmd, false)
return true if rc.zero?
OpenNebula.log_error("do_unmap: #{err}")
OpenNebula.log_error("#{__method__}: #{err}")
nil
end
end

View File

@ -29,12 +29,15 @@ class LXDConfiguration < Hash
:datastore_location => '/var/lib/one/datastores'
}
LXDRC = '../../etc/vmm/lxd/lxdrc'
def initialize
replace(DEFAULT_CONFIGURATION)
begin
merge!(YAML.load_file("#{__dir__}/../../etc/vmm/lxd/lxdrc"))
rescue
merge!(YAML.load_file("#{__dir__}/#{LXDRC}"))
rescue => e
OpenNebula.log_error e
end
end
@ -69,9 +72,6 @@ class OpenNebulaVM
return unless disk
@ds_path = get_dspath(disk)
@sysds_path = "#{@ds_path}/#{@sysds_id}"
@rootfs_id = disk['DISK_ID']
boot_order = @xml['//TEMPLATE/OS/BOOT']
@rootfs_id = boot_order.split(',')[0][-1] unless boot_order.empty?
@ -374,25 +374,6 @@ class OpenNebulaVM
mapped
end
# Returns the datastores BASE_PATH location
def get_dspath(disk)
source = disk['SOURCE']
cut = "/#{disk['DATASTORE_ID']}/"
result = source.split(cut)
if result.length == 2
path = result[0]
else
path = ''
0.upto(result.length - 2) do |i|
path << "#{result[i]}/#{dsid}/"
end
path = path[0..path.rindex(cut)]
end
path.gsub('//', '/')
end
end
# This class abstracts the access to XML elements. It provides basic methods