mirror of
https://git.proxmox.com/git/mirror_zfs.git
synced 2024-12-25 02:49:32 +03:00
Remove custom root pool import code
Non-Linux OpenZFS implementations require additional support to be used a root pool. This code should simply be removed to avoid confusion and improve readability. Signed-off-by: Brian Behlendorf <behlendorf1@llnl.gov> Signed-off-by: Chunwei Chen <david.chen@osnexus.com> Closes #4951
This commit is contained in:
parent
cf41432c70
commit
e5fe9ddeec
@ -37,11 +37,5 @@ typedef struct vdev_disk {
|
|||||||
struct block_device *vd_bdev;
|
struct block_device *vd_bdev;
|
||||||
} vdev_disk_t;
|
} vdev_disk_t;
|
||||||
|
|
||||||
#ifndef __linux__
|
|
||||||
extern int vdev_disk_physio(struct block_device *, caddr_t,
|
|
||||||
size_t, uint64_t, int);
|
|
||||||
extern int vdev_disk_read_rootlabel(char *, char *, nvlist_t **);
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#endif /* _KERNEL */
|
#endif /* _KERNEL */
|
||||||
#endif /* _SYS_VDEV_DISK_H */
|
#endif /* _SYS_VDEV_DISK_H */
|
||||||
|
205
module/zfs/spa.c
205
module/zfs/spa.c
@ -3971,211 +3971,6 @@ spa_create(const char *pool, nvlist_t *nvroot, nvlist_t *props,
|
|||||||
return (0);
|
return (0);
|
||||||
}
|
}
|
||||||
|
|
||||||
#if defined(_KERNEL) && !defined(__linux__)
|
|
||||||
/*
|
|
||||||
* Get the root pool information from the root disk, then import the root pool
|
|
||||||
* during the system boot up time.
|
|
||||||
*/
|
|
||||||
extern int vdev_disk_read_rootlabel(char *, char *, nvlist_t **);
|
|
||||||
|
|
||||||
static nvlist_t *
|
|
||||||
spa_generate_rootconf(char *devpath, char *devid, uint64_t *guid)
|
|
||||||
{
|
|
||||||
nvlist_t *config;
|
|
||||||
nvlist_t *nvtop, *nvroot;
|
|
||||||
uint64_t pgid;
|
|
||||||
|
|
||||||
if (vdev_disk_read_rootlabel(devpath, devid, &config) != 0)
|
|
||||||
return (NULL);
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Add this top-level vdev to the child array.
|
|
||||||
*/
|
|
||||||
VERIFY(nvlist_lookup_nvlist(config, ZPOOL_CONFIG_VDEV_TREE,
|
|
||||||
&nvtop) == 0);
|
|
||||||
VERIFY(nvlist_lookup_uint64(config, ZPOOL_CONFIG_POOL_GUID,
|
|
||||||
&pgid) == 0);
|
|
||||||
VERIFY(nvlist_lookup_uint64(config, ZPOOL_CONFIG_GUID, guid) == 0);
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Put this pool's top-level vdevs into a root vdev.
|
|
||||||
*/
|
|
||||||
VERIFY(nvlist_alloc(&nvroot, NV_UNIQUE_NAME, KM_SLEEP) == 0);
|
|
||||||
VERIFY(nvlist_add_string(nvroot, ZPOOL_CONFIG_TYPE,
|
|
||||||
VDEV_TYPE_ROOT) == 0);
|
|
||||||
VERIFY(nvlist_add_uint64(nvroot, ZPOOL_CONFIG_ID, 0ULL) == 0);
|
|
||||||
VERIFY(nvlist_add_uint64(nvroot, ZPOOL_CONFIG_GUID, pgid) == 0);
|
|
||||||
VERIFY(nvlist_add_nvlist_array(nvroot, ZPOOL_CONFIG_CHILDREN,
|
|
||||||
&nvtop, 1) == 0);
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Replace the existing vdev_tree with the new root vdev in
|
|
||||||
* this pool's configuration (remove the old, add the new).
|
|
||||||
*/
|
|
||||||
VERIFY(nvlist_add_nvlist(config, ZPOOL_CONFIG_VDEV_TREE, nvroot) == 0);
|
|
||||||
nvlist_free(nvroot);
|
|
||||||
return (config);
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Walk the vdev tree and see if we can find a device with "better"
|
|
||||||
* configuration. A configuration is "better" if the label on that
|
|
||||||
* device has a more recent txg.
|
|
||||||
*/
|
|
||||||
static void
|
|
||||||
spa_alt_rootvdev(vdev_t *vd, vdev_t **avd, uint64_t *txg)
|
|
||||||
{
|
|
||||||
int c;
|
|
||||||
|
|
||||||
for (c = 0; c < vd->vdev_children; c++)
|
|
||||||
spa_alt_rootvdev(vd->vdev_child[c], avd, txg);
|
|
||||||
|
|
||||||
if (vd->vdev_ops->vdev_op_leaf) {
|
|
||||||
nvlist_t *label;
|
|
||||||
uint64_t label_txg;
|
|
||||||
|
|
||||||
if (vdev_disk_read_rootlabel(vd->vdev_physpath, vd->vdev_devid,
|
|
||||||
&label) != 0)
|
|
||||||
return;
|
|
||||||
|
|
||||||
VERIFY(nvlist_lookup_uint64(label, ZPOOL_CONFIG_POOL_TXG,
|
|
||||||
&label_txg) == 0);
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Do we have a better boot device?
|
|
||||||
*/
|
|
||||||
if (label_txg > *txg) {
|
|
||||||
*txg = label_txg;
|
|
||||||
*avd = vd;
|
|
||||||
}
|
|
||||||
nvlist_free(label);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Import a root pool.
|
|
||||||
*
|
|
||||||
* For x86. devpath_list will consist of devid and/or physpath name of
|
|
||||||
* the vdev (e.g. "id1,sd@SSEAGATE..." or "/pci@1f,0/ide@d/disk@0,0:a").
|
|
||||||
* The GRUB "findroot" command will return the vdev we should boot.
|
|
||||||
*
|
|
||||||
* For Sparc, devpath_list consists the physpath name of the booting device
|
|
||||||
* no matter the rootpool is a single device pool or a mirrored pool.
|
|
||||||
* e.g.
|
|
||||||
* "/pci@1f,0/ide@d/disk@0,0:a"
|
|
||||||
*/
|
|
||||||
int
|
|
||||||
spa_import_rootpool(char *devpath, char *devid)
|
|
||||||
{
|
|
||||||
spa_t *spa;
|
|
||||||
vdev_t *rvd, *bvd, *avd = NULL;
|
|
||||||
nvlist_t *config, *nvtop;
|
|
||||||
uint64_t guid, txg;
|
|
||||||
char *pname;
|
|
||||||
int error;
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Read the label from the boot device and generate a configuration.
|
|
||||||
*/
|
|
||||||
config = spa_generate_rootconf(devpath, devid, &guid);
|
|
||||||
#if defined(_OBP) && defined(_KERNEL)
|
|
||||||
if (config == NULL) {
|
|
||||||
if (strstr(devpath, "/iscsi/ssd") != NULL) {
|
|
||||||
/* iscsi boot */
|
|
||||||
get_iscsi_bootpath_phy(devpath);
|
|
||||||
config = spa_generate_rootconf(devpath, devid, &guid);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
if (config == NULL) {
|
|
||||||
cmn_err(CE_NOTE, "Cannot read the pool label from '%s'",
|
|
||||||
devpath);
|
|
||||||
return (SET_ERROR(EIO));
|
|
||||||
}
|
|
||||||
|
|
||||||
VERIFY(nvlist_lookup_string(config, ZPOOL_CONFIG_POOL_NAME,
|
|
||||||
&pname) == 0);
|
|
||||||
VERIFY(nvlist_lookup_uint64(config, ZPOOL_CONFIG_POOL_TXG, &txg) == 0);
|
|
||||||
|
|
||||||
mutex_enter(&spa_namespace_lock);
|
|
||||||
if ((spa = spa_lookup(pname)) != NULL) {
|
|
||||||
/*
|
|
||||||
* Remove the existing root pool from the namespace so that we
|
|
||||||
* can replace it with the correct config we just read in.
|
|
||||||
*/
|
|
||||||
spa_remove(spa);
|
|
||||||
}
|
|
||||||
|
|
||||||
spa = spa_add(pname, config, NULL);
|
|
||||||
spa->spa_is_root = B_TRUE;
|
|
||||||
spa->spa_import_flags = ZFS_IMPORT_VERBATIM;
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Build up a vdev tree based on the boot device's label config.
|
|
||||||
*/
|
|
||||||
VERIFY(nvlist_lookup_nvlist(config, ZPOOL_CONFIG_VDEV_TREE,
|
|
||||||
&nvtop) == 0);
|
|
||||||
spa_config_enter(spa, SCL_ALL, FTAG, RW_WRITER);
|
|
||||||
error = spa_config_parse(spa, &rvd, nvtop, NULL, 0,
|
|
||||||
VDEV_ALLOC_ROOTPOOL);
|
|
||||||
spa_config_exit(spa, SCL_ALL, FTAG);
|
|
||||||
if (error) {
|
|
||||||
mutex_exit(&spa_namespace_lock);
|
|
||||||
nvlist_free(config);
|
|
||||||
cmn_err(CE_NOTE, "Can not parse the config for pool '%s'",
|
|
||||||
pname);
|
|
||||||
return (error);
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Get the boot vdev.
|
|
||||||
*/
|
|
||||||
if ((bvd = vdev_lookup_by_guid(rvd, guid)) == NULL) {
|
|
||||||
cmn_err(CE_NOTE, "Can not find the boot vdev for guid %llu",
|
|
||||||
(u_longlong_t)guid);
|
|
||||||
error = SET_ERROR(ENOENT);
|
|
||||||
goto out;
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Determine if there is a better boot device.
|
|
||||||
*/
|
|
||||||
avd = bvd;
|
|
||||||
spa_alt_rootvdev(rvd, &avd, &txg);
|
|
||||||
if (avd != bvd) {
|
|
||||||
cmn_err(CE_NOTE, "The boot device is 'degraded'. Please "
|
|
||||||
"try booting from '%s'", avd->vdev_path);
|
|
||||||
error = SET_ERROR(EINVAL);
|
|
||||||
goto out;
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
|
||||||
* If the boot device is part of a spare vdev then ensure that
|
|
||||||
* we're booting off the active spare.
|
|
||||||
*/
|
|
||||||
if (bvd->vdev_parent->vdev_ops == &vdev_spare_ops &&
|
|
||||||
!bvd->vdev_isspare) {
|
|
||||||
cmn_err(CE_NOTE, "The boot device is currently spared. Please "
|
|
||||||
"try booting from '%s'",
|
|
||||||
bvd->vdev_parent->
|
|
||||||
vdev_child[bvd->vdev_parent->vdev_children - 1]->vdev_path);
|
|
||||||
error = SET_ERROR(EINVAL);
|
|
||||||
goto out;
|
|
||||||
}
|
|
||||||
|
|
||||||
error = 0;
|
|
||||||
out:
|
|
||||||
spa_config_enter(spa, SCL_ALL, FTAG, RW_WRITER);
|
|
||||||
vdev_free(rvd);
|
|
||||||
spa_config_exit(spa, SCL_ALL, FTAG);
|
|
||||||
mutex_exit(&spa_namespace_lock);
|
|
||||||
|
|
||||||
nvlist_free(config);
|
|
||||||
return (error);
|
|
||||||
}
|
|
||||||
|
|
||||||
#endif /* defined(_KERNEL) && !defined(__linux__) */
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Import a non-root pool into the system.
|
* Import a non-root pool into the system.
|
||||||
*/
|
*/
|
||||||
|
@ -602,16 +602,6 @@ retry:
|
|||||||
return (error);
|
return (error);
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifndef __linux__
|
|
||||||
int
|
|
||||||
vdev_disk_physio(struct block_device *bdev, caddr_t kbuf,
|
|
||||||
size_t size, uint64_t offset, int rw, int flags)
|
|
||||||
{
|
|
||||||
bio_set_flags_failfast(bdev, &flags);
|
|
||||||
return (__vdev_disk_physio(bdev, NULL, kbuf, size, offset, rw, flags));
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
BIO_END_IO_PROTO(vdev_disk_io_flush_completion, bio, rc)
|
BIO_END_IO_PROTO(vdev_disk_io_flush_completion, bio, rc)
|
||||||
{
|
{
|
||||||
zio_t *zio = bio->bi_private;
|
zio_t *zio = bio->bi_private;
|
||||||
@ -798,71 +788,5 @@ vdev_ops_t vdev_disk_ops = {
|
|||||||
B_TRUE /* leaf vdev */
|
B_TRUE /* leaf vdev */
|
||||||
};
|
};
|
||||||
|
|
||||||
#ifndef __linux__
|
|
||||||
/*
|
|
||||||
* Given the root disk device devid or pathname, read the label from
|
|
||||||
* the device, and construct a configuration nvlist.
|
|
||||||
*/
|
|
||||||
int
|
|
||||||
vdev_disk_read_rootlabel(char *devpath, char *devid, nvlist_t **config)
|
|
||||||
{
|
|
||||||
struct block_device *bdev;
|
|
||||||
vdev_label_t *label;
|
|
||||||
uint64_t s, size;
|
|
||||||
int i;
|
|
||||||
|
|
||||||
bdev = vdev_bdev_open(devpath, vdev_bdev_mode(FREAD), zfs_vdev_holder);
|
|
||||||
if (IS_ERR(bdev))
|
|
||||||
return (-PTR_ERR(bdev));
|
|
||||||
|
|
||||||
s = bdev_capacity(bdev);
|
|
||||||
if (s == 0) {
|
|
||||||
vdev_bdev_close(bdev, vdev_bdev_mode(FREAD));
|
|
||||||
return (EIO);
|
|
||||||
}
|
|
||||||
|
|
||||||
size = P2ALIGN_TYPED(s, sizeof (vdev_label_t), uint64_t);
|
|
||||||
label = vmem_alloc(sizeof (vdev_label_t), KM_SLEEP);
|
|
||||||
|
|
||||||
for (i = 0; i < VDEV_LABELS; i++) {
|
|
||||||
uint64_t offset, state, txg = 0;
|
|
||||||
|
|
||||||
/* read vdev label */
|
|
||||||
offset = vdev_label_offset(size, i, 0);
|
|
||||||
if (vdev_disk_physio(bdev, (caddr_t)label,
|
|
||||||
VDEV_SKIP_SIZE + VDEV_PHYS_SIZE, offset, READ,
|
|
||||||
REQ_SYNC) != 0)
|
|
||||||
continue;
|
|
||||||
|
|
||||||
if (nvlist_unpack(label->vl_vdev_phys.vp_nvlist,
|
|
||||||
sizeof (label->vl_vdev_phys.vp_nvlist), config, 0) != 0) {
|
|
||||||
*config = NULL;
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (nvlist_lookup_uint64(*config, ZPOOL_CONFIG_POOL_STATE,
|
|
||||||
&state) != 0 || state >= POOL_STATE_DESTROYED) {
|
|
||||||
nvlist_free(*config);
|
|
||||||
*config = NULL;
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (nvlist_lookup_uint64(*config, ZPOOL_CONFIG_POOL_TXG,
|
|
||||||
&txg) != 0 || txg == 0) {
|
|
||||||
nvlist_free(*config);
|
|
||||||
*config = NULL;
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
vmem_free(label, sizeof (vdev_label_t));
|
|
||||||
vdev_bdev_close(bdev, vdev_bdev_mode(FREAD));
|
|
||||||
|
|
||||||
return (0);
|
|
||||||
}
|
|
||||||
#endif /* __linux__ */
|
|
||||||
|
|
||||||
module_param(zfs_vdev_scheduler, charp, 0644);
|
module_param(zfs_vdev_scheduler, charp, 0644);
|
||||||
MODULE_PARM_DESC(zfs_vdev_scheduler, "I/O scheduler");
|
MODULE_PARM_DESC(zfs_vdev_scheduler, "I/O scheduler");
|
||||||
|
Loading…
Reference in New Issue
Block a user