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 https://opensource.org/licenses/CDDL-1.0.
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 "../../libzfs_impl.h"
28 #include <sys/sysctl.h>
30 #include <sys/linker.h>
31 #include <sys/module.h>
33 #include <sys/param.h>
36 #define ZFS_KMOD "zfs"
38 #define ZFS_KMOD "openzfs"
43 execvPe(const char *name
, const char *path
, char * const *argv
,
48 int eacces
, save_errno
;
50 const char *bp
, *np
, *op
, *p
;
55 /* If it's an absolute or relative path name, it's easy. */
56 if (strchr(name
, '/')) {
63 /* If it's an empty path name, fail in the usual POSIX way. */
72 np
= strchrnul(op
, ':');
75 * It's a SHELL path -- double, leading and trailing colons
76 * mean the current directory.
79 /* Empty component. */
83 /* Non-empty component. */
88 /* Advance to the next component or terminate after this. */
95 * If the path is too long complain. This is a possible
96 * security issue; given a way to make the path too long
97 * the user may execute the wrong program.
99 if (lp
+ ln
+ 2 > sizeof (buf
)) {
100 (void) write(STDERR_FILENO
, "execvP: ", 8);
101 (void) write(STDERR_FILENO
, p
, lp
);
102 (void) write(STDERR_FILENO
, ": path too long\n",
108 memcpy(buf
+ lp
+ 1, name
, ln
);
109 buf
[lp
+ ln
+ 1] = '\0';
111 retry
: (void) execve(bp
, argv
, envp
);
120 for (cnt
= 0; argv
[cnt
]; ++cnt
)
124 * cnt may be 0 above; always allocate at least
125 * 3 entries so that we can at least fit "sh", bp, and
126 * the NULL terminator. We can rely on cnt to take into
127 * account the NULL terminator in all other scenarios,
128 * as we drop argv[0].
130 memp
= alloca(MAX(3, cnt
+ 2) * sizeof (char *));
132 /* errno = ENOMEM; XXX override ENOEXEC? */
138 memcpy(memp
+ 2, argv
+ 1,
139 cnt
* sizeof (char *));
145 (void) execve(_PATH_BSHELL
,
146 __DECONST(char **, memp
), envp
);
154 * We used to retry here, but sh(1) doesn't.
159 * EACCES may be for an inaccessible directory or
160 * a non-executable file. Call stat() to decide
161 * which. This also handles ambiguities for EFAULT
162 * and EIO, and undocumented errors like ESTALE.
163 * We hope that the race for a stat() is unimportant.
166 if (stat(bp
, &sb
) != 0)
168 if (save_errno
== EACCES
) {
185 execvpe(const char *name
, char * const argv
[], char * const envp
[])
189 /* Get the path we're searching. */
190 if ((path
= getenv("PATH")) == NULL
)
191 path
= _PATH_DEFPATH
;
193 return (execvPe(name
, path
, argv
, envp
));
196 static __thread
char errbuf
[ERRBUFLEN
];
199 libzfs_error_init(int error
)
202 size_t msglen
= sizeof (errbuf
);
204 if (modfind("zfs") < 0) {
205 size_t len
= snprintf(msg
, msglen
, dgettext(TEXT_DOMAIN
,
206 "Failed to load %s module: "), ZFS_KMOD
);
213 (void) snprintf(msg
, msglen
, "%s", strerror(error
));
219 zfs_ioctl(libzfs_handle_t
*hdl
, int request
, zfs_cmd_t
*zc
)
221 return (lzc_ioctl_fd(hdl
->libzfs_fd
, request
, zc
));
225 * Verify the required ZFS_DEV device is available and optionally attempt
226 * to load the ZFS modules. Under normal circumstances the modules
227 * should already have been loaded by some external mechanism.
230 libzfs_load_module(void)
233 * XXX: kldfind(ZFS_KMOD) would be nice here, but we retain
234 * modfind("zfs") so out-of-base openzfs userland works with the
237 if (modfind("zfs") < 0) {
238 /* Not present in kernel, try loading it. */
239 if (kldload(ZFS_KMOD
) < 0 && errno
!= EEXIST
) {
247 zpool_relabel_disk(libzfs_handle_t
*hdl
, const char *path
, const char *msg
)
249 (void) hdl
, (void) path
, (void) msg
;
254 zpool_label_disk(libzfs_handle_t
*hdl
, zpool_handle_t
*zhp
, const char *name
)
256 (void) hdl
, (void) zhp
, (void) name
;
261 find_shares_object(differ_info_t
*di
)
268 zfs_destroy_snaps_nvl_os(libzfs_handle_t
*hdl
, nvlist_t
*snaps
)
270 (void) hdl
, (void) snaps
;
275 * Attach/detach the given filesystem to/from the given jail.
278 zfs_jail(zfs_handle_t
*zhp
, int jailid
, int attach
)
280 libzfs_handle_t
*hdl
= zhp
->zfs_hdl
;
281 zfs_cmd_t zc
= {"\0"};
286 (void) snprintf(errbuf
, sizeof (errbuf
),
287 dgettext(TEXT_DOMAIN
, "cannot jail '%s'"), zhp
->zfs_name
);
289 (void) snprintf(errbuf
, sizeof (errbuf
),
290 dgettext(TEXT_DOMAIN
, "cannot unjail '%s'"), zhp
->zfs_name
);
293 switch (zhp
->zfs_type
) {
294 case ZFS_TYPE_VOLUME
:
295 zfs_error_aux(hdl
, dgettext(TEXT_DOMAIN
,
296 "volumes can not be jailed"));
297 return (zfs_error(hdl
, EZFS_BADTYPE
, errbuf
));
298 case ZFS_TYPE_SNAPSHOT
:
299 zfs_error_aux(hdl
, dgettext(TEXT_DOMAIN
,
300 "snapshots can not be jailed"));
301 return (zfs_error(hdl
, EZFS_BADTYPE
, errbuf
));
302 case ZFS_TYPE_BOOKMARK
:
303 zfs_error_aux(hdl
, dgettext(TEXT_DOMAIN
,
304 "bookmarks can not be jailed"));
305 return (zfs_error(hdl
, EZFS_BADTYPE
, errbuf
));
307 zfs_error_aux(hdl
, dgettext(TEXT_DOMAIN
,
308 "vdevs can not be jailed"));
309 return (zfs_error(hdl
, EZFS_BADTYPE
, errbuf
));
310 case ZFS_TYPE_INVALID
:
311 zfs_error_aux(hdl
, dgettext(TEXT_DOMAIN
,
312 "invalid zfs_type_t: ZFS_TYPE_INVALID"));
313 return (zfs_error(hdl
, EZFS_BADTYPE
, errbuf
));
315 case ZFS_TYPE_FILESYSTEM
:
319 assert(zhp
->zfs_type
== ZFS_TYPE_FILESYSTEM
);
321 (void) strlcpy(zc
.zc_name
, zhp
->zfs_name
, sizeof (zc
.zc_name
));
322 zc
.zc_objset_type
= DMU_OST_ZFS
;
323 zc
.zc_zoneid
= jailid
;
325 cmd
= attach
? ZFS_IOC_JAIL
: ZFS_IOC_UNJAIL
;
326 if ((ret
= zfs_ioctl(hdl
, cmd
, &zc
)) != 0)
327 zfs_standard_error(hdl
, errno
, errbuf
);
333 * Set loader options for next boot.
336 zpool_nextboot(libzfs_handle_t
*hdl
, uint64_t pool_guid
, uint64_t dev_guid
,
339 zfs_cmd_t zc
= {"\0"};
342 args
= fnvlist_alloc();
343 fnvlist_add_uint64(args
, ZPOOL_CONFIG_POOL_GUID
, pool_guid
);
344 fnvlist_add_uint64(args
, ZPOOL_CONFIG_GUID
, dev_guid
);
345 fnvlist_add_string(args
, "command", command
);
346 zcmd_write_src_nvlist(hdl
, &zc
, args
);
347 int error
= zfs_ioctl(hdl
, ZFS_IOC_NEXTBOOT
, &zc
);
348 zcmd_free_nvlists(&zc
);
354 * Return allocated loaded module version, or NULL on error (with errno set)
357 zfs_version_kernel(void)
360 if (sysctlbyname("vfs.zfs.version.module",
361 NULL
, &l
, NULL
, 0) == -1)
363 char *version
= malloc(l
);
366 if (sysctlbyname("vfs.zfs.version.module",
367 version
, &l
, NULL
, 0) == -1) {