/*
 * Read bootenv from ubi volume
 */
static int
ubi_write_bootenv(uint32_t devno, uint32_t id, bootenv_t env)
{
	libubi_t ulib;
	int rc = 0;
	char path[PATH_MAX];
	FILE* fp_out = NULL;
	size_t nbytes;

	rc = bootenv_size(env, &nbytes);
	if (rc) {
		err_msg("Cannot determine size of bootenv structure\n");
		return rc;
	}
	ulib = libubi_open();
	if (ulib == NULL) {
		err_msg("Cannot allocate ubi structure\n");
		return rc;
	}

	snprintf(path, PATH_MAX, DEFAULT_VOL_PATTERN, devno, id);

	fp_out = fopen(path, "r+");
	if (fp_out == NULL) {
		err_msg("Cannot fopen volume:%d number:%d\n", devno, id);
		rc = -EBADF;
		goto err;
	}

	rc = ubi_update_start(ulib, fileno(fp_out), nbytes);
	if (rc != 0) {
		err_msg("Cannot start update for %s\n", path);
		goto err;
	}

	rc = bootenv_write(fp_out, env);
	if (rc != 0) {
		err_msg("Cannot write bootenv to volume %d number:%d\n",
			devno, id);
		goto err;
	}
err:
	if( fp_out )
		fclose(fp_out);
	libubi_close(ulib);
	return rc;
}
コード例 #2
0
ファイル: libpfiflash.c プロジェクト: mobilipia/iods
/**
 * write_bootenv_volume - writes data from PFI file int to bootenv UBI volume
 * @devno	UBI device number
 * @id		UBI volume id
 * @bootend_old	old PDD data from machine
 * @pdd_f	function to handle PDD with
 * @fp_in	new pdd data contained in PFI
 * @fp_in_size	data size of new pdd data in PFI
 * @pfi_crc	crc value from PFI header
 *
 * Error handling:
 *	when UBI system couldn't be opened
 *	- returns -PFIFLASH_ERR_UBI_OPEN, err_buf matches text to err
 *	when bootenv can't be created
 *	- returns -PFIFLASH_ERR_BOOTENV_CREATE, err_buf matches text to err
 *	when bootenv can't be read
 *	- returns -PFIFLASH_ERR_BOOTENV_READ, err_buf matches text to err
 *	when PDD handling function returns and error
 *	- passes rc and err_buf data
 *	when CRC check fails
 *	- returns -PFIFLASH_ERR_CRC_CHECK, err_buf matches text to err
 *	when bootenv can't be resized
 *	- returns -PFIFLASH_ERR_BOOTENV_SIZE, err_buf matches text to err
 *	when UBI system couldn't open a volume
 *	- returns -PFIFLASH_ERR_UBI_VOL_FOPEN, err_buf matches text to err
 *	when couldn't write bootenv data
 *	- returns -PFIFLASH_ERR_BOOTENV_WRITE, err_buf matches text to err
 **/
static int
write_bootenv_volume(int devno, uint32_t id, bootenv_t bootenv_old,
		     pdd_func_t pdd_f, FILE* fp_in, size_t fp_in_size,
		     uint32_t pfi_crc,
		     char *err_buf, size_t err_buf_size)
{
	int rc, warnings;
	uint32_t crc;
	size_t update_size;
	FILE *fp_out;
	bootenv_t bootenv_new, bootenv_res;
	ubi_lib_t ulib;

	rc = 0;
	warnings = 0;
	crc = 0;
	update_size = 0;
	fp_out = NULL;
	bootenv_new = NULL;
	bootenv_res = NULL;
	ulib = NULL;

	log_msg("[ ubiupdatevol bootenv id=%d, fp_in=%p", id, fp_in);

	/* Workflow:
	 * 1. Apply PDD operation and get the size of the returning
	 *    bootenv_res section. Without the correct size it wouldn't
	 *    be possible to call UBI update vol.
	 * 2. Call UBI update vol
	 * 3. Get FILE* to vol dev
	 * 4. Write to FILE*
	 */

	rc = ubi_open(&ulib);
	if (rc != 0) {
		rc = -PFIFLASH_ERR_UBI_OPEN;
		EBUF(PFIFLASH_ERRSTR[-rc]);
		goto err;
	}

	rc = bootenv_create(&bootenv_new);
	if (rc != 0) {
		rc = -PFIFLASH_ERR_BOOTENV_CREATE;
		EBUF(PFIFLASH_ERRSTR[-rc], " 'new'");
		goto err;
	}

	rc = bootenv_create(&bootenv_res);
	if (rc != 0) {
		rc = -PFIFLASH_ERR_BOOTENV_CREATE;
		EBUF(PFIFLASH_ERRSTR[-rc], " 'res'");
		goto err;
	}

	rc = bootenv_read_crc(fp_in, bootenv_new, fp_in_size, &crc);
	if (rc != 0) {
		rc = -PFIFLASH_ERR_BOOTENV_READ;
		EBUF(PFIFLASH_ERRSTR[-rc]);
		goto err;
	} else if (crc != pfi_crc) {
		rc = -PFIFLASH_ERR_CRC_CHECK;
		EBUF(PFIFLASH_ERRSTR[-rc], pfi_crc, crc);
		goto err;
	}

	rc = pdd_f(bootenv_old, bootenv_new, &bootenv_res, &warnings,
		   err_buf, err_buf_size);
	if (rc != 0) {
		EBUF_PREPEND("handling PDD");
		goto err;
	}
	else if (warnings)
		/* TODO do something with warnings */
		dbg_msg("A warning in the PDD operation occured: %d",
			warnings);

	rc = bootenv_size(bootenv_res, &update_size);
	if (rc != 0) {
		rc = -PFIFLASH_ERR_BOOTENV_SIZE;
		EBUF(PFIFLASH_ERRSTR[-rc]);
		goto err;
	}

	fp_out = ubi_vol_fopen_update(ulib, devno, id, update_size);
	if (!fp_out) {
		rc = -PFIFLASH_ERR_UBI_VOL_FOPEN;
		EBUF(PFIFLASH_ERRSTR[-rc], id);
		goto err;
	}

	rc = bootenv_write(fp_out, bootenv_res);
	if (rc != 0) {
		rc = -PFIFLASH_ERR_BOOTENV_WRITE;
		EBUF(PFIFLASH_ERRSTR[-rc], devno, id);
		goto err;
	}

 err:
	if (ulib != NULL)
		ubi_close(&ulib);
	if (bootenv_new != NULL)
		bootenv_destroy(&bootenv_new);
	if (bootenv_res != NULL)
		bootenv_destroy(&bootenv_res);
	if (fp_out)
		fclose(fp_out);

	return rc;
}