Changeset View
Changeset View
Standalone View
Standalone View
sys/cddl/contrib/opensolaris/uts/common/fs/zfs/zfs_ioctl.c
Show First 20 Lines • Show All 207 Lines • ▼ Show 20 Lines | |||||
#include <sys/dsl_bookmark.h> | #include <sys/dsl_bookmark.h> | ||||
#include <sys/dsl_userhold.h> | #include <sys/dsl_userhold.h> | ||||
#include <sys/zfeature.h> | #include <sys/zfeature.h> | ||||
#include <sys/zcp.h> | #include <sys/zcp.h> | ||||
#include <sys/zio_checksum.h> | #include <sys/zio_checksum.h> | ||||
#include <sys/vdev_removal.h> | #include <sys/vdev_removal.h> | ||||
#include <sys/vdev_impl.h> | #include <sys/vdev_impl.h> | ||||
#include <sys/vdev_initialize.h> | #include <sys/vdev_initialize.h> | ||||
#include <sys/zfs_bootenv.h> | |||||
#include "zfs_namecheck.h" | #include "zfs_namecheck.h" | ||||
#include "zfs_prop.h" | #include "zfs_prop.h" | ||||
#include "zfs_deleg.h" | #include "zfs_deleg.h" | ||||
#include "zfs_comutil.h" | #include "zfs_comutil.h" | ||||
#include "zfs_ioctl_compat.h" | #include "zfs_ioctl_compat.h" | ||||
#include "lua.h" | #include "lua.h" | ||||
▲ Show 20 Lines • Show All 3,428 Lines • ▼ Show 20 Lines | zfs_ioc_log_history(const char *unused, nvlist_t *innvl, nvlist_t *outnvl) | ||||
error = spa_history_log(spa, message); | error = spa_history_log(spa, message); | ||||
spa_close(spa, FTAG); | spa_close(spa, FTAG); | ||||
return (error); | return (error); | ||||
} | } | ||||
/* | /* | ||||
* This ioctl is used to set the bootenv configuration on the current | * This ioctl is used to set the bootenv configuration on the current | ||||
* pool. This configuration is stored in the second padding area of the label, | * pool. This configuration is stored in the second padding area of the label, | ||||
* and it is used by the GRUB bootloader used on Linux to store the contents | * and it is used by the bootloader(s) to store bootloader and/or system | ||||
* of the grubenv file. The file is stored as raw ASCII, and is protected by | * specific data. | ||||
* an embedded checksum. By default, GRUB will check if the boot filesystem | * The data is stored as nvlist data stream, and is protected by | ||||
* supports storing the environment data in a special location, and if so, | * an embedded checksum. | ||||
* will invoke filesystem specific logic to retrieve it. This can be overriden | |||||
* by a variable, should the user so desire. | |||||
*/ | */ | ||||
/* ARGSUSED */ | /* ARGSUSED */ | ||||
static const zfs_ioc_key_t zfs_keys_set_bootenv[] = { | static const zfs_ioc_key_t zfs_keys_set_bootenv[] = { | ||||
{"envmap", DATA_TYPE_STRING, 0}, | {BOOTENV_VERSION, DATA_TYPE_UINT64, 0}, | ||||
{"<keys>", DATA_TYPE_ANY, ZK_OPTIONAL | ZK_WILDCARDLIST}, | |||||
}; | }; | ||||
static int | static int | ||||
zfs_ioc_set_bootenv(const char *name, nvlist_t *innvl, nvlist_t *outnvl) | zfs_ioc_set_bootenv(const char *name, nvlist_t *innvl, nvlist_t *outnvl) | ||||
{ | { | ||||
char *envmap; | |||||
int error; | int error; | ||||
spa_t *spa; | spa_t *spa; | ||||
envmap = fnvlist_lookup_string(innvl, "envmap"); | |||||
if ((error = spa_open(name, &spa, FTAG)) != 0) | if ((error = spa_open(name, &spa, FTAG)) != 0) | ||||
return (error); | return (error); | ||||
spa_vdev_state_enter(spa, SCL_ALL); | spa_vdev_state_enter(spa, SCL_ALL); | ||||
error = vdev_label_write_bootenv(spa->spa_root_vdev, envmap); | error = vdev_label_write_bootenv(spa->spa_root_vdev, innvl); | ||||
(void) spa_vdev_state_exit(spa, NULL, 0); | (void) spa_vdev_state_exit(spa, NULL, 0); | ||||
spa_close(spa, FTAG); | spa_close(spa, FTAG); | ||||
return (error); | return (error); | ||||
} | } | ||||
static const zfs_ioc_key_t zfs_keys_get_bootenv[] = { | static const zfs_ioc_key_t zfs_keys_get_bootenv[] = { | ||||
/* no nvl keys */ | /* no nvl keys */ | ||||
}; | }; | ||||
Show All 11 Lines | zfs_ioc_get_bootenv(const char *name, nvlist_t *innvl, nvlist_t *outnvl) | ||||
error = vdev_label_read_bootenv(spa->spa_root_vdev, outnvl); | error = vdev_label_read_bootenv(spa->spa_root_vdev, outnvl); | ||||
(void) spa_vdev_state_exit(spa, NULL, 0); | (void) spa_vdev_state_exit(spa, NULL, 0); | ||||
spa_close(spa, FTAG); | spa_close(spa, FTAG); | ||||
return (error); | return (error); | ||||
} | } | ||||
#ifdef __FreeBSD__ | #ifdef __FreeBSD__ | ||||
static const zfs_ioc_key_t zfs_keys_nextboot[] = { | static const zfs_ioc_key_t zfs_keys_nextboot[] = { | ||||
{"command", DATA_TYPE_STRING, 0}, | {BOOTENV_VERSION, DATA_TYPE_UINT64, 0}, | ||||
{ZPOOL_CONFIG_POOL_GUID, DATA_TYPE_UINT64, 0}, | {ZPOOL_CONFIG_POOL_GUID, DATA_TYPE_UINT64, 0}, | ||||
{ZPOOL_CONFIG_GUID, DATA_TYPE_UINT64, 0} | {ZPOOL_CONFIG_GUID, DATA_TYPE_UINT64, 0}, | ||||
{FREEBSD_BOOTONCE, DATA_TYPE_STRING, 0}, | |||||
}; | }; | ||||
/* This interface should be deprecated */ | |||||
static int | static int | ||||
zfs_ioc_nextboot(const char *unused, nvlist_t *innvl, nvlist_t *outnvl) | zfs_ioc_nextboot(const char *unused __unused, nvlist_t *innvl, nvlist_t *outnvl) | ||||
{ | { | ||||
char name[MAXNAMELEN]; | char name[MAXNAMELEN]; | ||||
spa_t *spa; | spa_t *spa; | ||||
vdev_t *vd; | |||||
char *command; | |||||
uint64_t pool_guid; | uint64_t pool_guid; | ||||
uint64_t vdev_guid; | uint64_t vdev_guid; | ||||
int error; | int error; | ||||
if (nvlist_lookup_uint64(innvl, | pool_guid = fnvlist_lookup_uint64(innvl, ZPOOL_CONFIG_POOL_GUID); | ||||
ZPOOL_CONFIG_POOL_GUID, &pool_guid) != 0) | vdev_guid = fnvlist_lookup_uint64(innvl, ZPOOL_CONFIG_GUID); | ||||
return (EINVAL); | |||||
if (nvlist_lookup_uint64(innvl, | |||||
ZPOOL_CONFIG_GUID, &vdev_guid) != 0) | |||||
return (EINVAL); | |||||
command = fnvlist_lookup_string(innvl, "command"); | |||||
mutex_enter(&spa_namespace_lock); | mutex_enter(&spa_namespace_lock); | ||||
spa = spa_by_guid(pool_guid, vdev_guid); | spa = spa_by_guid(pool_guid, vdev_guid); | ||||
if (spa != NULL) | if (spa != NULL) | ||||
strcpy(name, spa_name(spa)); | strcpy(name, spa_name(spa)); | ||||
mutex_exit(&spa_namespace_lock); | mutex_exit(&spa_namespace_lock); | ||||
if (spa == NULL) | if (spa == NULL) | ||||
return (ENOENT); | return (ENOENT); | ||||
if ((error = spa_open(name, &spa, FTAG)) != 0) | if ((error = spa_open(name, &spa, FTAG)) != 0) | ||||
return (error); | return (error); | ||||
/* No need to store pool and vdev guids */ | |||||
fnvlist_remove(innvl, ZPOOL_CONFIG_POOL_GUID); | |||||
fnvlist_remove(innvl, ZPOOL_CONFIG_GUID); | |||||
spa_vdev_state_enter(spa, SCL_ALL); | spa_vdev_state_enter(spa, SCL_ALL); | ||||
vd = spa_lookup_by_guid(spa, vdev_guid, B_TRUE); | error = vdev_label_write_bootenv(spa->spa_root_vdev, innvl); | ||||
if (vd == NULL) { | |||||
(void) spa_vdev_state_exit(spa, NULL, ENXIO); | |||||
spa_close(spa, FTAG); | |||||
return (ENODEV); | |||||
} | |||||
error = vdev_label_write_pad2(vd, command, strlen(command)); | |||||
(void) spa_vdev_state_exit(spa, NULL, 0); | (void) spa_vdev_state_exit(spa, NULL, 0); | ||||
txg_wait_synced(spa->spa_dsl_pool, 0); | |||||
spa_close(spa, FTAG); | spa_close(spa, FTAG); | ||||
return (error); | return (error); | ||||
} | } | ||||
#endif | #endif | ||||
/* | /* | ||||
* The dp_config_rwlock must not be held when calling this, because the | * The dp_config_rwlock must not be held when calling this, because the | ||||
* unmount may need to write out data. | * unmount may need to write out data. | ||||
▲ Show 20 Lines • Show All 3,930 Lines • Show Last 20 Lines |