func (d *Btrfs) Snapshot(config config.Config, srcSnapshot string) (string, error) { snapshot_dir := config.Subvolume() + "/" + config.SubvolumeDirectory() t := time.Now() timestamp := t.Format("20060102150405") snapshot := snapshot_dir + "/btrfs_backup_" + timestamp log.Printf("Making sure of the source directory: %s", srcSnapshot) var stderr bytes.Buffer cmd := exec.Command("btrfs", "subvolume", "show", srcSnapshot) cmd.Stderr = &stderr if err := cmd.Start(); err != nil { return "", err } if err := cmd.Wait(); err != nil { err = fmt.Errorf("Error checking for a valid subvolume: %s\nStderr: %s", err, stderr.String()) return "", err } log.Printf("Valid subvolume found: %s", srcSnapshot) log.Printf("Making sure of the destination directory: %s", snapshot_dir) create_destination := false var stderr3 bytes.Buffer cmd = exec.Command("btrfs", "subvolume", "show", snapshot_dir) cmd.Stderr = &stderr3 if err := cmd.Start(); err != nil { return "", err } if err := cmd.Wait(); err != nil { create_destination = true } if create_destination == true { log.Printf("Error in verifying the destination subvolume %s, trying to create it", snapshot_dir) new_volume, err_create := d.CreateSubvolume(snapshot_dir) if new_volume == snapshot_dir && err_create == nil { log.Printf("New subvolume created: %s", snapshot_dir) } else { err_create = fmt.Errorf("Error creating new subvolume. \nStderr: %s", err_create) return "", err_create } } log.Printf("Valid subvolume found: %s", snapshot_dir) // all good, is a valid subvolume source and destination log.Printf("Creating snapshot in: %s", snapshot) var stderr2 bytes.Buffer cmd = exec.Command("btrfs", "subvolume", "snapshot", "-r", srcSnapshot, snapshot) cmd.Stderr = &stderr2 if err := cmd.Start(); err != nil { return "", err } if err := cmd.Wait(); err != nil { err = fmt.Errorf("Error creating snapshot: %s\nStderr: %s", err, stderr2.String()) return "", err } cmd = exec.Command("sync", snapshot_dir) cmd.Stderr = &stderr2 if err := cmd.Start(); err != nil { return "", err } if err := cmd.Wait(); err != nil { err = fmt.Errorf("Error running filesystem sync: %s\nStderr: %s", err, stderr2.String()) return "", err } log.Printf("Snapshot created: %s from %s", snapshot, srcSnapshot) return snapshot, nil }