+ my $snapshotname;
+ my $newsnapname;
+ if (defined $device) {
+ $snapshotname = "$directory\@$current_snapshot";
+ $newsnapname = "$directory\@$self->{'snapshot'}";
+ } else {
+ # find snapshot name
+ @cmd = ();
+ if ($self->{pfexec_cmd}) {
+ push @cmd, $self->{pfexec_cmd};
+ }
+ push @cmd, $self->{zfs_path};
+ push @cmd, "list";
+ push @cmd, "-r";
+ push @cmd, "-t";
+ push @cmd, "snapshot";
+ push @cmd, $directory;
+ debug("cmd:" . join(" ", @cmd));
+
+ my($wtr, $rdr, $err, $pid);
+ my($msg, $errmsg);
+ $err = Symbol::gensym;
+ $pid = open3($wtr, $rdr, $err, @cmd);
+ close $wtr;
+ while ($msg = <$rdr>) {
+ next if $msg =~ /^NAME/;
+ my ($name, $used, $avail) = split(/ +/, $msg);
+ if ($name =~ /-current$/) {
+ $snapshotname = $name;
+ last;
+ }
+ }
+ $errmsg = <$err>;
+ waitpid $pid, 0;
+ close $rdr;
+ close $err;
+
+ if (defined $snapshotname and defined($level)) {
+ $newsnapname = $snapshotname;
+ $newsnapname =~ s/current$/$level/;
+ } else {
+ # destroy the snapshot
+ # restoring next level will fail.
+ @cmd = ();
+ if ($self->{pfexec_cmd}) {
+ push @cmd, $self->{pfexec_cmd};
+ }
+ push @cmd, $self->{zfs_path};
+ push @cmd, "destroy";
+ push @cmd, $snapshotname;
+
+ debug("cmd:" . join(" ", @cmd));
+ system @cmd;
+ }