1 /* 2 * CDDL HEADER START 3 * 4 * The contents of this file are subject to the terms of the 5 * Common Development and Distribution License (the "License"). 6 * You may not use this file except in compliance with the License. 7 * 8 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE 9 * or http://www.opensolaris.org/os/licensing. 10 * See the License for the specific language governing permissions 11 * and limitations under the License. 12 * 13 * When distributing Covered Code, include this CDDL HEADER in each 14 * file and include the License file at usr/src/OPENSOLARIS.LICENSE. 15 * If applicable, add the following below this CDDL HEADER, with the 16 * fields enclosed by brackets "[]" replaced with your own identifying 17 * information: Portions Copyright [yyyy] [name of copyright owner] 18 * 19 * CDDL HEADER END 20 */ 21 22 /* 23 * Copyright (c) 2013 Martin Matuska <mm@FreeBSD.org>. All rights reserved. 24 */ 25 #include "../../libzfs_impl.h" 26 #include <libzfs.h> 27 #include <libzutil.h> 28 #include <sys/sysctl.h> 29 #include <libintl.h> 30 #include <sys/linker.h> 31 #include <sys/module.h> 32 #include <sys/stat.h> 33 #include <sys/param.h> 34 35 #ifdef IN_BASE 36 #define ZFS_KMOD "zfs" 37 #else 38 #define ZFS_KMOD "openzfs" 39 #endif 40 41 void 42 libzfs_set_pipe_max(int infd) 43 { 44 /* FreeBSD automatically resizes */ 45 } 46 47 static int 48 execvPe(const char *name, const char *path, char * const *argv, 49 char * const *envp) 50 { 51 const char **memp; 52 size_t cnt, lp, ln; 53 int eacces, save_errno; 54 char buf[MAXPATHLEN]; 55 const char *bp, *np, *op, *p; 56 struct stat sb; 57 58 eacces = 0; 59 60 /* If it's an absolute or relative path name, it's easy. */ 61 if (strchr(name, '/')) { 62 bp = name; 63 op = NULL; 64 goto retry; 65 } 66 bp = buf; 67 68 /* If it's an empty path name, fail in the usual POSIX way. */ 69 if (*name == '\0') { 70 errno = ENOENT; 71 return (-1); 72 } 73 74 op = path; 75 ln = strlen(name); 76 while (op != NULL) { 77 np = strchrnul(op, ':'); 78 79 /* 80 * It's a SHELL path -- double, leading and trailing colons 81 * mean the current directory. 82 */ 83 if (np == op) { 84 /* Empty component. */ 85 p = "."; 86 lp = 1; 87 } else { 88 /* Non-empty component. */ 89 p = op; 90 lp = np - op; 91 } 92 93 /* Advance to the next component or terminate after this. */ 94 if (*np == '\0') 95 op = NULL; 96 else 97 op = np + 1; 98 99 /* 100 * If the path is too long complain. This is a possible 101 * security issue; given a way to make the path too long 102 * the user may execute the wrong program. 103 */ 104 if (lp + ln + 2 > sizeof (buf)) { 105 (void) write(STDERR_FILENO, "execvP: ", 8); 106 (void) write(STDERR_FILENO, p, lp); 107 (void) write(STDERR_FILENO, ": path too long\n", 108 16); 109 continue; 110 } 111 bcopy(p, buf, lp); 112 buf[lp] = '/'; 113 bcopy(name, buf + lp + 1, ln); 114 buf[lp + ln + 1] = '\0'; 115 116 retry: (void) execve(bp, argv, envp); 117 switch (errno) { 118 case E2BIG: 119 goto done; 120 case ELOOP: 121 case ENAMETOOLONG: 122 case ENOENT: 123 break; 124 case ENOEXEC: 125 for (cnt = 0; argv[cnt]; ++cnt) 126 ; 127 128 /* 129 * cnt may be 0 above; always allocate at least 130 * 3 entries so that we can at least fit "sh", bp, and 131 * the NULL terminator. We can rely on cnt to take into 132 * account the NULL terminator in all other scenarios, 133 * as we drop argv[0]. 134 */ 135 memp = alloca(MAX(3, cnt + 2) * sizeof (char *)); 136 if (memp == NULL) { 137 /* errno = ENOMEM; XXX override ENOEXEC? */ 138 goto done; 139 } 140 if (cnt > 0) { 141 memp[0] = argv[0]; 142 memp[1] = bp; 143 bcopy(argv + 1, memp + 2, 144 cnt * sizeof (char *)); 145 } else { 146 memp[0] = "sh"; 147 memp[1] = bp; 148 memp[2] = NULL; 149 } 150 (void) execve(_PATH_BSHELL, 151 __DECONST(char **, memp), envp); 152 goto done; 153 case ENOMEM: 154 goto done; 155 case ENOTDIR: 156 break; 157 case ETXTBSY: 158 /* 159 * We used to retry here, but sh(1) doesn't. 160 */ 161 goto done; 162 default: 163 /* 164 * EACCES may be for an inaccessible directory or 165 * a non-executable file. Call stat() to decide 166 * which. This also handles ambiguities for EFAULT 167 * and EIO, and undocumented errors like ESTALE. 168 * We hope that the race for a stat() is unimportant. 169 */ 170 save_errno = errno; 171 if (stat(bp, &sb) != 0) 172 break; 173 if (save_errno == EACCES) { 174 eacces = 1; 175 continue; 176 } 177 errno = save_errno; 178 goto done; 179 } 180 } 181 if (eacces) 182 errno = EACCES; 183 else 184 errno = ENOENT; 185 done: 186 return (-1); 187 } 188 189 int 190 execvpe(const char *name, char * const argv[], char * const envp[]) 191 { 192 const char *path; 193 194 /* Get the path we're searching. */ 195 if ((path = getenv("PATH")) == NULL) 196 path = _PATH_DEFPATH; 197 198 return (execvPe(name, path, argv, envp)); 199 } 200 201 #define ERRBUFLEN 256 202 203 static __thread char errbuf[ERRBUFLEN]; 204 205 const char * 206 libzfs_error_init(int error) 207 { 208 char *msg = errbuf; 209 size_t len, msglen = ERRBUFLEN; 210 211 if (modfind("zfs") < 0) { 212 len = snprintf(msg, msglen, dgettext(TEXT_DOMAIN, 213 "Failed to load %s module: "), ZFS_KMOD); 214 msg += len; 215 msglen -= len; 216 } 217 218 (void) snprintf(msg, msglen, "%s", strerror(error)); 219 220 return (errbuf); 221 } 222 223 int 224 zfs_ioctl(libzfs_handle_t *hdl, int request, zfs_cmd_t *zc) 225 { 226 return (lzc_ioctl_fd(hdl->libzfs_fd, request, zc)); 227 } 228 229 /* 230 * Verify the required ZFS_DEV device is available and optionally attempt 231 * to load the ZFS modules. Under normal circumstances the modules 232 * should already have been loaded by some external mechanism. 233 */ 234 int 235 libzfs_load_module(void) 236 { 237 /* 238 * XXX: kldfind(ZFS_KMOD) would be nice here, but we retain 239 * modfind("zfs") so out-of-base openzfs userland works with the 240 * in-base module. 241 */ 242 if (modfind("zfs") < 0) { 243 /* Not present in kernel, try loading it. */ 244 if (kldload(ZFS_KMOD) < 0 && errno != EEXIST) { 245 return (errno); 246 } 247 } 248 return (0); 249 } 250 251 int 252 zpool_relabel_disk(libzfs_handle_t *hdl, const char *path, const char *msg) 253 { 254 return (0); 255 } 256 257 int 258 zpool_label_disk(libzfs_handle_t *hdl, zpool_handle_t *zhp, const char *name) 259 { 260 return (0); 261 } 262 263 int 264 find_shares_object(differ_info_t *di) 265 { 266 return (0); 267 } 268 269 int 270 zfs_destroy_snaps_nvl_os(libzfs_handle_t *hdl, nvlist_t *snaps) 271 { 272 return (0); 273 } 274 275 /* 276 * Attach/detach the given filesystem to/from the given jail. 277 */ 278 int 279 zfs_jail(zfs_handle_t *zhp, int jailid, int attach) 280 { 281 libzfs_handle_t *hdl = zhp->zfs_hdl; 282 zfs_cmd_t zc = {"\0"}; 283 char errbuf[1024]; 284 unsigned long cmd; 285 int ret; 286 287 if (attach) { 288 (void) snprintf(errbuf, sizeof (errbuf), 289 dgettext(TEXT_DOMAIN, "cannot jail '%s'"), zhp->zfs_name); 290 } else { 291 (void) snprintf(errbuf, sizeof (errbuf), 292 dgettext(TEXT_DOMAIN, "cannot unjail '%s'"), zhp->zfs_name); 293 } 294 295 switch (zhp->zfs_type) { 296 case ZFS_TYPE_VOLUME: 297 zfs_error_aux(hdl, dgettext(TEXT_DOMAIN, 298 "volumes can not be jailed")); 299 return (zfs_error(hdl, EZFS_BADTYPE, errbuf)); 300 case ZFS_TYPE_SNAPSHOT: 301 zfs_error_aux(hdl, dgettext(TEXT_DOMAIN, 302 "snapshots can not be jailed")); 303 return (zfs_error(hdl, EZFS_BADTYPE, errbuf)); 304 case ZFS_TYPE_BOOKMARK: 305 zfs_error_aux(hdl, dgettext(TEXT_DOMAIN, 306 "bookmarks can not be jailed")); 307 return (zfs_error(hdl, EZFS_BADTYPE, errbuf)); 308 case ZFS_TYPE_VDEV: 309 zfs_error_aux(hdl, dgettext(TEXT_DOMAIN, 310 "vdevs can not be jailed")); 311 return (zfs_error(hdl, EZFS_BADTYPE, errbuf)); 312 case ZFS_TYPE_POOL: 313 case ZFS_TYPE_FILESYSTEM: 314 /* OK */ 315 ; 316 } 317 assert(zhp->zfs_type == ZFS_TYPE_FILESYSTEM); 318 319 (void) strlcpy(zc.zc_name, zhp->zfs_name, sizeof (zc.zc_name)); 320 zc.zc_objset_type = DMU_OST_ZFS; 321 zc.zc_zoneid = jailid; 322 323 cmd = attach ? ZFS_IOC_JAIL : ZFS_IOC_UNJAIL; 324 if ((ret = zfs_ioctl(hdl, cmd, &zc)) != 0) 325 zfs_standard_error(hdl, errno, errbuf); 326 327 return (ret); 328 } 329 330 /* 331 * Set loader options for next boot. 332 */ 333 int 334 zpool_nextboot(libzfs_handle_t *hdl, uint64_t pool_guid, uint64_t dev_guid, 335 const char *command) 336 { 337 zfs_cmd_t zc = {"\0"}; 338 nvlist_t *args; 339 int error; 340 341 args = fnvlist_alloc(); 342 fnvlist_add_uint64(args, ZPOOL_CONFIG_POOL_GUID, pool_guid); 343 fnvlist_add_uint64(args, ZPOOL_CONFIG_GUID, dev_guid); 344 fnvlist_add_string(args, "command", command); 345 error = zcmd_write_src_nvlist(hdl, &zc, args); 346 if (error == 0) 347 error = zfs_ioctl(hdl, ZFS_IOC_NEXTBOOT, &zc); 348 zcmd_free_nvlists(&zc); 349 nvlist_free(args); 350 return (error); 351 } 352 353 /* 354 * Fill given version buffer with zfs kernel version. 355 * Returns 0 on success, and -1 on error (with errno set) 356 */ 357 int 358 zfs_version_kernel(char *version, int len) 359 { 360 size_t l = len; 361 362 return (sysctlbyname("vfs.zfs.version.module", 363 version, &l, NULL, 0)); 364 } 365