Esempio n. 1
0
int vrt_rdev_replace(struct vrt_realdev *rdev, const exa_uuid_t *new_rdev_uuid)
{
    blockdevice_t *new_blockdevice;
    int err;

    if (rdev_is_ok(rdev))
    {
        exalog_error("Bad rdev status %d", rdev_get_compound_status(rdev));
        return -VRT_ERR_CANT_DGDISKRECOVER;
    }

    new_blockdevice = client_get_blockdevice(new_rdev_uuid);
    if (new_blockdevice == NULL)
    {
        exalog_error("Could not open device "UUID_FMT, UUID_VAL(new_rdev_uuid));
        return -ENODEV;
    }

    if (__get_block_aligned_bdev_size(new_blockdevice)
            < __get_block_aligned_bdev_size(rdev->blockdevice))
        return -VRT_ERR_RDEV_TOO_SMALL;

    rdev->blockdevice = new_blockdevice;

    /* re-open the superblock stream */
    vrt_rdev_close_superblock_streams(rdev);
    err = vrt_rdev_open_superblock_streams(rdev);
    if (err != 0)
        return err;

    uuid_copy(&rdev->nbd_uuid, new_rdev_uuid);

    return EXA_SUCCESS;
}
Esempio n. 2
0
exa_bool_t rain1_rdev_is_writable(const rain1_group_t *rxg, const struct vrt_realdev *rdev)
{
    const rain1_realdev_t *lr = RAIN1_REALDEV(rxg, rdev);
    sync_tag_t sync_tag = rxg->sync_tag;

    return rdev_is_ok(rdev)
        && (rain1_rdev_is_uptodate(lr, sync_tag) || rain1_rdev_is_updating(lr));
}
Esempio n. 3
0
/**
 * Predicate -- Does a SPOF group needs to be updated?
 *
 * @param[in] rxg         the group layout
 * @param[in] spof_group  SPOF group to check
 *
 * @return true if the SPOF group needs to be updated.
 */
static bool spof_group_needs_updating(const rain1_group_t *rxg,
                                      const spof_group_t *spof_group)
{
    uint32_t i;

    for (i = 0; i < spof_group->nb_realdevs; i++)
    {
        const struct vrt_realdev *rdev = spof_group->realdevs[i];
        const rain1_realdev_t *lr = RAIN1_REALDEV(rxg, rdev);
        sync_tag_t sync_tag = rxg->sync_tag;

        if (rdev_is_ok(rdev) && !rain1_rdev_is_uptodate(lr, sync_tag))
            return true;
    }

    return false;
}
Esempio n. 4
0
/**
 * Tells that a unusable device is now available again. We'll put it
 * in the EXA_REALDEV_UPDATING state, which doesn't mean we can safely
 * use it, but that a rebuilding process must take place before
 * changing the status to EXA_REALDEV_OK.
 *
 * @param[in] rdev       The real device which is now available again
 *
 * @return    always EXA_SUCCESS
 */
int
vrt_rdev_up(struct vrt_realdev *rdev)
{
    uint64_t size;
    uint64_t required_size;
    int err;

    /* Admind can send an up message even if the device is not down */
    if (rdev_is_ok(rdev))
        return EXA_SUCCESS;

    rdev->up = TRUE;

    size = __get_block_aligned_bdev_size(rdev->blockdevice);
    err = vrt_rdev_set_real_size(rdev, size);
    if (err != EXA_SUCCESS)
        return err;

    /* Check that the size of the device correspond to the real size of the
     * device.
     * This test is also done at group start (see vrt_group_start)
     *
     * FIXME: This kind of verification could be done by the service in
     * charge of the devices
     */
    required_size = rdev_chunk_based_size(rdev);
    if (vrt_realdev_get_usable_size(rdev) < required_size)
    {
        /* XXX Duplicate: same error in vrt_group_start() */
        exalog_error("Real size of device "UUID_FMT" is too small: %"PRIu64" < %"PRIu64,
                     UUID_VAL(&rdev->uuid), vrt_realdev_get_usable_size(rdev),
                     required_size);
        rdev->corrupted = TRUE;
        rdev->real_size = 0;

        return EXA_SUCCESS;
    }

    rdev->corrupted = FALSE;


    return EXA_SUCCESS;
}
Esempio n. 5
0
bool rain1_spof_group_has_defect(const rain1_group_t *rxg, const spof_group_t *spof_group)
{
    size_t i;

    /* The SPOF group has defect if any of its devices... */
    for (i = 0; i < spof_group->nb_realdevs; i++)
    {
	const struct vrt_realdev *rdev = spof_group->realdevs[i];
        const rain1_realdev_t *lr = RAIN1_REALDEV(rxg, rdev);
        sync_tag_t sync_tag = rxg->sync_tag;

	/* ... is down or corrupted */
	if (! rdev_is_ok(rdev))
	    return true;

	/* ... or is not up-to-date */
	if (!rain1_rdev_is_uptodate(lr, sync_tag))
	    return true;
    }
    return false;
}
Esempio n. 6
0
/**
 * Prepare an updating operation
 *
 * @param[in]  ag                assembly group
 * @param[in]  lg                rain1 group data
 * @param[in] spof_group         The SPOF group to update
 */
static void rain1_group_prepare_updating(const struct assembly_group *ag,
                                         const rain1_group_t *lg,
                                         const spof_group_t *spof_group)
{
    uint32_t i;

    for (i = 0; i < spof_group->nb_realdevs; i++)
    {
        struct vrt_realdev *rdev = spof_group->realdevs[i];
        struct rain1_realdev *lr = RAIN1_REALDEV(lg, rdev);

        if (rdev_is_ok(rdev) && !rain1_rdev_is_uptodate(lr, lg->sync_tag))
        {
            exalog_debug("New updating: update disk: index = %d, UUID = " UUID_FMT,
                         rdev->index, UUID_VAL(&rdev->uuid));

            rain1_rdev_init_rebuild_context(lr, EXA_RDEV_REBUILD_UPDATING,
                                            lg->sync_tag);
        }
    }
}