Module: Snapsync::Btrfs

Defined in:
lib/snapsync/btrfs.rb

Defined Under Namespace

Classes: Error, UnexpectedBtrfsOutput

Class Method Summary collapse

Class Method Details

.find_new(subvolume_dir, last_gen) {|a| ... } ⇒ Object .find_new(subvolume_dir, last_gen) ⇒ #each

Facade for ‘btrfs subvolume find-new’

It computes what changed between a reference generation of a subvolume, and that subvolume’s current state

Overloads:

  • .find_new(subvolume_dir, last_gen) {|a| ... } ⇒ Object

    Yield Parameters:

    • a (String)

      line of the find-new output

  • .find_new(subvolume_dir, last_gen) ⇒ #each

    Returns an enumeration of the lines of the find-new output.

    Returns:

    • (#each)

      an enumeration of the lines of the find-new output

Parameters:

  • subvolume_dir (String)

    the subvolume target of find-new

  • last_gen (Integer)

    the reference generation



93
94
95
96
# File 'lib/snapsync/btrfs.rb', line 93

def self.find_new(subvolume_dir, last_gen, &block)
    run('subvolume', 'find-new', subvolume_dir.to_s, last_gen.to_s).
        each_line(&block)
end

.generation_of(path) ⇒ Integer

Facade for finding the generation of a subvolume using ‘btrfs show’

Parameters:

  • path (Pathname)

    the subvolume path

Returns:

  • (Integer)

    the subvolume’s generation



71
72
73
74
75
76
77
78
# File 'lib/snapsync/btrfs.rb', line 71

def self.generation_of(path)
    info = Btrfs.run('subvolume', 'show', path.to_s)
    if info =~ /Generation[^:]*:\s+(\d+)/
        Integer($1)
    else
        raise UnexpectedBtrfsOutput, "unexpected output for 'btrfs subvolume show', expected #{info} to contain a Generation: line"
    end
end

.popen(*args, mode: 'r', raise_on_error: true, **options) ⇒ Object

This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.

A IO.popen-like API to btrfs subcommands



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
# File 'lib/snapsync/btrfs.rb', line 26

def self.popen(*args, mode: 'r', raise_on_error: true, **options)
    err_r, err_w = IO.pipe

    block_error, block_result = nil
    IO.popen(['btrfs', *args, err: err_w, **options], mode) do |io|
        err_w.close

        begin
            block_result = yield(io)
        rescue Error
            raise
        rescue Exception => block_error
        end
    end

    if $?.success? && !block_error
        block_result
    elsif raise_on_error
        if block_error
            raise Error.new, block_error.message
        else
            raise Error.new, "btrfs failed"
        end
    end

rescue Error => e
    prefix = args.join(" ")
    lines = err_r.readlines.map do |line|
        "#{prefix}: #{line.chomp}"
    end
    raise Error.new(e.error_lines + lines), e.message, e.backtrace

ensure err_r.close
end

.run(*args, **options) ⇒ Object



61
62
63
64
65
# File 'lib/snapsync/btrfs.rb', line 61

def self.run(*args, **options)
    popen(*args, **options) do |io|
        io.read.encode('utf-8', undef: :replace, invalid: :replace)
    end
end