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.
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.
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]
23 * Copyright (c) 2013 Martin Matuska <mm@FreeBSD.org>. All rights reserved.
25 #include <os/freebsd/zfs/sys/zfs_ioctl_compat.h>
26 #include <libzfs_impl.h>
29 #include <sys/sysctl.h>
31 #include <sys/linker.h>
32 #include <sys/module.h>
34 #include <sys/param.h>
37 #define ZFS_KMOD "zfs"
39 #define ZFS_KMOD "openzfs"
43 libzfs_set_pipe_max(int infd)
45 /* FreeBSD automatically resizes */
49 execvPe(const char *name, const char *path, char * const *argv,
54 int eacces, save_errno;
55 char *cur, buf[MAXPATHLEN];
61 /* If it's an absolute or relative path name, it's easy. */
62 if (strchr(name, '/')) {
69 /* If it's an empty path name, fail in the usual POSIX way. */
75 cur = alloca(strlen(path) + 1);
81 while ((p = strsep(&cur, ":")) != NULL) {
83 * It's a SHELL path -- double, leading and trailing colons
84 * mean the current directory.
94 * If the path is too long complain. This is a possible
95 * security issue; given a way to make the path too long
96 * the user may execute the wrong program.
98 if (lp + ln + 2 > sizeof (buf)) {
99 (void) write(STDERR_FILENO, "execvP: ", 8);
100 (void) write(STDERR_FILENO, p, lp);
101 (void) write(STDERR_FILENO, ": path too long\n",
107 bcopy(name, buf + lp + 1, ln);
108 buf[lp + ln + 1] = '\0';
110 retry: (void) execve(bp, argv, envp);
119 for (cnt = 0; argv[cnt]; ++cnt)
121 memp = alloca((cnt + 2) * sizeof (char *));
123 /* errno = ENOMEM; XXX override ENOEXEC? */
128 bcopy(argv + 1, memp + 2, cnt * sizeof (char *));
129 execve(_PATH_BSHELL, __DECONST(char **, memp), envp);
137 * We used to retry here, but sh(1) doesn't.
142 * EACCES may be for an inaccessible directory or
143 * a non-executable file. Call stat() to decide
144 * which. This also handles ambiguities for EFAULT
145 * and EIO, and undocumented errors like ESTALE.
146 * We hope that the race for a stat() is unimportant.
149 if (stat(bp, &sb) != 0)
151 if (save_errno == EACCES) {
168 execvpe(const char *name, char * const argv[], char * const envp[])
172 /* Get the path we're searching. */
173 if ((path = getenv("PATH")) == NULL)
174 path = _PATH_DEFPATH;
176 return (execvPe(name, path, argv, envp));
179 #define ERRBUFLEN 256
181 __thread static char errbuf[ERRBUFLEN];
184 libzfs_error_init(int error)
187 size_t len, msglen = ERRBUFLEN;
189 if (modfind("zfs") < 0) {
190 len = snprintf(msg, msglen, dgettext(TEXT_DOMAIN,
191 "Failed to load %s module: "), ZFS_KMOD);
196 (void) snprintf(msg, msglen, "%s", strerror(error));
202 zfs_ioctl(libzfs_handle_t *hdl, int request, zfs_cmd_t *zc)
204 return (zfs_ioctl_fd(hdl->libzfs_fd, request, zc));
208 * Verify the required ZFS_DEV device is available and optionally attempt
209 * to load the ZFS modules. Under normal circumstances the modules
210 * should already have been loaded by some external mechanism.
213 libzfs_load_module(void)
216 * XXX: kldfind(ZFS_KMOD) would be nice here, but we retain
217 * modfind("zfs") so out-of-base openzfs userland works with the
220 if (modfind("zfs") < 0) {
221 /* Not present in kernel, try loading it. */
222 if (kldload(ZFS_KMOD) < 0 && errno != EEXIST) {
230 zpool_relabel_disk(libzfs_handle_t *hdl, const char *path, const char *msg)
236 zpool_label_disk(libzfs_handle_t *hdl, zpool_handle_t *zhp, const char *name)
242 find_shares_object(differ_info_t *di)
248 * Attach/detach the given filesystem to/from the given jail.
251 zfs_jail(zfs_handle_t *zhp, int jailid, int attach)
253 libzfs_handle_t *hdl = zhp->zfs_hdl;
254 zfs_cmd_t zc = {"\0"};
260 (void) snprintf(errbuf, sizeof (errbuf),
261 dgettext(TEXT_DOMAIN, "cannot jail '%s'"), zhp->zfs_name);
263 (void) snprintf(errbuf, sizeof (errbuf),
264 dgettext(TEXT_DOMAIN, "cannot unjail '%s'"), zhp->zfs_name);
267 switch (zhp->zfs_type) {
268 case ZFS_TYPE_VOLUME:
269 zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
270 "volumes can not be jailed"));
271 return (zfs_error(hdl, EZFS_BADTYPE, errbuf));
272 case ZFS_TYPE_SNAPSHOT:
273 zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
274 "snapshots can not be jailed"));
275 return (zfs_error(hdl, EZFS_BADTYPE, errbuf));
276 case ZFS_TYPE_BOOKMARK:
277 zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
278 "bookmarks can not be jailed"));
279 return (zfs_error(hdl, EZFS_BADTYPE, errbuf));
281 case ZFS_TYPE_FILESYSTEM:
285 assert(zhp->zfs_type == ZFS_TYPE_FILESYSTEM);
287 (void) strlcpy(zc.zc_name, zhp->zfs_name, sizeof (zc.zc_name));
288 zc.zc_objset_type = DMU_OST_ZFS;
289 zc.zc_zoneid = jailid;
291 cmd = attach ? ZFS_IOC_JAIL : ZFS_IOC_UNJAIL;
292 if ((ret = zfs_ioctl(hdl, cmd, &zc)) != 0)
293 zfs_standard_error(hdl, errno, errbuf);
299 * Set loader options for next boot.
302 zpool_nextboot(libzfs_handle_t *hdl, uint64_t pool_guid, uint64_t dev_guid,
305 zfs_cmd_t zc = {"\0"};
309 args = fnvlist_alloc();
310 fnvlist_add_uint64(args, ZPOOL_CONFIG_POOL_GUID, pool_guid);
311 fnvlist_add_uint64(args, ZPOOL_CONFIG_GUID, dev_guid);
312 fnvlist_add_string(args, "command", command);
313 error = zcmd_write_src_nvlist(hdl, &zc, args);
315 error = zfs_ioctl(hdl, ZFS_IOC_NEXTBOOT, &zc);
316 zcmd_free_nvlists(&zc);
322 * Fill given version buffer with zfs kernel version.
323 * Returns 0 on success, and -1 on error (with errno set)
326 zfs_version_kernel(char *version, int len)
330 return (sysctlbyname("vfs.zfs.version.module",
331 version, &l, NULL, 0));