Example #1
0
// validate the config object
func validateConfig(backupConfig config.Config, driver *btrfs.Btrfs) error {

	// check to see if subvolume exists
	// do other sanity checks
	err := driver.Prepare(backupConfig)
	if err != nil {
		return err
	}

	// make sure that port number makes sense
	err = fmt.Errorf("Invalid port number: %d", backupConfig.DestinationPort)

	if backupConfig.DestinationPort > 65535 || backupConfig.DestinationPort < 1024 {
		return err
	}

	// do initial testing of system by listing subvolumes
	// and perform an initial snapshot for purposes of use later
	subvols, err := driver.Subvolumes(backupConfig)
	if err != nil && subvols == nil {
		return err
	}

	_, err2 := driver.Snapshot(backupConfig, "/")
	if err2 != nil {
		return err2
	}

	return nil
}
Example #2
0
// Do the majority of the application work,
// spawn off backup jobs, the like
//
// returns exit status for program
func process() error {

	// parse command line args
	subvolume_source := flag.String("subvolume", config.DefaultConfig().SubvolumePath, "Subvolume to back up.")
	subvolume_destination_directory := flag.String("destination_subvolume", config.DefaultConfig().SubvolumeDirectoryPath,
		"A relative path off of the subvolume path that will come to store snapshots.")
	server := flag.Bool("server", config.DefaultConfig().Server, "Whether to enable listening as a backup server.")
	destination_host := flag.String("host", config.DefaultConfig().DestinationHost, "Host to send backups to.")
	destination_port := flag.Int("port", config.DefaultConfig().DestinationPort,
		"TCP port of host to send backups to.  "+
			"Will also be the port to listen on in server mode.")

	flag.Parse()

	// header info
	info()

	// set backup configuration
	backupConfig := config.Config{*subvolume_source, *subvolume_destination_directory, *server, *destination_host, *destination_port}

	// create drivers
	btrfs_driver := new(btrfs.Btrfs)
	btrfs_driver.BackupConfig = backupConfig

	// validate
	err := validateConfig(backupConfig, btrfs_driver)

	if err != nil {
		return err
	}

	// start server if asked
	RPC := new(btrfs.BtrfsRPC)
	RPC.Driver = btrfs_driver

	if backupConfig.Server {
		rpc.Register(RPC)
		rpc.HandleHTTP()

		l, e := net.Listen("tcp", ":1234")
		if e != nil {
			log.Fatal("listen error:", e)
		}
		http.Serve(l, nil)

	} else {
		// otherwise we are a client.  Query the client for a list of snapshots to send!
		client, err := rpc.DialHTTP("tcp", backupConfig.DestinationHost+":"+string(backupConfig.DestinationPort))
		if err != nil {
			log.Fatal("dialing:", err)
		}

		// Synchronous call
		subvols, err := btrfs_driver.Subvolumes(backupConfig)
		args := btrfs.Args{subvols}
		var reply []string
		err = client.Call("BtrfsRPC.SnapshotsNeeded", args, &reply)
		if err != nil {
			log.Fatal("arith error:", err)
		}

		for i := 0; i < len(subvols); i++ {
			// Send all missing snapshots to other server
			// tell the other side to start receiving first

			btrfs_driver.SendSubvolume(subvols[i])
		}

	}

	return nil
}