static int
imgmgr_state_confirm(void)
{
    int rc;

    /* Confirm disallowed if a test is pending. */
    if (imgmgr_state_any_pending()) {
        return MGMT_ERR_EBADSTATE;
    }

    /* Confirm the unified image or loader in slot 0. */
    rc = boot_set_confirmed();
    if (rc != 0) {
        return MGMT_ERR_EUNKNOWN;
    }

    /* If a split app in slot 1 is active, confirm it as well. */
    if (split_app_active_get()) {
        rc = split_write_split(SPLIT_MODE_APP);
        if (rc != 0) {
            return MGMT_ERR_EUNKNOWN;
        }
    } else {
        rc = split_write_split(SPLIT_MODE_LOADER);
        if (rc != 0) {
            return MGMT_ERR_EUNKNOWN;
        }
    }

    return 0;
}
Example #2
0
/**
 * This validates and provides the loader image data
 *
 * @return                      0 on success; nonzero on failure.
 */
int
split_app_go(void **entry, int toboot)
{
    split_mode_t split_mode;
    int run_app;
    int rc;

    if (toboot) {
        split_mode = split_mode_get();

        /* if we are told not to, then we don't boot an app */
        if (split_mode == SPLIT_MODE_LOADER) {
            return -1;
        }

        /* if this is a one-time test, reset the split mode */
        switch (split_mode) {
        case SPLIT_MODE_LOADER:
            run_app = 0;
            break;

        case SPLIT_MODE_TEST_APP:
            split_write_split(SPLIT_MODE_LOADER);
            run_app = 1;
            break;

        case SPLIT_MODE_TEST_LOADER:
            split_write_split(SPLIT_MODE_APP);
            run_app = 0;
            break;

        case SPLIT_MODE_APP:
            run_app = 1;
            break;

        default:
            run_app = 0;
            break;
        }

        if (!run_app) {
            return -1;
        }
    }

    rc = split_go(LOADER_IMAGE_SLOT, SPLIT_IMAGE_SLOT, entry);
    if (rc != 0) {
        /* Images don't match; clear split status. */
        split_write_split(SPLIT_MODE_LOADER);
    }

    return rc;
}
int
imgmgr_state_test_slot(int slot)
{
    uint32_t image_flags;
    uint8_t state_flags;
    int split_app_active;
    int rc;

    state_flags = imgmgr_state_flags(slot);
    split_app_active = split_app_active_get();

    /* Unconfirmed slots are always testable.  A confirmed slot can only be
     * tested if it is a loader in a split image setup.
     */
    if (state_flags & IMGMGR_STATE_F_CONFIRMED &&
        (slot != 0 || !split_app_active)) {

        return MGMT_ERR_EBADSTATE;
    }

    rc = imgr_read_info(slot, NULL, NULL, &image_flags);
    if (rc != 0) {
        return MGMT_ERR_EUNKNOWN;
    }

    if (!(image_flags & IMAGE_F_NON_BOOTABLE)) {
        /* Unified image or loader. */
        if (!split_app_active) {
            /* No change in split status. */
            rc = boot_set_pending();
            if (rc != 0) {
                return MGMT_ERR_EUNKNOWN;
            }
        } else {
            /* Currently loader + app; testing loader-only. */
            rc = split_write_split(SPLIT_MODE_TEST_LOADER);
        }
    } else {
        /* Testing split app. */
        rc = split_write_split(SPLIT_MODE_TEST_APP);
        if (rc != 0) {
            return MGMT_ERR_EUNKNOWN;
        }
    }

    return 0;
}