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
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
|
#compdef zpool
# Synced with the S11U1 man page
_zpool() {
local context state line expl
local -a subcmds fields ro_props rw_props versions create_properties_dataset
subcmds=(
create destroy add remove list iostat status online
offline clear attach detach replace scrub import export
upgrade history get set split help
)
versions=(
${${${(M)"${(f)$(_call_program versions zpool upgrade -v)}":#[[:space:]]#<->*}##[[:space:]]}%%[[:space:]]*}
)
ro_props=(
"all[All properties]"
"allocated[Space allocated]"
"capacity[Space used (percentage)]"
"dedupratio[Deduplication ratio]"
"free[Space unallocated]"
"guid[Unique identifier]"
"health[Health status]"
"size[Total size]"
)
rw_props=(
"altroot[Alternate root directory]:value:"
"autoexpand[Automatic pool expansion]:value:(on off)"
"autoreplace[Automatic device replacement]:value:(on off)"
"bootfs[Default bootable dataset]:value:"
"cachefile[Pool configuration cache file location]:value:"
"dedupditto[Threshold for number of copies]:value:"
"delegation[Delegated administration]:value:(on off)"
"failmode[Failure-mode behavior]:value:(wait continue panic)"
"listshares[Show shares in 'zfs list']:value:(on off)"
"listsnaps[Show snapshots in 'zfs list']:value:(on off)"
"readonly[Controls whether the pool can be modified]:value:(on off)"
"version[Pool version]:version:($versions)"
)
fields=( ${ro_props%%:*} ${rw_props%%:*} )
create_properties_dataset=(
"aclinherit:value:(discard noallow restricted passthrough passthrough-x)"
"aclmode:value:(discard mask passthrough)"
"atime:value:(on off)"
"canmount:value:(on off noauto)"
"checksum:value:(on off fletcher2 fletcher4 sha256 sha256+mac)"
"compression:value:(on off lzjb gzip gzip-{1..9} zle)"
"copies:value:(1 2 3)"
"dedup:value:(on off verify sha256 sha256,verify)"
"devices:value:(on off)"
"encryption:value:(off on aes128-ccm aes-192-ccm aes-256-ccm aes-128-gcm aes-192-gcm aes-256-gcm)"
"exec:value:(on off)"
"groupquota@:value:" # TODO: complete group=size|none
"keysource:value:_zfs_keysource_props"
"logbias:value:(latency throughput)"
"mlslabel:value:(none)" # TODO: list sensitivity labels
"mountpoint:path, 'legacy', or 'none':{if [[ -prefix /* ]]; then _path_files -/; else _wanted mountpoints expl 'mountpoint (type \"/\" to start completing paths)' compadd legacy none; fi}"
"nbmand:value:(on off)"
"primarycache:value:(all none metadata)"
"quota:number or 'none':{if [[ -prefix [0-9]## ]]; then _message -e 'number'; elif [[ $PREFIX == quota= ]]; then _wanted none expl 'number or none' compadd none; else _wanted none expl 'quota' compadd none; fi}"
"readonly:value:(on off)"
"recordsize:value:(512 1K 2K 4K 8K 16K 32K 64K 128K 256K 512K 1M)"
"refquota:number or 'none':{if [[ -prefix [0-9]## ]]; then _message -e 'number'; elif [[ $PREFIX == refquota= ]]; then _wanted none expl 'number or none' compadd none; else _wanted none expl 'refquota' compadd none; fi}"
"refreservation:number or 'none':{if [[ -prefix [0-9]## ]]; then _message -e 'number'; elif [[ $PREFIX == refreservation= ]]; then _wanted none expl 'number or none' compadd none; else _wanted none expl 'refreservation' compadd none; fi}"
"reservation:value:{if [[ -prefix [0-9]## ]]; then _message -e 'number'; elif [[ $PREFIX == reservation= ]]; then _wanted none expl 'number or none' compadd none; else _wanted none expl 'reservation' compadd none; fi}"
"rstchown:value:(on off)"
"secondarycache:value:(all none metadata)"
"setuid:value:(on off)"
"shadow:value:" # TODO: complete URI|none
"share:share properties:"
"sharenfs:value:(on off)"
"sharesmb:value:(on off)"
"snapdir:value:(hidden visible)"
"sync:value:(standard always disabled)"
"userquota@:value:" # TODO: complete user=size|none
"version:value:(1 2 3 4 current)"
"volsize:value:" # <size>
"vscan:value:(on off)"
"xattr:value:(on off)"
"zoned:value:(on off)"
)
if [[ $service == "zpool" ]]; then
_arguments -C -A "-*" \
'-\?[show help information]' \
'1:subcommand:compadd -a subcmds' \
'*:: :->subcmd' && return
service="$words[1]"
curcontext="${curcontext%:*}-$service:"
fi
case $service in
(help)
_arguments -A "-*" \
- set1 \
':command/property:($subcmds ${fields%%\[*} properties)' \
- set2 \
'-l[Display property information]' \
': :(properties)'
;;
(clear)
_arguments -A "-*" \
'-F[Discard transactions to allow pool opening]' \
'-f[Ignore fmadm acquit and fmadm repair failures]' \
'-n[With -F, check if discarding transactions would work]' \
':pool name:_zfs_pool' \
'*:virtual device:_files'
;;
(create)
# TODO: investigate better vdev handling
_arguments -A "-*" \
'-B[Create EFI boot partition on whole disks]' \
'-o[Set pool property at creation time]:property:_values -s , "property" $rw_props' \
'-O[Set dataset property at creation time]:property:_values -s , "property" $create_properties_dataset' \
'-f[Force use of in-use devices]' \
'-l[Display configuration in /dev/chassis location form]' \
'-n[Display configuration without creating pool]' \
'-R[Use alternate root]:alternate root:_files -/' \
'-m[Set mountpoint for root dataset]:mountpoint:' \
':pool name:' \
'*:virtual device:_files'
;;
(destroy)
_arguments -A "-*" \
'-f[Force active datasets to be unmounted]' \
':pool name:_zfs_pool'
;;
(add)
_arguments -A "-*" \
'-f[Force use of in-use devices]' \
'-l[Display configuration in /dev/chassis location form]' \
'-n[Display configuration without modifying pool]' \
':pool name:_zfs_pool' \
'*:virtual device:_files'
;;
(list)
_arguments \
'-H[Scripted mode]' \
'-T[timestamp]:value:(u d)' \
'-o[Fields to list]:field:_values -s , "field" $fields' \
'::pool name:_zfs_pool'
;;
(iostat)
_arguments -A "-*" \
'-l[Display configuration in /dev/chassis location form]' \
'-T[timestamp]:value:(u d)' \
'-v[Verbose statistics]' \
'*::pool name:_zfs_pool' \
'::interval:' \
'::count:'
;;
(status)
_arguments -A "-*" \
'-l[Display configuration in /dev/chassis location form]' \
'-v[Verbose information]' \
'-x[Show only unhealthy pools]' \
'-T[timestamp]:value:(u d)' \
'*::pool name:_zfs_pool'
;;
(offline)
_arguments -A "-*" \
'-t[Offline until next reboot]' \
':pool name:_zfs_pool' \
'*:virtual device:_files'
;;
(online)
_arguments \
'-e[Expand device to use all available space]' \
':pool name:_zfs_pool' \
'*:virtual device:_files'
;;
(attach)
# TODO: first device should choose first from existing.
_arguments \
'-f[Force attach, even if in use]' \
':pool name:_zfs_pool' \
':virtual device:_files' \
':virtual device:_files'
;;
(detach)
_arguments \
':pool name:_zfs_pool' \
':virtual device:_files'
;;
(replace)
_arguments -A "-*" \
'-f[Force attach, even if in use]' \
':pool name:_zfs_pool' \
':virtual device:_files' \
'::virtual device:_files'
;;
(scrub)
_arguments -A "-*" \
'-s[Stop scrubbing]' \
'*:pool name:_zfs_pool'
;;
(export)
_arguments -A "-*" \
'-f[Forcefully unmount all datasets]' \
'*:pool name:_zfs_pool'
;;
(import)
# TODO: -o should complete mount options, too
_arguments -A "-*" \
'-D[Destroyed pools]' \
'(-d)*-c[Use cache file]:cache file:_files' \
'(-c,-D)*-d[Search for devices or files in directory]:directory:_files -/' \
'-F[Recovery mode: discard transactions if required]' \
'-f[Force import]' \
'-l[Display configuration in /dev/chassis location form]' \
'-m[Ignore missing log devices]' \
'-N[Import pool without mounting any filesystems]' \
'-n[With -F; do not perform input]' \
'-R[Alternate root]:alternate root:_files -/' \
'-o[Set pool or dataset property]:property:_values -s , "property" $create_properties_dataset $rw_props' \
- set1 \
'*:pool name or id:_zfs_pool' \
'::new pool name:' \
- set2 \
'-N[Do not mount any filesystems]' \
'-a[All pools]'
;;
(get)
_arguments -A "-*" \
':property:_values -s , "property" $fields' \
'*:pool name:_zfs_pool'
;;
(set)
_arguments -A "-*" \
':property:_values -s , "property" $rw_props' \
'*:pool name:_zfs_pool'
;;
(split)
_arguments -A "-*" \
'-R[Alternate root]:alternate root:_files -/' \
'-l[Display configuration in /dev/chassis location form]' \
'-n[Display configuration without splitting]' \
'-o[Set pool or dataset property]:property:_values -s , "property" $create_properties_dataset $rw_props' \
':pool name or id:_zfs_pool' \
':new pool name:' \
'*::virtual device:_files -/'
;;
(upgrade)
_arguments -A "-*" \
- set1 \
'-v[Display ZFS versions and descriptions]' \
- set2 \
"-V[Upgrade to given version]:version:($versions)" \
'-a[Upgrade all pools]' \
'*:pool name:_zfs_pool'
;;
(history)
_arguments -A "-*" \
'-i[Display internal events]' \
'-l[Long format]' \
'*:pool name:_zfs_pool'
;;
(*)
_message "unknown zpool subcommand: $service"
;;
esac
}
_zpool "$@"
|