1 789 ahrens /* 2 789 ahrens * CDDL HEADER START 3 789 ahrens * 4 789 ahrens * The contents of this file are subject to the terms of the 5 1544 eschrock * Common Development and Distribution License (the "License"). 6 1544 eschrock * You may not use this file except in compliance with the License. 7 789 ahrens * 8 789 ahrens * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE 9 789 ahrens * or http://www.opensolaris.org/os/licensing. 10 789 ahrens * See the License for the specific language governing permissions 11 789 ahrens * and limitations under the License. 12 789 ahrens * 13 789 ahrens * When distributing Covered Code, include this CDDL HEADER in each 14 789 ahrens * file and include the License file at usr/src/OPENSOLARIS.LICENSE. 15 789 ahrens * If applicable, add the following below this CDDL HEADER, with the 16 789 ahrens * fields enclosed by brackets "[]" replaced with your own identifying 17 789 ahrens * information: Portions Copyright [yyyy] [name of copyright owner] 18 789 ahrens * 19 789 ahrens * CDDL HEADER END 20 789 ahrens */ 21 789 ahrens /* 22 8811 Eric * Copyright 2009 Sun Microsystems, Inc. All rights reserved. 23 789 ahrens * Use is subject to license terms. 24 789 ahrens */ 25 789 ahrens 26 789 ahrens /* 27 789 ahrens * Internal utility routines for the ZFS library. 28 789 ahrens */ 29 789 ahrens 30 789 ahrens #include <errno.h> 31 789 ahrens #include <fcntl.h> 32 789 ahrens #include <libintl.h> 33 789 ahrens #include <stdarg.h> 34 789 ahrens #include <stdio.h> 35 789 ahrens #include <stdlib.h> 36 789 ahrens #include <strings.h> 37 789 ahrens #include <unistd.h> 38 5094 lling #include <ctype.h> 39 5094 lling #include <math.h> 40 789 ahrens #include <sys/mnttab.h> 41 3635 ck153898 #include <sys/mntent.h> 42 3635 ck153898 #include <sys/types.h> 43 789 ahrens 44 789 ahrens #include <libzfs.h> 45 789 ahrens 46 789 ahrens #include "libzfs_impl.h" 47 4787 ahrens #include "zfs_prop.h" 48 789 ahrens 49 2082 eschrock int 50 2082 eschrock libzfs_errno(libzfs_handle_t *hdl) 51 2082 eschrock { 52 2082 eschrock return (hdl->libzfs_error); 53 2082 eschrock } 54 789 ahrens 55 2082 eschrock const char * 56 2082 eschrock libzfs_error_action(libzfs_handle_t *hdl) 57 2082 eschrock { 58 2082 eschrock return (hdl->libzfs_action); 59 2082 eschrock } 60 789 ahrens 61 2082 eschrock const char * 62 2082 eschrock libzfs_error_description(libzfs_handle_t *hdl) 63 2082 eschrock { 64 2082 eschrock if (hdl->libzfs_desc[0] != '\0') 65 2082 eschrock return (hdl->libzfs_desc); 66 2082 eschrock 67 2082 eschrock switch (hdl->libzfs_error) { 68 2082 eschrock case EZFS_NOMEM: 69 2082 eschrock return (dgettext(TEXT_DOMAIN, "out of memory")); 70 2082 eschrock case EZFS_BADPROP: 71 2082 eschrock return (dgettext(TEXT_DOMAIN, "invalid property value")); 72 2082 eschrock case EZFS_PROPREADONLY: 73 2082 eschrock return (dgettext(TEXT_DOMAIN, "read only property")); 74 2082 eschrock case EZFS_PROPTYPE: 75 2082 eschrock return (dgettext(TEXT_DOMAIN, "property doesn't apply to " 76 2082 eschrock "datasets of this type")); 77 2082 eschrock case EZFS_PROPNONINHERIT: 78 2082 eschrock return (dgettext(TEXT_DOMAIN, "property cannot be inherited")); 79 2082 eschrock case EZFS_PROPSPACE: 80 2082 eschrock return (dgettext(TEXT_DOMAIN, "invalid quota or reservation")); 81 2082 eschrock case EZFS_BADTYPE: 82 2082 eschrock return (dgettext(TEXT_DOMAIN, "operation not applicable to " 83 2082 eschrock "datasets of this type")); 84 2082 eschrock case EZFS_BUSY: 85 2082 eschrock return (dgettext(TEXT_DOMAIN, "pool or dataset is busy")); 86 2082 eschrock case EZFS_EXISTS: 87 2082 eschrock return (dgettext(TEXT_DOMAIN, "pool or dataset exists")); 88 2082 eschrock case EZFS_NOENT: 89 2082 eschrock return (dgettext(TEXT_DOMAIN, "no such pool or dataset")); 90 2082 eschrock case EZFS_BADSTREAM: 91 2082 eschrock return (dgettext(TEXT_DOMAIN, "invalid backup stream")); 92 2082 eschrock case EZFS_DSREADONLY: 93 2082 eschrock return (dgettext(TEXT_DOMAIN, "dataset is read only")); 94 2082 eschrock case EZFS_VOLTOOBIG: 95 2082 eschrock return (dgettext(TEXT_DOMAIN, "volume size exceeds limit for " 96 2082 eschrock "this system")); 97 2082 eschrock case EZFS_INVALIDNAME: 98 2082 eschrock return (dgettext(TEXT_DOMAIN, "invalid name")); 99 2082 eschrock case EZFS_BADRESTORE: 100 2082 eschrock return (dgettext(TEXT_DOMAIN, "unable to restore to " 101 2082 eschrock "destination")); 102 2082 eschrock case EZFS_BADBACKUP: 103 2082 eschrock return (dgettext(TEXT_DOMAIN, "backup failed")); 104 2082 eschrock case EZFS_BADTARGET: 105 2082 eschrock return (dgettext(TEXT_DOMAIN, "invalid target vdev")); 106 2082 eschrock case EZFS_NODEVICE: 107 2082 eschrock return (dgettext(TEXT_DOMAIN, "no such device in pool")); 108 2082 eschrock case EZFS_BADDEV: 109 2082 eschrock return (dgettext(TEXT_DOMAIN, "invalid device")); 110 2082 eschrock case EZFS_NOREPLICAS: 111 2082 eschrock return (dgettext(TEXT_DOMAIN, "no valid replicas")); 112 2082 eschrock case EZFS_RESILVERING: 113 2082 eschrock return (dgettext(TEXT_DOMAIN, "currently resilvering")); 114 2082 eschrock case EZFS_BADVERSION: 115 2082 eschrock return (dgettext(TEXT_DOMAIN, "unsupported version")); 116 2082 eschrock case EZFS_POOLUNAVAIL: 117 2082 eschrock return (dgettext(TEXT_DOMAIN, "pool is unavailable")); 118 2082 eschrock case EZFS_DEVOVERFLOW: 119 2082 eschrock return (dgettext(TEXT_DOMAIN, "too many devices in one vdev")); 120 2082 eschrock case EZFS_BADPATH: 121 2082 eschrock return (dgettext(TEXT_DOMAIN, "must be an absolute path")); 122 2082 eschrock case EZFS_CROSSTARGET: 123 2082 eschrock return (dgettext(TEXT_DOMAIN, "operation crosses datasets or " 124 2082 eschrock "pools")); 125 2082 eschrock case EZFS_ZONED: 126 2082 eschrock return (dgettext(TEXT_DOMAIN, "dataset in use by local zone")); 127 2082 eschrock case EZFS_MOUNTFAILED: 128 2082 eschrock return (dgettext(TEXT_DOMAIN, "mount failed")); 129 2082 eschrock case EZFS_UMOUNTFAILED: 130 2082 eschrock return (dgettext(TEXT_DOMAIN, "umount failed")); 131 3126 ahl case EZFS_UNSHARENFSFAILED: 132 2082 eschrock return (dgettext(TEXT_DOMAIN, "unshare(1M) failed")); 133 3126 ahl case EZFS_SHARENFSFAILED: 134 2082 eschrock return (dgettext(TEXT_DOMAIN, "share(1M) failed")); 135 5331 amw case EZFS_UNSHARESMBFAILED: 136 5331 amw return (dgettext(TEXT_DOMAIN, "smb remove share failed")); 137 5331 amw case EZFS_SHARESMBFAILED: 138 5331 amw return (dgettext(TEXT_DOMAIN, "smb add share failed")); 139 4543 marks case EZFS_ISCSISVCUNAVAIL: 140 4543 marks return (dgettext(TEXT_DOMAIN, 141 4543 marks "iscsitgt service need to be enabled by " 142 4543 marks "a privileged user")); 143 2082 eschrock case EZFS_PERM: 144 2082 eschrock return (dgettext(TEXT_DOMAIN, "permission denied")); 145 2082 eschrock case EZFS_NOSPC: 146 2082 eschrock return (dgettext(TEXT_DOMAIN, "out of space")); 147 2082 eschrock case EZFS_IO: 148 2082 eschrock return (dgettext(TEXT_DOMAIN, "I/O error")); 149 2082 eschrock case EZFS_INTR: 150 2082 eschrock return (dgettext(TEXT_DOMAIN, "signal received")); 151 2082 eschrock case EZFS_ISSPARE: 152 2082 eschrock return (dgettext(TEXT_DOMAIN, "device is reserved as a hot " 153 2082 eschrock "spare")); 154 2082 eschrock case EZFS_INVALCONFIG: 155 2082 eschrock return (dgettext(TEXT_DOMAIN, "invalid vdev configuration")); 156 2474 eschrock case EZFS_RECURSIVE: 157 2474 eschrock return (dgettext(TEXT_DOMAIN, "recursive dataset dependency")); 158 2926 ek110237 case EZFS_NOHISTORY: 159 2926 ek110237 return (dgettext(TEXT_DOMAIN, "no history available")); 160 3126 ahl case EZFS_UNSHAREISCSIFAILED: 161 3126 ahl return (dgettext(TEXT_DOMAIN, 162 3126 ahl "iscsitgtd failed request to unshare")); 163 3126 ahl case EZFS_SHAREISCSIFAILED: 164 3126 ahl return (dgettext(TEXT_DOMAIN, 165 3126 ahl "iscsitgtd failed request to share")); 166 3912 lling case EZFS_POOLPROPS: 167 3912 lling return (dgettext(TEXT_DOMAIN, "failed to retrieve " 168 3912 lling "pool properties")); 169 3912 lling case EZFS_POOL_NOTSUP: 170 3912 lling return (dgettext(TEXT_DOMAIN, "operation not supported " 171 3912 lling "on this type of pool")); 172 3912 lling case EZFS_POOL_INVALARG: 173 3912 lling return (dgettext(TEXT_DOMAIN, "invalid argument for " 174 3912 lling "this pool operation")); 175 3978 mmusante case EZFS_NAMETOOLONG: 176 3978 mmusante return (dgettext(TEXT_DOMAIN, "dataset name is too long")); 177 4276 taylor case EZFS_OPENFAILED: 178 4276 taylor return (dgettext(TEXT_DOMAIN, "open failed")); 179 4276 taylor case EZFS_NOCAP: 180 4276 taylor return (dgettext(TEXT_DOMAIN, 181 4276 taylor "disk capacity information could not be retrieved")); 182 4276 taylor case EZFS_LABELFAILED: 183 4276 taylor return (dgettext(TEXT_DOMAIN, "write of label failed")); 184 4543 marks case EZFS_BADWHO: 185 4543 marks return (dgettext(TEXT_DOMAIN, "invalid user/group")); 186 4543 marks case EZFS_BADPERM: 187 4543 marks return (dgettext(TEXT_DOMAIN, "invalid permission")); 188 4543 marks case EZFS_BADPERMSET: 189 4543 marks return (dgettext(TEXT_DOMAIN, "invalid permission set name")); 190 4543 marks case EZFS_NODELEGATION: 191 4543 marks return (dgettext(TEXT_DOMAIN, "delegated administration is " 192 4543 marks "disabled on pool")); 193 4543 marks case EZFS_PERMRDONLY: 194 4543 marks return (dgettext(TEXT_DOMAIN, "snapshot permissions cannot be" 195 4543 marks " modified")); 196 5363 eschrock case EZFS_BADCACHE: 197 5363 eschrock return (dgettext(TEXT_DOMAIN, "invalid or missing cache file")); 198 5450 brendan case EZFS_ISL2CACHE: 199 5450 brendan return (dgettext(TEXT_DOMAIN, "device is in use as a cache")); 200 6423 gw25295 case EZFS_VDEVNOTSUP: 201 6423 gw25295 return (dgettext(TEXT_DOMAIN, "vdev specification is not " 202 6423 gw25295 "supported")); 203 7042 gw25295 case EZFS_NOTSUP: 204 7042 gw25295 return (dgettext(TEXT_DOMAIN, "operation not supported " 205 7042 gw25295 "on this dataset")); 206 7214 lling case EZFS_ACTIVE_SPARE: 207 7214 lling return (dgettext(TEXT_DOMAIN, "pool has active shared spare " 208 7214 lling "device")); 209 9701 George case EZFS_UNPLAYED_LOGS: 210 9701 George return (dgettext(TEXT_DOMAIN, "log device has unplayed intent " 211 9701 George "logs")); 212 10242 chris case EZFS_REFTAG_RELE: 213 10242 chris return (dgettext(TEXT_DOMAIN, "no such tag on this dataset")); 214 10242 chris case EZFS_REFTAG_HOLD: 215 10242 chris return (dgettext(TEXT_DOMAIN, "tag already exists on this " 216 10242 chris "dataset")); 217 10342 chris case EZFS_TAGTOOLONG: 218 10342 chris return (dgettext(TEXT_DOMAIN, "tag too long")); 219 11007 Lori case EZFS_PIPEFAILED: 220 11007 Lori return (dgettext(TEXT_DOMAIN, "pipe create failed")); 221 11007 Lori case EZFS_THREADCREATEFAILED: 222 11007 Lori return (dgettext(TEXT_DOMAIN, "thread create failed")); 223 2082 eschrock case EZFS_UNKNOWN: 224 2082 eschrock return (dgettext(TEXT_DOMAIN, "unknown error")); 225 2082 eschrock default: 226 2500 eschrock assert(hdl->libzfs_error == 0); 227 2500 eschrock return (dgettext(TEXT_DOMAIN, "no error")); 228 2082 eschrock } 229 2082 eschrock } 230 2082 eschrock 231 2082 eschrock /*PRINTFLIKE2*/ 232 789 ahrens void 233 2082 eschrock zfs_error_aux(libzfs_handle_t *hdl, const char *fmt, ...) 234 789 ahrens { 235 789 ahrens va_list ap; 236 789 ahrens 237 789 ahrens va_start(ap, fmt); 238 789 ahrens 239 2082 eschrock (void) vsnprintf(hdl->libzfs_desc, sizeof (hdl->libzfs_desc), 240 2082 eschrock fmt, ap); 241 2082 eschrock hdl->libzfs_desc_active = 1; 242 789 ahrens 243 789 ahrens va_end(ap); 244 789 ahrens } 245 789 ahrens 246 2082 eschrock static void 247 2082 eschrock zfs_verror(libzfs_handle_t *hdl, int error, const char *fmt, va_list ap) 248 2082 eschrock { 249 2082 eschrock (void) vsnprintf(hdl->libzfs_action, sizeof (hdl->libzfs_action), 250 2082 eschrock fmt, ap); 251 2082 eschrock hdl->libzfs_error = error; 252 2082 eschrock 253 2082 eschrock if (hdl->libzfs_desc_active) 254 2082 eschrock hdl->libzfs_desc_active = 0; 255 2082 eschrock else 256 2082 eschrock hdl->libzfs_desc[0] = '\0'; 257 2082 eschrock 258 2082 eschrock if (hdl->libzfs_printerr) { 259 2082 eschrock if (error == EZFS_UNKNOWN) { 260 2082 eschrock (void) fprintf(stderr, dgettext(TEXT_DOMAIN, "internal " 261 2082 eschrock "error: %s\n"), libzfs_error_description(hdl)); 262 2082 eschrock abort(); 263 2082 eschrock } 264 2082 eschrock 265 2082 eschrock (void) fprintf(stderr, "%s: %s\n", hdl->libzfs_action, 266 3912 lling libzfs_error_description(hdl)); 267 2082 eschrock if (error == EZFS_NOMEM) 268 2082 eschrock exit(1); 269 2082 eschrock } 270 2082 eschrock } 271 2082 eschrock 272 3237 lling int 273 3237 lling zfs_error(libzfs_handle_t *hdl, int error, const char *msg) 274 3237 lling { 275 3237 lling return (zfs_error_fmt(hdl, error, "%s", msg)); 276 3237 lling } 277 3237 lling 278 2082 eschrock /*PRINTFLIKE3*/ 279 2082 eschrock int 280 3237 lling zfs_error_fmt(libzfs_handle_t *hdl, int error, const char *fmt, ...) 281 789 ahrens { 282 789 ahrens va_list ap; 283 789 ahrens 284 789 ahrens va_start(ap, fmt); 285 789 ahrens 286 2082 eschrock zfs_verror(hdl, error, fmt, ap); 287 2082 eschrock 288 2082 eschrock va_end(ap); 289 2082 eschrock 290 2082 eschrock return (-1); 291 2082 eschrock } 292 2082 eschrock 293 2082 eschrock static int 294 2082 eschrock zfs_common_error(libzfs_handle_t *hdl, int error, const char *fmt, 295 2082 eschrock va_list ap) 296 2082 eschrock { 297 2082 eschrock switch (error) { 298 2082 eschrock case EPERM: 299 2082 eschrock case EACCES: 300 2082 eschrock zfs_verror(hdl, EZFS_PERM, fmt, ap); 301 2082 eschrock return (-1); 302 2082 eschrock 303 4543 marks case ECANCELED: 304 4543 marks zfs_verror(hdl, EZFS_NODELEGATION, fmt, ap); 305 4543 marks return (-1); 306 4543 marks 307 2082 eschrock case EIO: 308 2082 eschrock zfs_verror(hdl, EZFS_IO, fmt, ap); 309 2082 eschrock return (-1); 310 2082 eschrock 311 2082 eschrock case EINTR: 312 2082 eschrock zfs_verror(hdl, EZFS_INTR, fmt, ap); 313 2082 eschrock return (-1); 314 2082 eschrock } 315 2082 eschrock 316 2082 eschrock return (0); 317 2082 eschrock } 318 2082 eschrock 319 3237 lling int 320 3237 lling zfs_standard_error(libzfs_handle_t *hdl, int error, const char *msg) 321 3237 lling { 322 3237 lling return (zfs_standard_error_fmt(hdl, error, "%s", msg)); 323 3237 lling } 324 3237 lling 325 2082 eschrock /*PRINTFLIKE3*/ 326 2082 eschrock int 327 3237 lling zfs_standard_error_fmt(libzfs_handle_t *hdl, int error, const char *fmt, ...) 328 2082 eschrock { 329 2082 eschrock va_list ap; 330 2082 eschrock 331 2082 eschrock va_start(ap, fmt); 332 2082 eschrock 333 2082 eschrock if (zfs_common_error(hdl, error, fmt, ap) != 0) { 334 2082 eschrock va_end(ap); 335 2082 eschrock return (-1); 336 2082 eschrock } 337 2082 eschrock 338 2082 eschrock switch (error) { 339 2082 eschrock case ENXIO: 340 5807 ck153898 case ENODEV: 341 2082 eschrock zfs_verror(hdl, EZFS_IO, fmt, ap); 342 2082 eschrock break; 343 2082 eschrock 344 2082 eschrock case ENOENT: 345 2082 eschrock zfs_error_aux(hdl, dgettext(TEXT_DOMAIN, 346 2082 eschrock "dataset does not exist")); 347 2082 eschrock zfs_verror(hdl, EZFS_NOENT, fmt, ap); 348 2082 eschrock break; 349 2082 eschrock 350 2082 eschrock case ENOSPC: 351 2082 eschrock case EDQUOT: 352 2082 eschrock zfs_verror(hdl, EZFS_NOSPC, fmt, ap); 353 2082 eschrock return (-1); 354 2082 eschrock 355 2082 eschrock case EEXIST: 356 2082 eschrock zfs_error_aux(hdl, dgettext(TEXT_DOMAIN, 357 2082 eschrock "dataset already exists")); 358 2082 eschrock zfs_verror(hdl, EZFS_EXISTS, fmt, ap); 359 2082 eschrock break; 360 2082 eschrock 361 2082 eschrock case EBUSY: 362 2082 eschrock zfs_error_aux(hdl, dgettext(TEXT_DOMAIN, 363 2082 eschrock "dataset is busy")); 364 2082 eschrock zfs_verror(hdl, EZFS_BUSY, fmt, ap); 365 2082 eschrock break; 366 4543 marks case EROFS: 367 4543 marks zfs_error_aux(hdl, dgettext(TEXT_DOMAIN, 368 4543 marks "snapshot permissions cannot be modified")); 369 4543 marks zfs_verror(hdl, EZFS_PERMRDONLY, fmt, ap); 370 4543 marks break; 371 3978 mmusante case ENAMETOOLONG: 372 3978 mmusante zfs_verror(hdl, EZFS_NAMETOOLONG, fmt, ap); 373 5860 ck153898 break; 374 5860 ck153898 case ENOTSUP: 375 5860 ck153898 zfs_verror(hdl, EZFS_BADVERSION, fmt, ap); 376 3978 mmusante break; 377 9234 George case EAGAIN: 378 9234 George zfs_error_aux(hdl, dgettext(TEXT_DOMAIN, 379 9234 George "pool I/O is currently suspended")); 380 9234 George zfs_verror(hdl, EZFS_POOLUNAVAIL, fmt, ap); 381 9234 George break; 382 2082 eschrock default: 383 11022 Tom zfs_error_aux(hdl, strerror(error)); 384 2082 eschrock zfs_verror(hdl, EZFS_UNKNOWN, fmt, ap); 385 2082 eschrock break; 386 789 ahrens } 387 789 ahrens 388 789 ahrens va_end(ap); 389 2082 eschrock return (-1); 390 789 ahrens } 391 789 ahrens 392 3237 lling int 393 3237 lling zpool_standard_error(libzfs_handle_t *hdl, int error, const char *msg) 394 3237 lling { 395 3237 lling return (zpool_standard_error_fmt(hdl, error, "%s", msg)); 396 3237 lling } 397 3237 lling 398 2082 eschrock /*PRINTFLIKE3*/ 399 2082 eschrock int 400 3237 lling zpool_standard_error_fmt(libzfs_handle_t *hdl, int error, const char *fmt, ...) 401 789 ahrens { 402 2082 eschrock va_list ap; 403 2082 eschrock 404 2082 eschrock va_start(ap, fmt); 405 2082 eschrock 406 2082 eschrock if (zfs_common_error(hdl, error, fmt, ap) != 0) { 407 2082 eschrock va_end(ap); 408 2082 eschrock return (-1); 409 2082 eschrock } 410 2082 eschrock 411 2082 eschrock switch (error) { 412 2082 eschrock case ENODEV: 413 2082 eschrock zfs_verror(hdl, EZFS_NODEVICE, fmt, ap); 414 2082 eschrock break; 415 2082 eschrock 416 2082 eschrock case ENOENT: 417 3912 lling zfs_error_aux(hdl, 418 3912 lling dgettext(TEXT_DOMAIN, "no such pool or dataset")); 419 2082 eschrock zfs_verror(hdl, EZFS_NOENT, fmt, ap); 420 2082 eschrock break; 421 2082 eschrock 422 2082 eschrock case EEXIST: 423 2082 eschrock zfs_error_aux(hdl, dgettext(TEXT_DOMAIN, 424 2082 eschrock "pool already exists")); 425 2082 eschrock zfs_verror(hdl, EZFS_EXISTS, fmt, ap); 426 2082 eschrock break; 427 2082 eschrock 428 2082 eschrock case EBUSY: 429 2082 eschrock zfs_error_aux(hdl, dgettext(TEXT_DOMAIN, "pool is busy")); 430 7341 Eric zfs_verror(hdl, EZFS_BUSY, fmt, ap); 431 2082 eschrock break; 432 2082 eschrock 433 2082 eschrock case ENXIO: 434 2082 eschrock zfs_error_aux(hdl, dgettext(TEXT_DOMAIN, 435 2082 eschrock "one or more devices is currently unavailable")); 436 2082 eschrock zfs_verror(hdl, EZFS_BADDEV, fmt, ap); 437 2082 eschrock break; 438 2082 eschrock 439 2082 eschrock case ENAMETOOLONG: 440 2082 eschrock zfs_verror(hdl, EZFS_DEVOVERFLOW, fmt, ap); 441 3912 lling break; 442 3912 lling 443 3912 lling case ENOTSUP: 444 3912 lling zfs_verror(hdl, EZFS_POOL_NOTSUP, fmt, ap); 445 3912 lling break; 446 3912 lling 447 3912 lling case EINVAL: 448 3912 lling zfs_verror(hdl, EZFS_POOL_INVALARG, fmt, ap); 449 2082 eschrock break; 450 4543 marks 451 4543 marks case ENOSPC: 452 4543 marks case EDQUOT: 453 4543 marks zfs_verror(hdl, EZFS_NOSPC, fmt, ap); 454 4543 marks return (-1); 455 9234 George case EAGAIN: 456 9234 George zfs_error_aux(hdl, dgettext(TEXT_DOMAIN, 457 9234 George "pool I/O is currently suspended")); 458 9234 George zfs_verror(hdl, EZFS_POOLUNAVAIL, fmt, ap); 459 9234 George break; 460 2082 eschrock 461 2082 eschrock default: 462 2082 eschrock zfs_error_aux(hdl, strerror(error)); 463 2082 eschrock zfs_verror(hdl, EZFS_UNKNOWN, fmt, ap); 464 2082 eschrock } 465 2082 eschrock 466 2082 eschrock va_end(ap); 467 2082 eschrock return (-1); 468 789 ahrens } 469 789 ahrens 470 789 ahrens /* 471 789 ahrens * Display an out of memory error message and abort the current program. 472 789 ahrens */ 473 2082 eschrock int 474 2082 eschrock no_memory(libzfs_handle_t *hdl) 475 789 ahrens { 476 2082 eschrock return (zfs_error(hdl, EZFS_NOMEM, "internal error")); 477 789 ahrens } 478 789 ahrens 479 789 ahrens /* 480 789 ahrens * A safe form of malloc() which will die if the allocation fails. 481 789 ahrens */ 482 789 ahrens void * 483 2082 eschrock zfs_alloc(libzfs_handle_t *hdl, size_t size) 484 789 ahrens { 485 789 ahrens void *data; 486 789 ahrens 487 789 ahrens if ((data = calloc(1, size)) == NULL) 488 2082 eschrock (void) no_memory(hdl); 489 789 ahrens 490 789 ahrens return (data); 491 789 ahrens } 492 789 ahrens 493 789 ahrens /* 494 2676 eschrock * A safe form of realloc(), which also zeroes newly allocated space. 495 2676 eschrock */ 496 2676 eschrock void * 497 2676 eschrock zfs_realloc(libzfs_handle_t *hdl, void *ptr, size_t oldsize, size_t newsize) 498 2676 eschrock { 499 2676 eschrock void *ret; 500 2676 eschrock 501 2676 eschrock if ((ret = realloc(ptr, newsize)) == NULL) { 502 2676 eschrock (void) no_memory(hdl); 503 2676 eschrock return (NULL); 504 2676 eschrock } 505 2676 eschrock 506 2676 eschrock bzero((char *)ret + oldsize, (newsize - oldsize)); 507 2676 eschrock return (ret); 508 2676 eschrock } 509 2676 eschrock 510 2676 eschrock /* 511 789 ahrens * A safe form of strdup() which will die if the allocation fails. 512 789 ahrens */ 513 789 ahrens char * 514 2082 eschrock zfs_strdup(libzfs_handle_t *hdl, const char *str) 515 789 ahrens { 516 789 ahrens char *ret; 517 789 ahrens 518 789 ahrens if ((ret = strdup(str)) == NULL) 519 2082 eschrock (void) no_memory(hdl); 520 789 ahrens 521 789 ahrens return (ret); 522 789 ahrens } 523 789 ahrens 524 789 ahrens /* 525 789 ahrens * Convert a number to an appropriately human-readable output. 526 789 ahrens */ 527 789 ahrens void 528 789 ahrens zfs_nicenum(uint64_t num, char *buf, size_t buflen) 529 789 ahrens { 530 789 ahrens uint64_t n = num; 531 789 ahrens int index = 0; 532 789 ahrens char u; 533 789 ahrens 534 789 ahrens while (n >= 1024) { 535 1162 eschrock n /= 1024; 536 789 ahrens index++; 537 789 ahrens } 538 789 ahrens 539 789 ahrens u = " KMGTPE"[index]; 540 789 ahrens 541 1162 eschrock if (index == 0) { 542 789 ahrens (void) snprintf(buf, buflen, "%llu", n); 543 1162 eschrock } else if ((num & ((1ULL << 10 * index) - 1)) == 0) { 544 1162 eschrock /* 545 1162 eschrock * If this is an even multiple of the base, always display 546 1162 eschrock * without any decimal precision. 547 1162 eschrock */ 548 789 ahrens (void) snprintf(buf, buflen, "%llu%c", n, u); 549 1162 eschrock } else { 550 1162 eschrock /* 551 1162 eschrock * We want to choose a precision that reflects the best choice 552 1162 eschrock * for fitting in 5 characters. This can get rather tricky when 553 1162 eschrock * we have numbers that are very close to an order of magnitude. 554 1162 eschrock * For example, when displaying 10239 (which is really 9.999K), 555 1162 eschrock * we want only a single place of precision for 10.0K. We could 556 1162 eschrock * develop some complex heuristics for this, but it's much 557 1162 eschrock * easier just to try each combination in turn. 558 1162 eschrock */ 559 1162 eschrock int i; 560 1162 eschrock for (i = 2; i >= 0; i--) { 561 4451 eschrock if (snprintf(buf, buflen, "%.*f%c", i, 562 4451 eschrock (double)num / (1ULL << 10 * index), u) <= 5) 563 1162 eschrock break; 564 1162 eschrock } 565 1162 eschrock } 566 789 ahrens } 567 2082 eschrock 568 2082 eschrock void 569 2082 eschrock libzfs_print_on_error(libzfs_handle_t *hdl, boolean_t printerr) 570 2082 eschrock { 571 2082 eschrock hdl->libzfs_printerr = printerr; 572 2082 eschrock } 573 2082 eschrock 574 2082 eschrock libzfs_handle_t * 575 2082 eschrock libzfs_init(void) 576 2082 eschrock { 577 2082 eschrock libzfs_handle_t *hdl; 578 2082 eschrock 579 2082 eschrock if ((hdl = calloc(sizeof (libzfs_handle_t), 1)) == NULL) { 580 2082 eschrock return (NULL); 581 2082 eschrock } 582 2082 eschrock 583 2500 eschrock if ((hdl->libzfs_fd = open(ZFS_DEV, O_RDWR)) < 0) { 584 2082 eschrock free(hdl); 585 2082 eschrock return (NULL); 586 2082 eschrock } 587 2082 eschrock 588 2082 eschrock if ((hdl->libzfs_mnttab = fopen(MNTTAB, "r")) == NULL) { 589 2082 eschrock (void) close(hdl->libzfs_fd); 590 2082 eschrock free(hdl); 591 2082 eschrock return (NULL); 592 2082 eschrock } 593 2082 eschrock 594 2082 eschrock hdl->libzfs_sharetab = fopen("/etc/dfs/sharetab", "r"); 595 4787 ahrens 596 4787 ahrens zfs_prop_init(); 597 5094 lling zpool_prop_init(); 598 8811 Eric libzfs_mnttab_init(hdl); 599 2082 eschrock 600 2082 eschrock return (hdl); 601 2082 eschrock } 602 2082 eschrock 603 2082 eschrock void 604 2082 eschrock libzfs_fini(libzfs_handle_t *hdl) 605 2082 eschrock { 606 2082 eschrock (void) close(hdl->libzfs_fd); 607 2082 eschrock if (hdl->libzfs_mnttab) 608 2082 eschrock (void) fclose(hdl->libzfs_mnttab); 609 2082 eschrock if (hdl->libzfs_sharetab) 610 2082 eschrock (void) fclose(hdl->libzfs_sharetab); 611 4180 dougm zfs_uninit_libshare(hdl); 612 4543 marks if (hdl->libzfs_log_str) 613 4543 marks (void) free(hdl->libzfs_log_str); 614 6865 rm160521 zpool_free_handles(hdl); 615 10817 Eric libzfs_fru_clear(hdl, B_TRUE); 616 2082 eschrock namespace_clear(hdl); 617 8811 Eric libzfs_mnttab_fini(hdl); 618 2082 eschrock free(hdl); 619 2082 eschrock } 620 2082 eschrock 621 2082 eschrock libzfs_handle_t * 622 2082 eschrock zpool_get_handle(zpool_handle_t *zhp) 623 2082 eschrock { 624 2082 eschrock return (zhp->zpool_hdl); 625 2082 eschrock } 626 2082 eschrock 627 2082 eschrock libzfs_handle_t * 628 2082 eschrock zfs_get_handle(zfs_handle_t *zhp) 629 2082 eschrock { 630 2082 eschrock return (zhp->zfs_hdl); 631 7538 Richard } 632 7538 Richard 633 7538 Richard zpool_handle_t * 634 7538 Richard zfs_get_pool_handle(const zfs_handle_t *zhp) 635 7538 Richard { 636 7538 Richard return (zhp->zpool_hdl); 637 2082 eschrock } 638 2676 eschrock 639 2676 eschrock /* 640 3635 ck153898 * Given a name, determine whether or not it's a valid path 641 3635 ck153898 * (starts with '/' or "./"). If so, walk the mnttab trying 642 3635 ck153898 * to match the device number. If not, treat the path as an 643 3635 ck153898 * fs/vol/snap name. 644 3635 ck153898 */ 645 3635 ck153898 zfs_handle_t * 646 3635 ck153898 zfs_path_to_zhandle(libzfs_handle_t *hdl, char *path, zfs_type_t argtype) 647 3635 ck153898 { 648 3635 ck153898 struct stat64 statbuf; 649 3635 ck153898 struct extmnttab entry; 650 3635 ck153898 int ret; 651 3635 ck153898 652 3635 ck153898 if (path[0] != '/' && strncmp(path, "./", strlen("./")) != 0) { 653 3635 ck153898 /* 654 3635 ck153898 * It's not a valid path, assume it's a name of type 'argtype'. 655 3635 ck153898 */ 656 3635 ck153898 return (zfs_open(hdl, path, argtype)); 657 3635 ck153898 } 658 3635 ck153898 659 3635 ck153898 if (stat64(path, &statbuf) != 0) { 660 3635 ck153898 (void) fprintf(stderr, "%s: %s\n", path, strerror(errno)); 661 3635 ck153898 return (NULL); 662 3635 ck153898 } 663 3635 ck153898 664 3635 ck153898 rewind(hdl->libzfs_mnttab); 665 3635 ck153898 while ((ret = getextmntent(hdl->libzfs_mnttab, &entry, 0)) == 0) { 666 3635 ck153898 if (makedevice(entry.mnt_major, entry.mnt_minor) == 667 3635 ck153898 statbuf.st_dev) { 668 3635 ck153898 break; 669 3635 ck153898 } 670 3635 ck153898 } 671 3635 ck153898 if (ret != 0) { 672 3635 ck153898 return (NULL); 673 3635 ck153898 } 674 3635 ck153898 675 3635 ck153898 if (strcmp(entry.mnt_fstype, MNTTYPE_ZFS) != 0) { 676 3635 ck153898 (void) fprintf(stderr, gettext("'%s': not a ZFS filesystem\n"), 677 3635 ck153898 path); 678 3635 ck153898 return (NULL); 679 3635 ck153898 } 680 3635 ck153898 681 3635 ck153898 return (zfs_open(hdl, entry.mnt_special, ZFS_TYPE_FILESYSTEM)); 682 3635 ck153898 } 683 3635 ck153898 684 3635 ck153898 /* 685 2676 eschrock * Initialize the zc_nvlist_dst member to prepare for receiving an nvlist from 686 2676 eschrock * an ioctl(). 687 2676 eschrock */ 688 2676 eschrock int 689 2676 eschrock zcmd_alloc_dst_nvlist(libzfs_handle_t *hdl, zfs_cmd_t *zc, size_t len) 690 2676 eschrock { 691 2676 eschrock if (len == 0) 692 10407 Matthew len = 4*1024; 693 2676 eschrock zc->zc_nvlist_dst_size = len; 694 2676 eschrock if ((zc->zc_nvlist_dst = (uint64_t)(uintptr_t) 695 2676 eschrock zfs_alloc(hdl, zc->zc_nvlist_dst_size)) == NULL) 696 2676 eschrock return (-1); 697 2676 eschrock 698 2676 eschrock return (0); 699 2676 eschrock } 700 2676 eschrock 701 2676 eschrock /* 702 2676 eschrock * Called when an ioctl() which returns an nvlist fails with ENOMEM. This will 703 2676 eschrock * expand the nvlist to the size specified in 'zc_nvlist_dst_size', which was 704 2676 eschrock * filled in by the kernel to indicate the actual required size. 705 2676 eschrock */ 706 2676 eschrock int 707 2676 eschrock zcmd_expand_dst_nvlist(libzfs_handle_t *hdl, zfs_cmd_t *zc) 708 2676 eschrock { 709 2676 eschrock free((void *)(uintptr_t)zc->zc_nvlist_dst); 710 2676 eschrock if ((zc->zc_nvlist_dst = (uint64_t)(uintptr_t) 711 2676 eschrock zfs_alloc(hdl, zc->zc_nvlist_dst_size)) 712 2676 eschrock == NULL) 713 2676 eschrock return (-1); 714 2676 eschrock 715 2676 eschrock return (0); 716 2676 eschrock } 717 2676 eschrock 718 2676 eschrock /* 719 2885 ahrens * Called to free the src and dst nvlists stored in the command structure. 720 2676 eschrock */ 721 2676 eschrock void 722 2676 eschrock zcmd_free_nvlists(zfs_cmd_t *zc) 723 2676 eschrock { 724 5094 lling free((void *)(uintptr_t)zc->zc_nvlist_conf); 725 2676 eschrock free((void *)(uintptr_t)zc->zc_nvlist_src); 726 2676 eschrock free((void *)(uintptr_t)zc->zc_nvlist_dst); 727 2676 eschrock } 728 2676 eschrock 729 5094 lling static int 730 5094 lling zcmd_write_nvlist_com(libzfs_handle_t *hdl, uint64_t *outnv, uint64_t *outlen, 731 5094 lling nvlist_t *nvl) 732 2676 eschrock { 733 2676 eschrock char *packed; 734 2676 eschrock size_t len; 735 2676 eschrock 736 2676 eschrock verify(nvlist_size(nvl, &len, NV_ENCODE_NATIVE) == 0); 737 2676 eschrock 738 2676 eschrock if ((packed = zfs_alloc(hdl, len)) == NULL) 739 2676 eschrock return (-1); 740 2676 eschrock 741 2676 eschrock verify(nvlist_pack(nvl, &packed, &len, NV_ENCODE_NATIVE, 0) == 0); 742 2676 eschrock 743 5094 lling *outnv = (uint64_t)(uintptr_t)packed; 744 5094 lling *outlen = len; 745 2676 eschrock 746 2676 eschrock return (0); 747 5094 lling } 748 5094 lling 749 5094 lling int 750 5094 lling zcmd_write_conf_nvlist(libzfs_handle_t *hdl, zfs_cmd_t *zc, nvlist_t *nvl) 751 5094 lling { 752 5094 lling return (zcmd_write_nvlist_com(hdl, &zc->zc_nvlist_conf, 753 5094 lling &zc->zc_nvlist_conf_size, nvl)); 754 5094 lling } 755 5094 lling 756 5094 lling int 757 5094 lling zcmd_write_src_nvlist(libzfs_handle_t *hdl, zfs_cmd_t *zc, nvlist_t *nvl) 758 5094 lling { 759 5094 lling return (zcmd_write_nvlist_com(hdl, &zc->zc_nvlist_src, 760 5094 lling &zc->zc_nvlist_src_size, nvl)); 761 2676 eschrock } 762 2676 eschrock 763 2676 eschrock /* 764 2676 eschrock * Unpacks an nvlist from the ZFS ioctl command structure. 765 2676 eschrock */ 766 2676 eschrock int 767 2676 eschrock zcmd_read_dst_nvlist(libzfs_handle_t *hdl, zfs_cmd_t *zc, nvlist_t **nvlp) 768 2676 eschrock { 769 2676 eschrock if (nvlist_unpack((void *)(uintptr_t)zc->zc_nvlist_dst, 770 2676 eschrock zc->zc_nvlist_dst_size, nvlp, 0) != 0) 771 2676 eschrock return (no_memory(hdl)); 772 2676 eschrock 773 2676 eschrock return (0); 774 2676 eschrock } 775 3912 lling 776 5094 lling int 777 5094 lling zfs_ioctl(libzfs_handle_t *hdl, int request, zfs_cmd_t *zc) 778 5094 lling { 779 5094 lling int error; 780 5094 lling 781 5094 lling zc->zc_history = (uint64_t)(uintptr_t)hdl->libzfs_log_str; 782 5094 lling error = ioctl(hdl->libzfs_fd, request, zc); 783 5094 lling if (hdl->libzfs_log_str) { 784 5094 lling free(hdl->libzfs_log_str); 785 5094 lling hdl->libzfs_log_str = NULL; 786 5094 lling } 787 5094 lling zc->zc_history = 0; 788 5094 lling 789 5094 lling return (error); 790 5094 lling } 791 5094 lling 792 5094 lling /* 793 5094 lling * ================================================================ 794 5094 lling * API shared by zfs and zpool property management 795 5094 lling * ================================================================ 796 5094 lling */ 797 5094 lling 798 3912 lling static void 799 5094 lling zprop_print_headers(zprop_get_cbdata_t *cbp, zfs_type_t type) 800 3912 lling { 801 5094 lling zprop_list_t *pl = cbp->cb_proplist; 802 3912 lling int i; 803 3912 lling char *title; 804 3912 lling size_t len; 805 3912 lling 806 3912 lling cbp->cb_first = B_FALSE; 807 3912 lling if (cbp->cb_scripted) 808 3912 lling return; 809 3912 lling 810 3912 lling /* 811 3912 lling * Start with the length of the column headers. 812 3912 lling */ 813 3912 lling cbp->cb_colwidths[GET_COL_NAME] = strlen(dgettext(TEXT_DOMAIN, "NAME")); 814 3912 lling cbp->cb_colwidths[GET_COL_PROPERTY] = strlen(dgettext(TEXT_DOMAIN, 815 3912 lling "PROPERTY")); 816 3912 lling cbp->cb_colwidths[GET_COL_VALUE] = strlen(dgettext(TEXT_DOMAIN, 817 3912 lling "VALUE")); 818 11022 Tom cbp->cb_colwidths[GET_COL_RECVD] = strlen(dgettext(TEXT_DOMAIN, 819 11022 Tom "RECEIVED")); 820 3912 lling cbp->cb_colwidths[GET_COL_SOURCE] = strlen(dgettext(TEXT_DOMAIN, 821 3912 lling "SOURCE")); 822 3912 lling 823 8269 Mark /* first property is always NAME */ 824 8269 Mark assert(cbp->cb_proplist->pl_prop == 825 8269 Mark ((type == ZFS_TYPE_POOL) ? ZPOOL_PROP_NAME : ZFS_PROP_NAME)); 826 8269 Mark 827 3912 lling /* 828 3912 lling * Go through and calculate the widths for each column. For the 829 3912 lling * 'source' column, we kludge it up by taking the worst-case scenario of 830 3912 lling * inheriting from the longest name. This is acceptable because in the 831 3912 lling * majority of cases 'SOURCE' is the last column displayed, and we don't 832 3912 lling * use the width anyway. Note that the 'VALUE' column can be oversized, 833 11022 Tom * if the name of the property is much longer than any values we find. 834 3912 lling */ 835 3912 lling for (pl = cbp->cb_proplist; pl != NULL; pl = pl->pl_next) { 836 3912 lling /* 837 3912 lling * 'PROPERTY' column 838 3912 lling */ 839 5094 lling if (pl->pl_prop != ZPROP_INVAL) { 840 5094 lling const char *propname = (type == ZFS_TYPE_POOL) ? 841 5094 lling zpool_prop_to_name(pl->pl_prop) : 842 5094 lling zfs_prop_to_name(pl->pl_prop); 843 5094 lling 844 5094 lling len = strlen(propname); 845 3912 lling if (len > cbp->cb_colwidths[GET_COL_PROPERTY]) 846 3912 lling cbp->cb_colwidths[GET_COL_PROPERTY] = len; 847 3912 lling } else { 848 3912 lling len = strlen(pl->pl_user_prop); 849 3912 lling if (len > cbp->cb_colwidths[GET_COL_PROPERTY]) 850 3912 lling cbp->cb_colwidths[GET_COL_PROPERTY] = len; 851 3912 lling } 852 3912 lling 853 3912 lling /* 854 8269 Mark * 'VALUE' column. The first property is always the 'name' 855 8269 Mark * property that was tacked on either by /sbin/zfs's 856 8269 Mark * zfs_do_get() or when calling zprop_expand_list(), so we 857 8269 Mark * ignore its width. If the user specified the name property 858 8269 Mark * to display, then it will be later in the list in any case. 859 3912 lling */ 860 8269 Mark if (pl != cbp->cb_proplist && 861 3912 lling pl->pl_width > cbp->cb_colwidths[GET_COL_VALUE]) 862 3912 lling cbp->cb_colwidths[GET_COL_VALUE] = pl->pl_width; 863 3912 lling 864 11022 Tom /* 'RECEIVED' column. */ 865 11022 Tom if (pl != cbp->cb_proplist && 866 11022 Tom pl->pl_recvd_width > cbp->cb_colwidths[GET_COL_RECVD]) 867 11022 Tom cbp->cb_colwidths[GET_COL_RECVD] = pl->pl_recvd_width; 868 11022 Tom 869 3912 lling /* 870 3912 lling * 'NAME' and 'SOURCE' columns 871 3912 lling */ 872 5094 lling if (pl->pl_prop == (type == ZFS_TYPE_POOL ? ZPOOL_PROP_NAME : 873 5094 lling ZFS_PROP_NAME) && 874 3912 lling pl->pl_width > cbp->cb_colwidths[GET_COL_NAME]) { 875 3912 lling cbp->cb_colwidths[GET_COL_NAME] = pl->pl_width; 876 3912 lling cbp->cb_colwidths[GET_COL_SOURCE] = pl->pl_width + 877 3912 lling strlen(dgettext(TEXT_DOMAIN, "inherited from")); 878 3912 lling } 879 3912 lling } 880 3912 lling 881 3912 lling /* 882 3912 lling * Now go through and print the headers. 883 3912 lling */ 884 11022 Tom for (i = 0; i < ZFS_GET_NCOLS; i++) { 885 3912 lling switch (cbp->cb_columns[i]) { 886 3912 lling case GET_COL_NAME: 887 3912 lling title = dgettext(TEXT_DOMAIN, "NAME"); 888 3912 lling break; 889 3912 lling case GET_COL_PROPERTY: 890 3912 lling title = dgettext(TEXT_DOMAIN, "PROPERTY"); 891 3912 lling break; 892 3912 lling case GET_COL_VALUE: 893 3912 lling title = dgettext(TEXT_DOMAIN, "VALUE"); 894 3912 lling break; 895 11022 Tom case GET_COL_RECVD: 896 11022 Tom title = dgettext(TEXT_DOMAIN, "RECEIVED"); 897 11022 Tom break; 898 3912 lling case GET_COL_SOURCE: 899 3912 lling title = dgettext(TEXT_DOMAIN, "SOURCE"); 900 3912 lling break; 901 3912 lling default: 902 3912 lling title = NULL; 903 3912 lling } 904 3912 lling 905 3912 lling if (title != NULL) { 906 11022 Tom if (i == (ZFS_GET_NCOLS - 1) || 907 11022 Tom cbp->cb_columns[i + 1] == GET_COL_NONE) 908 3912 lling (void) printf("%s", title); 909 3912 lling else 910 3912 lling (void) printf("%-*s ", 911 3912 lling cbp->cb_colwidths[cbp->cb_columns[i]], 912 3912 lling title); 913 3912 lling } 914 3912 lling } 915 3912 lling (void) printf("\n"); 916 3912 lling } 917 3912 lling 918 3912 lling /* 919 3912 lling * Display a single line of output, according to the settings in the callback 920 3912 lling * structure. 921 3912 lling */ 922 3912 lling void 923 5094 lling zprop_print_one_property(const char *name, zprop_get_cbdata_t *cbp, 924 5094 lling const char *propname, const char *value, zprop_source_t sourcetype, 925 11022 Tom const char *source, const char *recvd_value) 926 3912 lling { 927 3912 lling int i; 928 3912 lling const char *str; 929 3912 lling char buf[128]; 930 3912 lling 931 3912 lling /* 932 3912 lling * Ignore those source types that the user has chosen to ignore. 933 3912 lling */ 934 3912 lling if ((sourcetype & cbp->cb_sources) == 0) 935 3912 lling return; 936 3912 lling 937 3912 lling if (cbp->cb_first) 938 5094 lling zprop_print_headers(cbp, cbp->cb_type); 939 3912 lling 940 11022 Tom for (i = 0; i < ZFS_GET_NCOLS; i++) { 941 3912 lling switch (cbp->cb_columns[i]) { 942 3912 lling case GET_COL_NAME: 943 3912 lling str = name; 944 3912 lling break; 945 3912 lling 946 3912 lling case GET_COL_PROPERTY: 947 3912 lling str = propname; 948 3912 lling break; 949 3912 lling 950 3912 lling case GET_COL_VALUE: 951 3912 lling str = value; 952 3912 lling break; 953 3912 lling 954 3912 lling case GET_COL_SOURCE: 955 3912 lling switch (sourcetype) { 956 5094 lling case ZPROP_SRC_NONE: 957 3912 lling str = "-"; 958 3912 lling break; 959 3912 lling 960 5094 lling case ZPROP_SRC_DEFAULT: 961 3912 lling str = "default"; 962 3912 lling break; 963 3912 lling 964 5094 lling case ZPROP_SRC_LOCAL: 965 3912 lling str = "local"; 966 3912 lling break; 967 3912 lling 968 5094 lling case ZPROP_SRC_TEMPORARY: 969 3912 lling str = "temporary"; 970 3912 lling break; 971 3912 lling 972 5094 lling case ZPROP_SRC_INHERITED: 973 3912 lling (void) snprintf(buf, sizeof (buf), 974 3912 lling "inherited from %s", source); 975 3912 lling str = buf; 976 3912 lling break; 977 11022 Tom case ZPROP_SRC_RECEIVED: 978 11022 Tom str = "received"; 979 11022 Tom break; 980 3912 lling } 981 11022 Tom break; 982 11022 Tom 983 11022 Tom case GET_COL_RECVD: 984 11022 Tom str = (recvd_value == NULL ? "-" : recvd_value); 985 3912 lling break; 986 3912 lling 987 3912 lling default: 988 3912 lling continue; 989 3912 lling } 990 3912 lling 991 11022 Tom if (cbp->cb_columns[i + 1] == GET_COL_NONE) 992 3912 lling (void) printf("%s", str); 993 3912 lling else if (cbp->cb_scripted) 994 3912 lling (void) printf("%s\t", str); 995 3912 lling else 996 3912 lling (void) printf("%-*s ", 997 3912 lling cbp->cb_colwidths[cbp->cb_columns[i]], 998 3912 lling str); 999 3912 lling } 1000 3912 lling 1001 3912 lling (void) printf("\n"); 1002 3912 lling } 1003 4543 marks 1004 5094 lling /* 1005 5094 lling * Given a numeric suffix, convert the value into a number of bits that the 1006 5094 lling * resulting value must be shifted. 1007 5094 lling */ 1008 5094 lling static int 1009 5094 lling str2shift(libzfs_handle_t *hdl, const char *buf) 1010 5094 lling { 1011 5094 lling const char *ends = "BKMGTPEZ"; 1012 5094 lling int i; 1013 5094 lling 1014 5094 lling if (buf[0] == '\0') 1015 5094 lling return (0); 1016 5094 lling for (i = 0; i < strlen(ends); i++) { 1017 5094 lling if (toupper(buf[0]) == ends[i]) 1018 5094 lling break; 1019 5094 lling } 1020 5094 lling if (i == strlen(ends)) { 1021 5094 lling zfs_error_aux(hdl, dgettext(TEXT_DOMAIN, 1022 5094 lling "invalid numeric suffix '%s'"), buf); 1023 5094 lling return (-1); 1024 5094 lling } 1025 5094 lling 1026 5094 lling /* 1027 5094 lling * We want to allow trailing 'b' characters for 'GB' or 'Mb'. But don't 1028 5094 lling * allow 'BB' - that's just weird. 1029 5094 lling */ 1030 5094 lling if (buf[1] == '\0' || (toupper(buf[1]) == 'B' && buf[2] == '\0' && 1031 5094 lling toupper(buf[0]) != 'B')) 1032 5094 lling return (10*i); 1033 5094 lling 1034 5094 lling zfs_error_aux(hdl, dgettext(TEXT_DOMAIN, 1035 5094 lling "invalid numeric suffix '%s'"), buf); 1036 5094 lling return (-1); 1037 5094 lling } 1038 5094 lling 1039 5094 lling /* 1040 5094 lling * Convert a string of the form '100G' into a real number. Used when setting 1041 5094 lling * properties or creating a volume. 'buf' is used to place an extended error 1042 5094 lling * message for the caller to use. 1043 5094 lling */ 1044 4543 marks int 1045 5094 lling zfs_nicestrtonum(libzfs_handle_t *hdl, const char *value, uint64_t *num) 1046 4543 marks { 1047 5094 lling char *end; 1048 5094 lling int shift; 1049 4543 marks 1050 5094 lling *num = 0; 1051 5094 lling 1052 5094 lling /* Check to see if this looks like a number. */ 1053 5094 lling if ((value[0] < '0' || value[0] > '9') && value[0] != '.') { 1054 5094 lling if (hdl) 1055 5094 lling zfs_error_aux(hdl, dgettext(TEXT_DOMAIN, 1056 5094 lling "bad numeric value '%s'"), value); 1057 5094 lling return (-1); 1058 4543 marks } 1059 4543 marks 1060 10817 Eric /* Rely on strtoull() to process the numeric portion. */ 1061 5094 lling errno = 0; 1062 8343 Eric *num = strtoull(value, &end, 10); 1063 5094 lling 1064 5094 lling /* 1065 5094 lling * Check for ERANGE, which indicates that the value is too large to fit 1066 5094 lling * in a 64-bit value. 1067 5094 lling */ 1068 5094 lling if (errno == ERANGE) { 1069 5094 lling if (hdl) 1070 5094 lling zfs_error_aux(hdl, dgettext(TEXT_DOMAIN, 1071 5094 lling "numeric value is too large")); 1072 5094 lling return (-1); 1073 5094 lling } 1074 5094 lling 1075 5094 lling /* 1076 5094 lling * If we have a decimal value, then do the computation with floating 1077 5094 lling * point arithmetic. Otherwise, use standard arithmetic. 1078 5094 lling */ 1079 5094 lling if (*end == '.') { 1080 5094 lling double fval = strtod(value, &end); 1081 5094 lling 1082 5094 lling if ((shift = str2shift(hdl, end)) == -1) 1083 5094 lling return (-1); 1084 5094 lling 1085 5094 lling fval *= pow(2, shift); 1086 5094 lling 1087 5094 lling if (fval > UINT64_MAX) { 1088 5094 lling if (hdl) 1089 5094 lling zfs_error_aux(hdl, dgettext(TEXT_DOMAIN, 1090 5094 lling "numeric value is too large")); 1091 5094 lling return (-1); 1092 5094 lling } 1093 5094 lling 1094 5094 lling *num = (uint64_t)fval; 1095 5094 lling } else { 1096 5094 lling if ((shift = str2shift(hdl, end)) == -1) 1097 5094 lling return (-1); 1098 5094 lling 1099 5094 lling /* Check for overflow */ 1100 5094 lling if (shift >= 64 || (*num << shift) >> shift != *num) { 1101 5094 lling if (hdl) 1102 5094 lling zfs_error_aux(hdl, dgettext(TEXT_DOMAIN, 1103 5094 lling "numeric value is too large")); 1104 5094 lling return (-1); 1105 5094 lling } 1106 5094 lling 1107 5094 lling *num <<= shift; 1108 5094 lling } 1109 5094 lling 1110 5094 lling return (0); 1111 4543 marks } 1112 5094 lling 1113 5094 lling /* 1114 5094 lling * Given a propname=value nvpair to set, parse any numeric properties 1115 5094 lling * (index, boolean, etc) if they are specified as strings and add the 1116 5094 lling * resulting nvpair to the returned nvlist. 1117 5094 lling * 1118 5094 lling * At the DSL layer, all properties are either 64-bit numbers or strings. 1119 5094 lling * We want the user to be able to ignore this fact and specify properties 1120 5094 lling * as native values (numbers, for example) or as strings (to simplify 1121 5094 lling * command line utilities). This also handles converting index types 1122 5094 lling * (compression, checksum, etc) from strings to their on-disk index. 1123 5094 lling */ 1124 5094 lling int 1125 5094 lling zprop_parse_value(libzfs_handle_t *hdl, nvpair_t *elem, int prop, 1126 5094 lling zfs_type_t type, nvlist_t *ret, char **svalp, uint64_t *ivalp, 1127 5094 lling const char *errbuf) 1128 5094 lling { 1129 5094 lling data_type_t datatype = nvpair_type(elem); 1130 5094 lling zprop_type_t proptype; 1131 5094 lling const char *propname; 1132 5094 lling char *value; 1133 5094 lling boolean_t isnone = B_FALSE; 1134 5094 lling 1135 5094 lling if (type == ZFS_TYPE_POOL) { 1136 5094 lling proptype = zpool_prop_get_type(prop); 1137 5094 lling propname = zpool_prop_to_name(prop); 1138 5094 lling } else { 1139 5094 lling proptype = zfs_prop_get_type(prop); 1140 5094 lling propname = zfs_prop_to_name(prop); 1141 5094 lling } 1142 5094 lling 1143 5094 lling /* 1144 5094 lling * Convert any properties to the internal DSL value types. 1145 5094 lling */ 1146 5094 lling *svalp = NULL; 1147 5094 lling *ivalp = 0; 1148 5094 lling 1149 5094 lling switch (proptype) { 1150 5094 lling case PROP_TYPE_STRING: 1151 5094 lling if (datatype != DATA_TYPE_STRING) { 1152 5094 lling zfs_error_aux(hdl, dgettext(TEXT_DOMAIN, 1153 5094 lling "'%s' must be a string"), nvpair_name(elem)); 1154 5094 lling goto error; 1155 5094 lling } 1156 5094 lling (void) nvpair_value_string(elem, svalp); 1157 5094 lling if (strlen(*svalp) >= ZFS_MAXPROPLEN) { 1158 5094 lling zfs_error_aux(hdl, dgettext(TEXT_DOMAIN, 1159 5094 lling "'%s' is too long"), nvpair_name(elem)); 1160 5094 lling goto error; 1161 5094 lling } 1162 5094 lling break; 1163 5094 lling 1164 5094 lling case PROP_TYPE_NUMBER: 1165 5094 lling if (datatype == DATA_TYPE_STRING) { 1166 5094 lling (void) nvpair_value_string(elem, &value); 1167 5094 lling if (strcmp(value, "none") == 0) { 1168 5094 lling isnone = B_TRUE; 1169 5094 lling } else if (zfs_nicestrtonum(hdl, value, ivalp) 1170 5094 lling != 0) { 1171 5094 lling goto error; 1172 5094 lling } 1173 5094 lling } else if (datatype == DATA_TYPE_UINT64) { 1174 5094 lling (void) nvpair_value_uint64(elem, ivalp); 1175 5094 lling } else { 1176 5094 lling zfs_error_aux(hdl, dgettext(TEXT_DOMAIN, 1177 5094 lling "'%s' must be a number"), nvpair_name(elem)); 1178 5094 lling goto error; 1179 5094 lling } 1180 5094 lling 1181 5094 lling /* 1182 5094 lling * Quota special: force 'none' and don't allow 0. 1183 5094 lling */ 1184 5378 ck153898 if ((type & ZFS_TYPE_DATASET) && *ivalp == 0 && !isnone && 1185 5378 ck153898 (prop == ZFS_PROP_QUOTA || prop == ZFS_PROP_REFQUOTA)) { 1186 5094 lling zfs_error_aux(hdl, dgettext(TEXT_DOMAIN, 1187 5378 ck153898 "use 'none' to disable quota/refquota")); 1188 5094 lling goto error; 1189 5094 lling } 1190 5094 lling break; 1191 5094 lling 1192 5094 lling case PROP_TYPE_INDEX: 1193 5378 ck153898 if (datatype != DATA_TYPE_STRING) { 1194 5094 lling zfs_error_aux(hdl, dgettext(TEXT_DOMAIN, 1195 5094 lling "'%s' must be a string"), nvpair_name(elem)); 1196 5094 lling goto error; 1197 5094 lling } 1198 5378 ck153898 1199 5378 ck153898 (void) nvpair_value_string(elem, &value); 1200 5094 lling 1201 5094 lling if (zprop_string_to_index(prop, value, ivalp, type) != 0) { 1202 5094 lling zfs_error_aux(hdl, dgettext(TEXT_DOMAIN, 1203 5094 lling "'%s' must be one of '%s'"), propname, 1204 5094 lling zprop_values(prop, type)); 1205 5094 lling goto error; 1206 5094 lling } 1207 5094 lling break; 1208 5094 lling 1209 5094 lling default: 1210 5094 lling abort(); 1211 5094 lling } 1212 5094 lling 1213 5094 lling /* 1214 5094 lling * Add the result to our return set of properties. 1215 5094 lling */ 1216 5094 lling if (*svalp != NULL) { 1217 5094 lling if (nvlist_add_string(ret, propname, *svalp) != 0) { 1218 5094 lling (void) no_memory(hdl); 1219 5094 lling return (-1); 1220 5094 lling } 1221 5094 lling } else { 1222 5094 lling if (nvlist_add_uint64(ret, propname, *ivalp) != 0) { 1223 5094 lling (void) no_memory(hdl); 1224 5094 lling return (-1); 1225 5094 lling } 1226 5094 lling } 1227 5094 lling 1228 5094 lling return (0); 1229 5094 lling error: 1230 5094 lling (void) zfs_error(hdl, EZFS_BADPROP, errbuf); 1231 5094 lling return (-1); 1232 5094 lling } 1233 5094 lling 1234 7390 Matthew static int 1235 7390 Matthew addlist(libzfs_handle_t *hdl, char *propname, zprop_list_t **listp, 1236 7390 Matthew zfs_type_t type) 1237 7390 Matthew { 1238 7390 Matthew int prop; 1239 7390 Matthew zprop_list_t *entry; 1240 7390 Matthew 1241 7390 Matthew prop = zprop_name_to_prop(propname, type); 1242 7390 Matthew 1243 7390 Matthew if (prop != ZPROP_INVAL && !zprop_valid_for_type(prop, type)) 1244 7390 Matthew prop = ZPROP_INVAL; 1245 7390 Matthew 1246 7390 Matthew /* 1247 7390 Matthew * When no property table entry can be found, return failure if 1248 7390 Matthew * this is a pool property or if this isn't a user-defined 1249 7390 Matthew * dataset property, 1250 7390 Matthew */ 1251 7390 Matthew if (prop == ZPROP_INVAL && (type == ZFS_TYPE_POOL || 1252 9396 Matthew (!zfs_prop_user(propname) && !zfs_prop_userquota(propname)))) { 1253 7390 Matthew zfs_error_aux(hdl, dgettext(TEXT_DOMAIN, 1254 7390 Matthew "invalid property '%s'"), propname); 1255 7390 Matthew return (zfs_error(hdl, EZFS_BADPROP, 1256 7390 Matthew dgettext(TEXT_DOMAIN, "bad property list"))); 1257 7390 Matthew } 1258 7390 Matthew 1259 7390 Matthew if ((entry = zfs_alloc(hdl, sizeof (zprop_list_t))) == NULL) 1260 7390 Matthew return (-1); 1261 7390 Matthew 1262 7390 Matthew entry->pl_prop = prop; 1263 7390 Matthew if (prop == ZPROP_INVAL) { 1264 7390 Matthew if ((entry->pl_user_prop = zfs_strdup(hdl, propname)) == NULL) { 1265 7390 Matthew free(entry); 1266 7390 Matthew return (-1); 1267 7390 Matthew } 1268 7390 Matthew entry->pl_width = strlen(propname); 1269 7390 Matthew } else { 1270 7390 Matthew entry->pl_width = zprop_width(prop, &entry->pl_fixed, 1271 7390 Matthew type); 1272 7390 Matthew } 1273 7390 Matthew 1274 7390 Matthew *listp = entry; 1275 7390 Matthew 1276 7390 Matthew return (0); 1277 7390 Matthew } 1278 7390 Matthew 1279 5094 lling /* 1280 5094 lling * Given a comma-separated list of properties, construct a property list 1281 5094 lling * containing both user-defined and native properties. This function will 1282 5094 lling * return a NULL list if 'all' is specified, which can later be expanded 1283 5094 lling * by zprop_expand_list(). 1284 5094 lling */ 1285 5094 lling int 1286 5094 lling zprop_get_list(libzfs_handle_t *hdl, char *props, zprop_list_t **listp, 1287 5094 lling zfs_type_t type) 1288 5094 lling { 1289 5094 lling *listp = NULL; 1290 5094 lling 1291 5094 lling /* 1292 5094 lling * If 'all' is specified, return a NULL list. 1293 5094 lling */ 1294 5094 lling if (strcmp(props, "all") == 0) 1295 5094 lling return (0); 1296 5094 lling 1297 5094 lling /* 1298 5094 lling * If no props were specified, return an error. 1299 5094 lling */ 1300 5094 lling if (props[0] == '\0') { 1301 5094 lling zfs_error_aux(hdl, dgettext(TEXT_DOMAIN, 1302 5094 lling "no properties specified")); 1303 5094 lling return (zfs_error(hdl, EZFS_BADPROP, dgettext(TEXT_DOMAIN, 1304 5094 lling "bad property list"))); 1305 5094 lling } 1306 5094 lling 1307 5094 lling /* 1308 5094 lling * It would be nice to use getsubopt() here, but the inclusion of column 1309 5094 lling * aliases makes this more effort than it's worth. 1310 5094 lling */ 1311 7390 Matthew while (*props != '\0') { 1312 7390 Matthew size_t len; 1313 7390 Matthew char *p; 1314 7390 Matthew char c; 1315 7390 Matthew 1316 7390 Matthew if ((p = strchr(props, ',')) == NULL) { 1317 7390 Matthew len = strlen(props); 1318 7390 Matthew p = props + len; 1319 5094 lling } else { 1320 7390 Matthew len = p - props; 1321 5094 lling } 1322 5094 lling 1323 5094 lling /* 1324 5094 lling * Check for empty options. 1325 5094 lling */ 1326 5094 lling if (len == 0) { 1327 5094 lling zfs_error_aux(hdl, dgettext(TEXT_DOMAIN, 1328 5094 lling "empty property name")); 1329 5094 lling return (zfs_error(hdl, EZFS_BADPROP, 1330 5094 lling dgettext(TEXT_DOMAIN, "bad property list"))); 1331 5094 lling } 1332 5094 lling 1333 5094 lling /* 1334 5094 lling * Check all regular property names. 1335 5094 lling */ 1336 7390 Matthew c = props[len]; 1337 7390 Matthew props[len] = '\0'; 1338 5094 lling 1339 7390 Matthew if (strcmp(props, "space") == 0) { 1340 7390 Matthew static char *spaceprops[] = { 1341 7390 Matthew "name", "avail", "used", "usedbysnapshots", 1342 7390 Matthew "usedbydataset", "usedbyrefreservation", 1343 7390 Matthew "usedbychildren", NULL 1344 7390 Matthew }; 1345 7390 Matthew int i; 1346 5094 lling 1347 7390 Matthew for (i = 0; spaceprops[i]; i++) { 1348 7390 Matthew if (addlist(hdl, spaceprops[i], listp, type)) 1349 7390 Matthew return (-1); 1350 7390 Matthew listp = &(*listp)->pl_next; 1351 7390 Matthew } 1352 7390 Matthew } else { 1353 7390 Matthew if (addlist(hdl, props, listp, type)) 1354 7390 Matthew return (-1); 1355 7390 Matthew listp = &(*listp)->pl_next; 1356 5094 lling } 1357 5094 lling 1358 7390 Matthew props = p; 1359 5094 lling if (c == ',') 1360 7390 Matthew props++; 1361 5094 lling } 1362 5094 lling 1363 5094 lling return (0); 1364 5094 lling } 1365 5094 lling 1366 5094 lling void 1367 5094 lling zprop_free_list(zprop_list_t *pl) 1368 5094 lling { 1369 5094 lling zprop_list_t *next; 1370 5094 lling 1371 5094 lling while (pl != NULL) { 1372 5094 lling next = pl->pl_next; 1373 5094 lling free(pl->pl_user_prop); 1374 5094 lling free(pl); 1375 5094 lling pl = next; 1376 5094 lling } 1377 5094 lling } 1378 5094 lling 1379 5094 lling typedef struct expand_data { 1380 5094 lling zprop_list_t **last; 1381 5094 lling libzfs_handle_t *hdl; 1382 5094 lling zfs_type_t type; 1383 5094 lling } expand_data_t; 1384 5094 lling 1385 5094 lling int 1386 5094 lling zprop_expand_list_cb(int prop, void *cb) 1387 5094 lling { 1388 5094 lling zprop_list_t *entry; 1389 5094 lling expand_data_t *edp = cb; 1390 5094 lling 1391 5094 lling if ((entry = zfs_alloc(edp->hdl, sizeof (zprop_list_t))) == NULL) 1392 5094 lling return (ZPROP_INVAL); 1393 5094 lling 1394 5094 lling entry->pl_prop = prop; 1395 5094 lling entry->pl_width = zprop_width(prop, &entry->pl_fixed, edp->type); 1396 5094 lling entry->pl_all = B_TRUE; 1397 5094 lling 1398 5094 lling *(edp->last) = entry; 1399 5094 lling edp->last = &entry->pl_next; 1400 5094 lling 1401 5094 lling return (ZPROP_CONT); 1402 5094 lling } 1403 5094 lling 1404 5094 lling int 1405 5094 lling zprop_expand_list(libzfs_handle_t *hdl, zprop_list_t **plp, zfs_type_t type) 1406 5094 lling { 1407 5094 lling zprop_list_t *entry; 1408 5094 lling zprop_list_t **last; 1409 5094 lling expand_data_t exp; 1410 5094 lling 1411 5094 lling if (*plp == NULL) { 1412 5094 lling /* 1413 5094 lling * If this is the very first time we've been called for an 'all' 1414 5094 lling * specification, expand the list to include all native 1415 5094 lling * properties. 1416 5094 lling */ 1417 5094 lling last = plp; 1418 5094 lling 1419 5094 lling exp.last = last; 1420 5094 lling exp.hdl = hdl; 1421 5094 lling exp.type = type; 1422 5094 lling 1423 5094 lling if (zprop_iter_common(zprop_expand_list_cb, &exp, B_FALSE, 1424 5094 lling B_FALSE, type) == ZPROP_INVAL) 1425 5094 lling return (-1); 1426 5094 lling 1427 5094 lling /* 1428 5094 lling * Add 'name' to the beginning of the list, which is handled 1429 5094 lling * specially. 1430 5094 lling */ 1431 5094 lling if ((entry = zfs_alloc(hdl, sizeof (zprop_list_t))) == NULL) 1432 5094 lling return (-1); 1433 5094 lling 1434 5094 lling entry->pl_prop = (type == ZFS_TYPE_POOL) ? ZPOOL_PROP_NAME : 1435 5094 lling ZFS_PROP_NAME; 1436 5094 lling entry->pl_width = zprop_width(entry->pl_prop, 1437 5094 lling &entry->pl_fixed, type); 1438 5094 lling entry->pl_all = B_TRUE; 1439 5094 lling entry->pl_next = *plp; 1440 5094 lling *plp = entry; 1441 5094 lling } 1442 5094 lling return (0); 1443 5094 lling } 1444 5094 lling 1445 5094 lling int 1446 5094 lling zprop_iter(zprop_func func, void *cb, boolean_t show_all, boolean_t ordered, 1447 5094 lling zfs_type_t type) 1448 5094 lling { 1449 5094 lling return (zprop_iter_common(func, cb, show_all, ordered, type)); 1450 5094 lling } 1451