示例#1
0
func (remote RemoteSnapshotsLoc) SendSnapshot(snapshot Snapshot, parent Timestamp) (err error) {
	var sendCmd *exec.Cmd
	if parent == "" {
		if verbosity > 1 {
			log.Println("Performing full send/receive")
		}
		sendCmd = exec.Command(btrfsBin, "send", snapshot.Path())
	} else {
		if verbosity > 1 {
			log.Println("Performing incremental send/receive")
		}
		parentPath := path.Join(path.Dir(snapshot.Path()), string(parent))
		sendCmd = exec.Command(btrfsBin, "send", "-p", parentPath, snapshot.Path())
	}
	if verbosity > 1 {
		sendCmd.Stderr = os.Stderr
	}
	sendRd, sendWr := io.Pipe()
	defer sendRd.Close()
	var recvRunner CmdRunner
	var compOut *snappy.Writer
	closeComp := false
	if remote.Host == "" {
		sendCmd.Stdout = sendWr
		recvRunner = remote.SnapshotsLoc.ReceiveAndCleanUp(sendRd, snapshot.timestamp)
	} else {
		if *noCompressionFlag {
			sendCmd.Stdout = sendWr
			recvRunner = remote.RemoteReceive(sendRd, snapshot.timestamp)
		} else {
			compOut = snappy.NewBufferedWriter(sendWr)
			closeComp = true
			sendCmd.Stdout = compOut
			recvRunner = remote.RemoteReceive(sendRd, snapshot.timestamp)
		}
	}
	sendRunner := RunCommand(sendCmd)

	err = <-recvRunner.Started
	if err != nil {
		log.Println("Error starting btrfs receive")
		return
	}

	if verbosity > 1 {
		printCommand(sendCmd)
	}
	err = <-sendRunner.Started
	if err != nil {
		log.Println("Error starting btrfs send")
		return
	}
	select {
	case err = <-sendRunner.Done:
		if err != nil {
			log.Println("Error running btrfs send")
		}
		if closeComp {
			compOut.Close()
		}
		sendWr.Close()
		<-recvRunner.Done
		return
	case err = <-recvRunner.Done:
		if err != nil {
			log.Println("Error running btrfs receive")
		}
		sendRunner.Signal <- os.Kill
		<-sendRunner.Done
		return
	}
}