/
loop.rb
73 lines (65 loc) · 1.78 KB
/
loop.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
require 'kernelext/kernelext.rb'
require 'file/file_patch.rb'
module Loop
@losetup_path = "/sbin/losetup"
# Sets up loop device for file at path, returns the name of the loop device that was created
def self.add(path, read_only = false, offset = nil, size = nil)
path = path.path if (path.is_a? File)
args = [@losetup_path, "--show"]
if (read_only)
args.push("--read-only")
end
if (!offset.nil?)
args.push("--offset", offset)
end
if (!size.nil?)
args.push("--sizelimit", size)
end
args.push("-f", path)
line = KernelExt::fork_exec_get_output(*args)
line.strip
end
# Removes loop device
def self.remove(device)
KernelExt::fork_exec_get_output(@losetup_path, "-d", device)
end
# Removes all loop devices associated with given file
def self.remove_for(path)
devices = devices_for(path)
devices.each { |device| remove(device) }
end
def self.file_name_for(loop_dev)
File.open(loop_dev, "rb") do |f|
v = "\0" * 224 # space for struct loop_info
f.ioctl(0x4C05, v) # LOOP_GET_STATUS64
v[56,64].unpack("A64")[0] # lo_file_name
end
end
def self.devices
devices = []
File.open("/proc/partitions", "rb") do |f|
lines = f.readlines
lines.slice!(0,2)
lines.each do |line|
if (line.match(/^\s+\d+\s+\d+\s+\d+\s+(loop.*?)$/))
devices.push("/dev/#{$1}")
end
end
end
devices
end
def self.device_for(path)
loop_devs = devices_for(path)
if (loop_devs.length == 0)
nil
else
loop_devs[0]
end
end
def self.devices_for(path)
path = path.path if (path.is_a? File)
loop_devs = devices
loop_devs.reject! { |dev| file_name_for(dev) != path }
loop_devs
end
end