1eda14cbcSMatt Macy /* 2eda14cbcSMatt Macy * Copyright (c) 2020 iXsystems, Inc. 3eda14cbcSMatt Macy * All rights reserved. 4eda14cbcSMatt Macy * 5eda14cbcSMatt Macy * Redistribution and use in source and binary forms, with or without 6eda14cbcSMatt Macy * modification, are permitted provided that the following conditions 7eda14cbcSMatt Macy * are met: 8eda14cbcSMatt Macy * 1. Redistributions of source code must retain the above copyright 9eda14cbcSMatt Macy * notice, this list of conditions and the following disclaimer. 10eda14cbcSMatt Macy * 2. Redistributions in binary form must reproduce the above copyright 11eda14cbcSMatt Macy * notice, this list of conditions and the following disclaimer in the 12eda14cbcSMatt Macy * documentation and/or other materials provided with the distribution. 13eda14cbcSMatt Macy * 14eda14cbcSMatt Macy * THIS SOFTWARE IS PROVIDED BY THE AUTHORS AND CONTRIBUTORS ``AS IS'' AND 15eda14cbcSMatt Macy * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 16eda14cbcSMatt Macy * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 17eda14cbcSMatt Macy * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHORS OR CONTRIBUTORS BE LIABLE 18eda14cbcSMatt Macy * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 19eda14cbcSMatt Macy * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 20eda14cbcSMatt Macy * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 21eda14cbcSMatt Macy * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 22eda14cbcSMatt Macy * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 23eda14cbcSMatt Macy * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 24eda14cbcSMatt Macy * SUCH DAMAGE. 25eda14cbcSMatt Macy * 26eda14cbcSMatt Macy */ 27eda14cbcSMatt Macy 28eda14cbcSMatt Macy #include <sys/types.h> 29eda14cbcSMatt Macy #include <sys/errno.h> 30eda14cbcSMatt Macy #include <sys/nvpair.h> 31eda14cbcSMatt Macy #include <sys/spa_impl.h> 32eda14cbcSMatt Macy #include <sys/vdev_os.h> 33eda14cbcSMatt Macy #include <sys/zfs_vfsops.h> 34eda14cbcSMatt Macy #include <sys/zone.h> 35eda14cbcSMatt Macy #include <vm/vm_pageout.h> 36eda14cbcSMatt Macy 37eda14cbcSMatt Macy #include <sys/zfs_ioctl_impl.h> 38eda14cbcSMatt Macy 39eda14cbcSMatt Macy int 40eda14cbcSMatt Macy zfs_vfs_ref(zfsvfs_t **zfvp) 41eda14cbcSMatt Macy { 42eda14cbcSMatt Macy int error = 0; 43eda14cbcSMatt Macy 44eda14cbcSMatt Macy if (*zfvp == NULL) 45eda14cbcSMatt Macy return (SET_ERROR(ESRCH)); 46eda14cbcSMatt Macy 47eda14cbcSMatt Macy error = vfs_busy((*zfvp)->z_vfs, 0); 48eda14cbcSMatt Macy if (error != 0) { 49eda14cbcSMatt Macy *zfvp = NULL; 50eda14cbcSMatt Macy error = SET_ERROR(ESRCH); 51eda14cbcSMatt Macy } 52eda14cbcSMatt Macy return (error); 53eda14cbcSMatt Macy } 54eda14cbcSMatt Macy 55*64b5d74fSDimitry Andric boolean_t 56eda14cbcSMatt Macy zfs_vfs_held(zfsvfs_t *zfsvfs) 57eda14cbcSMatt Macy { 58eda14cbcSMatt Macy return (zfsvfs->z_vfs != NULL); 59eda14cbcSMatt Macy } 60eda14cbcSMatt Macy 61eda14cbcSMatt Macy void 62eda14cbcSMatt Macy zfs_vfs_rele(zfsvfs_t *zfsvfs) 63eda14cbcSMatt Macy { 64eda14cbcSMatt Macy vfs_unbusy(zfsvfs->z_vfs); 65eda14cbcSMatt Macy } 66eda14cbcSMatt Macy 67eda14cbcSMatt Macy static const zfs_ioc_key_t zfs_keys_nextboot[] = { 68eda14cbcSMatt Macy {"command", DATA_TYPE_STRING, 0}, 69eda14cbcSMatt Macy { ZPOOL_CONFIG_POOL_GUID, DATA_TYPE_UINT64, 0}, 70eda14cbcSMatt Macy { ZPOOL_CONFIG_GUID, DATA_TYPE_UINT64, 0} 71eda14cbcSMatt Macy }; 72eda14cbcSMatt Macy 73eda14cbcSMatt Macy static int 74eda14cbcSMatt Macy zfs_ioc_jail(zfs_cmd_t *zc) 75eda14cbcSMatt Macy { 76eda14cbcSMatt Macy 77eda14cbcSMatt Macy return (zone_dataset_attach(curthread->td_ucred, zc->zc_name, 78eda14cbcSMatt Macy (int)zc->zc_zoneid)); 79eda14cbcSMatt Macy } 80eda14cbcSMatt Macy 81eda14cbcSMatt Macy static int 82eda14cbcSMatt Macy zfs_ioc_unjail(zfs_cmd_t *zc) 83eda14cbcSMatt Macy { 84eda14cbcSMatt Macy 85eda14cbcSMatt Macy return (zone_dataset_detach(curthread->td_ucred, zc->zc_name, 86eda14cbcSMatt Macy (int)zc->zc_zoneid)); 87eda14cbcSMatt Macy } 88eda14cbcSMatt Macy 89eda14cbcSMatt Macy static int 90eda14cbcSMatt Macy zfs_ioc_nextboot(const char *unused, nvlist_t *innvl, nvlist_t *outnvl) 91eda14cbcSMatt Macy { 92eda14cbcSMatt Macy char name[MAXNAMELEN]; 93eda14cbcSMatt Macy spa_t *spa; 94eda14cbcSMatt Macy vdev_t *vd; 952a58b312SMartin Matuska const char *command; 96eda14cbcSMatt Macy uint64_t pool_guid; 97eda14cbcSMatt Macy uint64_t vdev_guid; 98eda14cbcSMatt Macy int error; 99eda14cbcSMatt Macy 100eda14cbcSMatt Macy if (nvlist_lookup_uint64(innvl, 101eda14cbcSMatt Macy ZPOOL_CONFIG_POOL_GUID, &pool_guid) != 0) 102eda14cbcSMatt Macy return (EINVAL); 103eda14cbcSMatt Macy if (nvlist_lookup_uint64(innvl, 104eda14cbcSMatt Macy ZPOOL_CONFIG_GUID, &vdev_guid) != 0) 105eda14cbcSMatt Macy return (EINVAL); 106eda14cbcSMatt Macy if (nvlist_lookup_string(innvl, 107eda14cbcSMatt Macy "command", &command) != 0) 108eda14cbcSMatt Macy return (EINVAL); 109eda14cbcSMatt Macy 110eda14cbcSMatt Macy mutex_enter(&spa_namespace_lock); 111eda14cbcSMatt Macy spa = spa_by_guid(pool_guid, vdev_guid); 112eda14cbcSMatt Macy if (spa != NULL) 113eda14cbcSMatt Macy strcpy(name, spa_name(spa)); 114eda14cbcSMatt Macy mutex_exit(&spa_namespace_lock); 115eda14cbcSMatt Macy if (spa == NULL) 116eda14cbcSMatt Macy return (ENOENT); 117eda14cbcSMatt Macy 118eda14cbcSMatt Macy if ((error = spa_open(name, &spa, FTAG)) != 0) 119eda14cbcSMatt Macy return (error); 120eda14cbcSMatt Macy spa_vdev_state_enter(spa, SCL_ALL); 121eda14cbcSMatt Macy vd = spa_lookup_by_guid(spa, vdev_guid, B_TRUE); 122eda14cbcSMatt Macy if (vd == NULL) { 123eda14cbcSMatt Macy (void) spa_vdev_state_exit(spa, NULL, ENXIO); 124eda14cbcSMatt Macy spa_close(spa, FTAG); 125eda14cbcSMatt Macy return (ENODEV); 126eda14cbcSMatt Macy } 127eda14cbcSMatt Macy error = vdev_label_write_pad2(vd, command, strlen(command)); 128eda14cbcSMatt Macy (void) spa_vdev_state_exit(spa, NULL, 0); 129eda14cbcSMatt Macy txg_wait_synced(spa->spa_dsl_pool, 0); 130eda14cbcSMatt Macy spa_close(spa, FTAG); 131eda14cbcSMatt Macy return (error); 132eda14cbcSMatt Macy } 133eda14cbcSMatt Macy 13416038816SMartin Matuska /* Update the VFS's cache of mountpoint properties */ 13516038816SMartin Matuska void 13616038816SMartin Matuska zfs_ioctl_update_mount_cache(const char *dsname) 13716038816SMartin Matuska { 13816038816SMartin Matuska zfsvfs_t *zfsvfs; 13916038816SMartin Matuska 14016038816SMartin Matuska if (getzfsvfs(dsname, &zfsvfs) == 0) { 14116038816SMartin Matuska struct mount *mp = zfsvfs->z_vfs; 14216038816SMartin Matuska VFS_STATFS(mp, &mp->mnt_stat); 14316038816SMartin Matuska zfs_vfs_rele(zfsvfs); 14416038816SMartin Matuska } 14516038816SMartin Matuska /* 14616038816SMartin Matuska * Ignore errors; we can't do anything useful if either getzfsvfs or 14716038816SMartin Matuska * VFS_STATFS fails. 14816038816SMartin Matuska */ 14916038816SMartin Matuska } 15016038816SMartin Matuska 151eda14cbcSMatt Macy uint64_t 152eda14cbcSMatt Macy zfs_max_nvlist_src_size_os(void) 153eda14cbcSMatt Macy { 154eda14cbcSMatt Macy if (zfs_max_nvlist_src_size != 0) 155eda14cbcSMatt Macy return (zfs_max_nvlist_src_size); 156eda14cbcSMatt Macy 157eda14cbcSMatt Macy return (ptob(vm_page_max_user_wired) / 4); 158eda14cbcSMatt Macy } 159eda14cbcSMatt Macy 160eda14cbcSMatt Macy void 161eda14cbcSMatt Macy zfs_ioctl_init_os(void) 162eda14cbcSMatt Macy { 163eda14cbcSMatt Macy zfs_ioctl_register_dataset_nolog(ZFS_IOC_JAIL, zfs_ioc_jail, 164eda14cbcSMatt Macy zfs_secpolicy_config, POOL_CHECK_NONE); 165eda14cbcSMatt Macy zfs_ioctl_register_dataset_nolog(ZFS_IOC_UNJAIL, zfs_ioc_unjail, 166eda14cbcSMatt Macy zfs_secpolicy_config, POOL_CHECK_NONE); 167eda14cbcSMatt Macy zfs_ioctl_register("fbsd_nextboot", ZFS_IOC_NEXTBOOT, 168eda14cbcSMatt Macy zfs_ioc_nextboot, zfs_secpolicy_config, NO_NAME, 169eda14cbcSMatt Macy POOL_CHECK_NONE, B_FALSE, B_FALSE, zfs_keys_nextboot, 3); 170eda14cbcSMatt Macy 171eda14cbcSMatt Macy } 172