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