forked from bicomsystems/go-libzfs
-
Notifications
You must be signed in to change notification settings - Fork 1
/
common.c
executable file
·306 lines (293 loc) · 7.63 KB
/
common.c
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
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
#include <libzfs.h>
#include <memory.h>
#include <string.h>
#include <stdio.h>
#include "common.h"
libzfs_handle_t *g_zfs;
libzfs_handle_t *libzfs_get_handle() {
return g_zfs;
}
int go_libzfs_init() {
g_zfs = libzfs_init();
return 0;
}
int libzfs_last_error() {
return libzfs_errno(libzfs_get_handle());
}
const char *libzfs_last_error_str() {
return libzfs_error_description(libzfs_get_handle());
}
int libzfs_clear_last_error() {
zfs_standard_error(libzfs_get_handle(), EZFS_SUCCESS, "success");
return 0;
}
property_list_t *new_property_list() {
property_list_t *r = malloc(sizeof(property_list_t));
if (r == NULL) return NULL;
memset(r, 0, sizeof(property_list_t));
return r;
}
void free_properties(property_list_t *list) {
property_list_t *tmp = 0;
while (list) {
tmp = list;
list = list->pnext;
free(tmp);
}
}
nvlist_ptr new_property_nvlist() {
nvlist_ptr props = NULL;
int r = nvlist_alloc(&props, NV_UNIQUE_NAME, 0);
if ( r != 0 ) {
return NULL;
}
return props;
}
int property_nvlist_add(nvlist_ptr list, const char *prop, const char *value) {
return nvlist_add_string(list, prop, value);
}
int redirect_libzfs_stdout(int to) {
int save, res;
save = dup(STDOUT_FILENO);
if (save < 0) {
return save;
}
res = dup2(to, STDOUT_FILENO);
if (res < 0) {
return res;
}
return save;
}
int restore_libzfs_stdout(int saved) {
int res;
fflush(stdout);
res = dup2(saved, STDOUT_FILENO);
if (res < 0) {
return res;
}
close(saved);
}
const char *libzfs_strerrno(int errcode) {
switch (errcode) {
case EZFS_SUCCESS:
return "success";
case EZFS_NOMEM:
return "out of memory";
case EZFS_BADPROP:
return "invalid property value";
case EZFS_PROPREADONLY:
return "read-only property";
case EZFS_PROPTYPE:
return "property doesn't apply to datasets of this type";
case EZFS_PROPNONINHERIT:
return "property cannot be inherited";
case EZFS_PROPSPACE:
return "invalid quota or reservation";
case EZFS_BADTYPE:
return "operation not applicable to datasets of this type";
case EZFS_BUSY:
return "pool or dataset is busy";
case EZFS_EXISTS:
return "pool or dataset exists";
case EZFS_NOENT:
return "no such pool or dataset";
case EZFS_BADSTREAM:
return "invalid backup stream";
case EZFS_DSREADONLY:
return "dataset is read-only";
case EZFS_VOLTOOBIG:
return "volume size exceeds limit for this system";
case EZFS_INVALIDNAME:
return "invalid name";
case EZFS_BADRESTORE:
return "unable to restore to destination";
case EZFS_BADBACKUP:
return "backup failed";
case EZFS_BADTARGET:
return "invalid target vdev";
case EZFS_NODEVICE:
return "no such device in pool";
case EZFS_BADDEV:
return "invalid device";
case EZFS_NOREPLICAS:
return "no valid replicas";
case EZFS_RESILVERING:
return "currently resilvering";
case EZFS_BADVERSION:
return "unsupported version or feature";
case EZFS_POOLUNAVAIL:
return "pool is unavailable";
case EZFS_DEVOVERFLOW:
return "too many devices in one vdev";
case EZFS_BADPATH:
return "must be an absolute path";
case EZFS_CROSSTARGET:
return "operation crosses datasets or pools";
case EZFS_ZONED:
return "dataset in use by local zone";
case EZFS_MOUNTFAILED:
return "mount failed";
case EZFS_UMOUNTFAILED:
return "umount failed";
case EZFS_UNSHARENFSFAILED:
return "unshare(1M) failed";
case EZFS_SHARENFSFAILED:
return "share(1M) failed";
case EZFS_UNSHARESMBFAILED:
return "smb remove share failed";
case EZFS_SHARESMBFAILED:
return "smb add share failed";
case EZFS_PERM:
return "permission denied";
case EZFS_NOSPC:
return "out of space";
case EZFS_FAULT:
return "bad address";
case EZFS_IO:
return "I/O error";
case EZFS_INTR:
return "signal received";
case EZFS_ISSPARE:
return "device is reserved as a hot spare";
case EZFS_INVALCONFIG:
return "invalid vdev configuration";
case EZFS_RECURSIVE:
return "recursive dataset dependency";
case EZFS_NOHISTORY:
return "no history available";
case EZFS_POOLPROPS:
return "failed to retrieve pool properties";
case EZFS_POOL_NOTSUP:
return "operation not supported on this type of pool";
case EZFS_POOL_INVALARG:
return "invalid argument for this pool operation";
case EZFS_NAMETOOLONG:
return "dataset name is too long";
case EZFS_OPENFAILED:
return "open failed";
case EZFS_NOCAP:
return "disk capacity information could not be retrieved";
case EZFS_LABELFAILED:
return "write of label failed";
case EZFS_BADWHO:
return "invalid user/group";
case EZFS_BADPERM:
return "invalid permission";
case EZFS_BADPERMSET:
return "invalid permission set name";
case EZFS_NODELEGATION:
return "delegated administration is disabled on pool";
case EZFS_BADCACHE:
return "invalid or missing cache file";
case EZFS_ISL2CACHE:
return "device is in use as a cache";
case EZFS_VDEVNOTSUP:
return "vdev specification is not supported";
case EZFS_NOTSUP:
return "operation not supported on this dataset";
#ifdef EZFS_IOC_NOTSUPPORTED
case EZFS_IOC_NOTSUPPORTED:
return "operation not supported by zfs kernel module";
#endif
case EZFS_ACTIVE_SPARE:
return "pool has active shared spare device";
case EZFS_UNPLAYED_LOGS:
return "log device has unplayed intent logs";
case EZFS_REFTAG_RELE:
return "no such tag on this dataset";
case EZFS_REFTAG_HOLD:
return "tag already exists on this dataset";
case EZFS_TAGTOOLONG:
return "tag too long";
case EZFS_PIPEFAILED:
return "pipe create failed";
case EZFS_THREADCREATEFAILED:
return "thread create failed";
case EZFS_POSTSPLIT_ONLINE:
return "disk was split from this pool into a new one";
case EZFS_SCRUB_PAUSED:
return "scrub is paused; use 'zpool scrub' to resume";
case EZFS_SCRUBBING:
return "currently scrubbing; use 'zpool scrub -s' to cancel current scrub";
case EZFS_NO_SCRUB:
return "there is no active scrub";
case EZFS_DIFF:
return "unable to generate diffs";
case EZFS_DIFFDATA:
return "invalid diff data";
case EZFS_POOLREADONLY:
return "pool is read-only";
#ifdef EZFS_NO_PENDING
case EZFS_NO_PENDING:
return "operation is not in progress";
#endif
#ifdef EZFS_CHECKPOINT_EXISTS
case EZFS_CHECKPOINT_EXISTS:
return "checkpoint exists";
#endif
#ifdef EZFS_DISCARDING_CHECKPOINT
case EZFS_DISCARDING_CHECKPOINT:
return "currently discarding checkpoint";
#endif
#ifdef EZFS_NO_CHECKPOINT
case EZFS_NO_CHECKPOINT:
return "checkpoint does not exist";
#endif
#ifdef EZFS_DEVRM_IN_PROGRESS
case EZFS_DEVRM_IN_PROGRESS:
return "device removal in progress";
#endif
#ifdef EZFS_VDEV_TOO_BIG
case EZFS_VDEV_TOO_BIG:
return "device exceeds supported size";
#endif
#ifdef EZFS_ACTIVE_POOL
case EZFS_ACTIVE_POOL:
return "pool is imported on a different host";
#endif
#ifdef EZFS_CRYPTOFAILED
case EZFS_CRYPTOFAILED:
return "encryption failure";
#endif
#ifdef EZFS_TOOMANY
case EZFS_TOOMANY:
return "argument list too long";
#endif
#ifdef EZFS_INITIALIZING
case EZFS_INITIALIZING:
return "currently initializing";
#endif
#ifdef EZFS_NO_INITIALIZE
case EZFS_NO_INITIALIZE:
return "there is no active initialization";
#endif
#ifdef EZFS_WRONG_PARENT
case EZFS_WRONG_PARENT:
return "invalid parent dataset";
#endif
#ifdef EZFS_TRIMMING
case EZFS_TRIMMING:
return "currently trimming";
#endif
#ifdef EZFS_NO_TRIM
case EZFS_NO_TRIM:
return "there is no active trim";
#endif
#ifdef EZFS_TRIM_NOTSUP
case EZFS_TRIM_NOTSUP:
return "trim operations are not supported by this device";
#endif
#ifdef EZFS_NO_RESILVER_DEFER
case EZFS_NO_RESILVER_DEFER:
return "this action requires the resilver_defer feature";
#endif
#ifdef EZFS_EXPORT_IN_PROGRESS
case EZFS_EXPORT_IN_PROGRESS:
return ("pool export in progress");
#endif
case EZFS_UNKNOWN:
return "unknown error";
default:
return "no error";
}
}