diff --git a/src/vmm_mad/remotes/lib/lxd/command.rb b/src/vmm_mad/remotes/lib/lxd/command.rb index 51cffdfc98..6352353f74 100644 --- a/src/vmm_mad/remotes/lib/lxd/command.rb +++ b/src/vmm_mad/remotes/lib/lxd/command.rb @@ -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 diff --git a/src/vmm_mad/remotes/lib/lxd/container.rb b/src/vmm_mad/remotes/lib/lxd/container.rb index 266264611a..fc683b5ada 100644 --- a/src/vmm_mad/remotes/lib/lxd/container.rb +++ b/src/vmm_mad/remotes/lib/lxd/container.rb @@ -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}" diff --git a/src/vmm_mad/remotes/lib/lxd/mapper/mapper.rb b/src/vmm_mad/remotes/lib/lxd/mapper/mapper.rb index fb7b04c2ee..0fc875d5e4 100644 --- a/src/vmm_mad/remotes/lib/lxd/mapper/mapper.rb +++ b/src/vmm_mad/remotes/lib/lxd/mapper/mapper.rb @@ -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}") diff --git a/src/vmm_mad/remotes/lib/lxd/mapper/qcow2.rb b/src/vmm_mad/remotes/lib/lxd/mapper/qcow2.rb index c66322dbbd..19d9d411ca 100644 --- a/src/vmm_mad/remotes/lib/lxd/mapper/qcow2.rb +++ b/src/vmm_mad/remotes/lib/lxd/mapper/qcow2.rb @@ -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 diff --git a/src/vmm_mad/remotes/lib/lxd/mapper/raw.rb b/src/vmm_mad/remotes/lib/lxd/mapper/raw.rb index abfd1c709f..1240192835 100644 --- a/src/vmm_mad/remotes/lib/lxd/mapper/raw.rb +++ b/src/vmm_mad/remotes/lib/lxd/mapper/raw.rb @@ -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 diff --git a/src/vmm_mad/remotes/lib/lxd/mapper/rbd.rb b/src/vmm_mad/remotes/lib/lxd/mapper/rbd.rb index 4132b2f8dc..65edb2f2f0 100644 --- a/src/vmm_mad/remotes/lib/lxd/mapper/rbd.rb +++ b/src/vmm_mad/remotes/lib/lxd/mapper/rbd.rb @@ -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 diff --git a/src/vmm_mad/remotes/lib/lxd/opennebula_vm.rb b/src/vmm_mad/remotes/lib/lxd/opennebula_vm.rb index 938556c4aa..59169462b7 100644 --- a/src/vmm_mad/remotes/lib/lxd/opennebula_vm.rb +++ b/src/vmm_mad/remotes/lib/lxd/opennebula_vm.rb @@ -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