-
Notifications
You must be signed in to change notification settings - Fork 1
Expand file tree
/
Copy pathlvdiff.go
More file actions
executable file
·94 lines (80 loc) · 2.36 KB
/
lvdiff.go
File metadata and controls
executable file
·94 lines (80 loc) · 2.36 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
package main
import (
"os"
"fmt"
"strings"
"github.com/hyperblock/lvdiff/lvbackup"
"github.com/spf13/cobra"
)
type Pair struct {
key, value string
}
const c_HEADER = "HYPERLAYER/1.0\n"
func main() {
var rootCmd *cobra.Command
//var pool string
// var head string
var metaPairs []string
// var value []string
var vgname string
var vol0, vol1 string
var depth int32
//var output string
// header := c_HEADER
rootCmd = &cobra.Command{
Use: "lvdiff <volume_A> <volume_B>",
Short: "lvdiff is a tool to dump differential blocks of two thin volumes.",
Run: func(cmd *cobra.Command, args []string) {
if vgname == "" || len(args) < 2 {
fmt.Fprintf(os.Stderr, "Too few arguments.")
rootCmd.Usage()
return
}
if depth < 0 && depth > 3 {
fmt.Fprintf(os.Stderr, "Detect level range: 0-3")
rootCmd.Usage()
return
}
//pair := []Pair{}
header := []byte{}
for _, obj := range metaPairs {
token := strings.Split(obj, ":")
if len(token) != 2 {
fmt.Fprintf(os.Stderr, "Invalid key-value pair: %s\n", obj)
rootCmd.Usage()
return
}
token[0] = strings.TrimLeft(strings.TrimRight(token[0], " "), " ")
token[1] = strings.TrimLeft(strings.TrimRight(token[1], " "), " ")
// pair = append(pair, Pair{key: token[0], value: token[1]})
buf := fmt.Sprintf("%s: %s\n", token[0], token[1])
//print(token[0], token[1])
header = append(header, []byte(buf)...)
}
vol1, vol0 = args[0], args[1]
f := os.Stdout
sender, err := lvbackup.NewStreamSender(vgname, vol1, vol0, f, int(depth))
if err != nil {
fmt.Fprintln(os.Stderr, err)
return
}
if err := sender.Run(header); err != nil {
fmt.Fprintln(os.Stderr, err)
return
}
},
}
rootCmd.Flags().StringVarP(&vgname, "lvgroup", "g", "", "volume group.")
// rootCmd.Flags().StringVarP(&pool, "pool", "p", "", "thin volume pool.")
rootCmd.Flags().Int32VarP(&depth, "", "d", 2, `checksum detect level. range: 0-3
0 means no checksum,
1 means only check head block,
2 means random check,
3 means scan all data blocks.`)
rootCmd.Flags().StringArrayVarP(&metaPairs, "meta", "", nil, "set metadata (format as '$key:$value').")
//rootCmd.Flags().StringArrayVarP(&value, "value", "", nil, "set value.")
if err := rootCmd.Execute(); err != nil {
os.Exit(-1)
}
os.Exit(0)
}