perlopenvz

Where is the code of subroutine in the VZDump package?


I am trying to understand VZDump's source code which I found on debian repository. Creating snapshots and their compression is exactly what I am looking for. However, I cannot find the code that creates them.

I see that here: https://sources.debian.org/src/vzdump/1.2.6-5/VZDump.pm/#L913 is $plugin->snapshot being called so I expect, that this part of the code is where program goes to next: https://sources.debian.org/src/vzdump/1.2.6-5/Plugin.pm/#L119 . But there is die command with comment # implement in subclass and I cannot find where is the actual process of creating a snapshot or where is the subclass located.

Can you please explain to me, what is happening in this case ? Where does the code that creates snapshots reside ?


Solution

  • The code for creating a snapshot is located at Line 277-306 of OpenVZ.pm. OpenVZ.pm is the subclass of Plugin.pm. snapshot() shells out to the lvcreate command for actually creating the snapshots. $self->cmd in snapshot() method calls Plugin's cmd() method, which calls run_command() in VZDump.pm, which calls open3 from IPC::Open3.

    When calling a method on a subclass, Perl tries to call the derived method first. If there is no method by that name in the subclass, then it calls the superclass's method. If that class doesn't have the method, then Perl checks the superclass's superclass, and so on. If Perl reached the base class and didn't find the method that the program was attempting to call, then it gives an error. Because OpenVZ.pm defined a snapshot method, Plugin's snapshot method that just calls die is never executed.

    line 277-306 of OpenVZ.pm

    sub snapshot {
        my ($self, $task) = @_;
    
        my $opts = $self->{vzdump}->{opts};
    
        my $di = $task->{diskinfo};
    
        mkpath $di->{mountpoint}; # create mount point for lvm snapshot
    
        if (-b $di->{snapdev}) {
        $self->loginfo ("trying to remove stale snapshot '$di->{snapdev}'");
            
        $self->cmd_noerr ("umount $di->{mountpoint}");
            
        $self->cmd_noerr ("lvremove -f $di->{snapdev}");
        }
    
        $self->loginfo ("creating lvm snapshot of $di->{srcdev} ('$di->{snapdev}')");
    
        $task->{cleanup}->{lvm_snapshot} = 1;
        
        $self->cmd ("lvcreate --size $opts->{size}M --snapshot" .
            " --name $di->{snapname} /dev/$di->{lvmvg}/$di->{lvmlv}");
    
        my $mopts = $di->{fstype} eq 'xfs' ? "-o nouuid" : '';
    
        $task->{cleanup}->{snapshot_mount} = 1;
    
        $self->cmd ("mount -t $di->{fstype} $mopts $di->{snapdev} $di->{mountpoint}");
    }