Skip to content

Commit

Permalink
Correct byte-order on LVM metadata reads [Fixes GH#31]
Browse files Browse the repository at this point in the history
Somehow I managed to completely confuse myself as to the LVM metadata
format, and it was only the bug in htonq/ntohq (GH#6) that I fixed recently
that had made it work all this time.  Once I fixed that bug, this one
appeared.

Thanks to UnwashedMeme for the detective work, and pointing me in the right
direction.
  • Loading branch information
mpalmer committed Oct 6, 2014
1 parent ecb45fa commit 7cd5505
Show file tree
Hide file tree
Showing 2 changed files with 15 additions and 6 deletions.
15 changes: 12 additions & 3 deletions lib/lvm/helpers.rb
Original file line number Diff line number Diff line change
Expand Up @@ -3,16 +3,25 @@ module LVM; end
module LVM::Helpers
# Are we on a big-endian system? Needed for our htonq/ntohq methods
def big_endian?
@bigendian ||= [1].pack("s") == [1].pack("n")
@big_endian ||= [1].pack("s") == [1].pack("n")
end

def htonq val
# This won't work on a nUxi byte-order machine, but if you have one of
# those, I'm guessing you've got bigger problems
big_endian? ? val : ([val].pack("Q").reverse.unpack("Q").first)
big_endian? ? val : swap_longs(val)
end

def ntohq val
htonq val
big_endian? ? val : swap_longs(val)
end

# On-disk (LVM) format (which is little-endian) to host byte order
def dtohq val
big_endian? ? swap_longs(val) : val
end

def swap_longs val
[val].pack("Q").reverse.unpack("Q").first
end
end
6 changes: 3 additions & 3 deletions lib/lvm/snapshot.rb
Original file line number Diff line number Diff line change
Expand Up @@ -30,15 +30,15 @@ def differences

while in_progress
# The snapshot on-disk format is a stream of <blocklist>, <blockdata>
# sets; within each <blocklist>, it's network-byte-order 64-bit block
# sets; within each <blocklist>, it's little-endian 64-bit block
# IDs -- the first is the location (chunk_size * offset) in the origin
# LV that the data has been changed, the second is the location (again,
# chunk_size * offset) in the metadata LV where the changed data is
# being stored.
(chunk_size / 16).times do
origin_offset, snap_offset = metafd.read(16).unpack("QQ")
origin_offset = ntohq(origin_offset)
snap_offset = ntohq(snap_offset)
origin_offset = dtohq(origin_offset)
snap_offset = dtohq(snap_offset)

# A snapshot offset of 0 would point back to the metadata
# device header, so that's clearly invalid -- hence it's the
Expand Down

0 comments on commit 7cd5505

Please sign in to comment.