Пример #1
0
static int scan_ubi_device(libubi_t lib_ubi, struct ubi_node *dev)
{
	int lo = dev->info.lowest_vol_id, hi = dev->info.highest_vol_id;
	int i, idx = 0, dev_num = dev->info.dev_num;
	struct ubi_vol_info vol_info;

	if (!dev->info.vol_count)
		return 0;

	dev->vol_info = xcalloc(dev->info.vol_count, sizeof(dev->vol_info[0]));

	for (i = lo; i <= hi; ++i) {
		if (ubi_get_vol_info1(lib_ubi, dev_num, i, &vol_info)) {
			if (errno == ENOENT)
				continue;
			perror("ubi_get_vol_info1");
			return -1;
		}

		dev->vol_info[idx++] = vol_info;
	}

	if (sort_by)
		qsort(dev->vol_info, idx, sizeof(vol_info), compare_ubi_vol);
	return 0;
}
Пример #2
0
int ubi_get_vol_info1_nm(libubi_t desc, int dev_num, const char *name,
			 struct ubi_vol_info *info)
{
	int i, err;
	unsigned int nlen = strlen(name);
	struct ubi_dev_info dev_info;

	if (nlen == 0) {
		errmsg("bad \"name\" input parameter");
		errno = EINVAL;
		return -1;
	}

	err = ubi_get_dev_info1(desc, dev_num, &dev_info);
	if (err)
		return err;

	for (i = dev_info.lowest_vol_id;
	     i <= dev_info.highest_vol_id; i++) {
		err = ubi_get_vol_info1(desc, dev_num, i, info);
		if (err == -1) {
			if (errno == ENOENT)
				continue;
			return -1;
		}

		if (nlen == strlen(info->name) && !strcmp(name, info->name))
			return 0;
	}

	errno = ENOENT;
	return -1;
}
Пример #3
0
static void scan_ubi_volumes(struct mtd_ubi_info *info)
{
	struct flash_description *flash = get_flash_info();
	libubi_t libubi = flash->libubi;
	struct ubi_part *ubi_part;
	int i, err;

	for (i = info->dev_info.lowest_vol_id;
	     i <= info->dev_info.highest_vol_id; i++) {
		ubi_part = (struct ubi_part *)calloc(1, sizeof(struct ubi_part));
		if (!ubi_part) {
			ERROR("No memory: malloc failed\n");
			return;
		}

		err = ubi_get_vol_info1(libubi, info->dev_info.dev_num,
					i, &ubi_part->vol_info);
		if (err == -1) {
			if (errno == ENOENT)
				continue;

			ERROR("libubi failed to probe volume %d on ubi%d",
					  i, info->dev_info.dev_num);
			return;
		}

		LIST_INSERT_HEAD(&info->ubi_partitions, ubi_part, next);
		TRACE("mtd%d:\tVolume found : \t%s",
			info->dev_info.mtd_num,
			ubi_part->vol_info.name);
	}

	info->scanned = 1;
}
/**
 * __check_volume - check volume information.
 *
 * @libubi    libubi descriptor
 * @dev_info  UBI device description
 * @test      test name
 * @func      function name
 * @line      line number
 * @vol_id    ID of existing volume to check
 * @req       volume creation request to compare with
 *
 * This function checks if a volume created using @req request has exactly the
 * requested characteristics. Returns 0 in case of success and %-1 in case of
 * error.
 */
int __check_volume(libubi_t libubi, struct ubi_dev_info *dev_info,
		   const char *test, const char *func, int line, int vol_id,
		   const struct ubi_mkvol_request *req)
{
	int ret;
	struct ubi_vol_info vol_info;
	int leb_size;
	long long rsvd_bytes;

	ret = ubi_get_vol_info1(libubi, dev_info->dev_num, vol_id, &vol_info);
	if (ret) {
		__failed(test, func, line, "ubi_get_vol_info");
		return -1;
	}

	if (req->alignment != vol_info.alignment) {
		__err_msg(test, func, line,
			  "bad alignment: requested %d, got %d",
			  req->alignment, vol_info.alignment);
		return -1;
	}
	if (req->vol_type != vol_info.type) {
		__err_msg(test, func, line, "bad type: requested %d, got %d",
			  req->vol_type, vol_info.type);
		return -1;
	}
	if (strlen(req->name) != strlen(vol_info.name) ||
	    strcmp(req->name, vol_info.name) != 0) {
		__err_msg(test, func, line,
			  "bad name: requested \"%s\", got \"%s\"",
			  req->name, vol_info.name);
		return -1;
	}
	if (vol_info.corrupted) {
		__err_msg(test, func, line, "corrupted new volume");
		return -1;
	}

	leb_size = dev_info->leb_size - (dev_info->leb_size % req->alignment);
	if (leb_size != vol_info.leb_size) {
		__err_msg(test, func, line,
			  "bad usable LEB size %d, should be %d",
			  vol_info.leb_size, leb_size);
		return -1;
	}

	rsvd_bytes = req->bytes;
	if (rsvd_bytes % leb_size)
		rsvd_bytes += leb_size - (rsvd_bytes % leb_size);

	if (rsvd_bytes != vol_info.rsvd_bytes) {
		__err_msg(test, func, line,
			  "bad reserved bytes %lld, should be %lld",
			  vol_info.rsvd_bytes, rsvd_bytes);
		return -1;
	}

	return 0;
}
Пример #5
0
/**
 * mkvol_multiple - test multiple volumes creation
 *
 * Thus function returns %0 if the test passed and %-1 if not.
 */
static int mkvol_multiple(void)
{
	struct ubi_mkvol_request req;
	int i, ret, max = dev_info.max_vol_count;
	const char *name = PROGRAM_NAME ":mkvol_multiple()";

	/* Create maximum number of volumes */
	for (i = 0; i < max; i++) {
		char nm[strlen(name) + 50];

		req.vol_id = UBI_VOL_NUM_AUTO;
		req.alignment = 1;
		req.bytes = 1;
		req.vol_type = UBI_STATIC_VOLUME;

		sprintf(nm, "%s:%d", name, i);
		req.name = nm;

		if (ubi_mkvol(libubi, node, &req)) {
			if (errno == ENFILE) {
				max = i;
				break;
			}
			failed("ubi_mkvol");
			errorm("vol_id %d", i);
			goto remove;
		}

		if (check_volume(req.vol_id, &req)) {
			errorm("vol_id %d", i);
			goto remove;
		}
	}

	for (i = 0; i < max; i++) {
		struct ubi_vol_info vol_info;

		if (ubi_rmvol(libubi, node, i)) {
			failed("ubi_rmvol");
			return -1;
		}

		/* Make sure volume does not exist */
		ret = ubi_get_vol_info1(libubi, dev_info.dev_num, i, &vol_info);
		if (ret == 0) {
			errorm("removed volume %d exists", i);
			goto remove;
		}
	}

	return 0;

remove:
	for (i = 0; i < dev_info.max_vol_count + 1; i++)
		ubi_rmvol(libubi, node, i);
	return -1;
}
Пример #6
0
int ubi_get_vol_info(libubi_t desc, const char *node, struct ubi_vol_info *info)
{
	int vol_id, dev_num;
	struct libubi *lib = (struct libubi *)desc;

	if (vol_node2nums(lib, node, &dev_num, &vol_id))
		return -1;

	return ubi_get_vol_info1(desc, dev_num, vol_id, info);
}
Пример #7
0
int ubi_get_vol_info(libubi_t desc, const char *node, struct ubi_vol_info *info)
{
	int vol_id, dev_num;
	struct libubi *lib = (struct libubi *)desc;

	dev_num = find_dev_num_vol(lib, node);
	if (dev_num == -1)
		return -1;

	vol_id = find_vol_num(lib, dev_num, node);
	if (vol_id == -1)
		return -1;

	return ubi_get_vol_info1(desc, dev_num, vol_id, info);
}
Пример #8
0
int ubi_get_vol_info(libubi_t desc, const char *node, struct ubi_vol_info *info)
{
	int err, vol_id, dev_num;
	struct libubi *lib = (struct libubi *)desc;

	err = ubi_probe_node(desc, node);
	if (err != 2) {
		if (err == 1)
			errno = ENODEV;
		return -1;
	}

	if (vol_node2nums(lib, node, &dev_num, &vol_id))
		return -1;

	return ubi_get_vol_info1(desc, dev_num, vol_id, info);
}
Пример #9
0
static int get_vol_id(libubi_t libubi, struct ubi_dev_info *dev_info,
		       char *name)
{
	int err, i;
	struct ubi_vol_info vol_info;

	for (i=dev_info->lowest_vol_id; i<=dev_info->highest_vol_id; i++) {
		err = ubi_get_vol_info1(libubi, dev_info->dev_num, i, &vol_info);
		if (err == -1) {
			if (errno == ENOENT)
				continue;
			return -1;
		}

		if (strcmp(name, vol_info.name) == 0)
			return vol_info.vol_id;
	}

	return -1;
}
Пример #10
0
/**
 * mkvol_basic - simple test that checks basic volume creation capability.
 *
 * Thus function returns %0 in case of success and %-1 in case of failure.
 */
static int mkvol_basic(void)
{
	struct ubi_mkvol_request req;
	struct ubi_vol_info vol_info;
	int vol_id, ret;
	const char *name = PROGRAM_NAME ":mkvol_basic()";

	/* Create dynamic volume of maximum size */
	req.vol_id = UBI_VOL_NUM_AUTO;
	req.alignment = 1;
	req.bytes = dev_info.avail_bytes;
	req.vol_type = UBI_DYNAMIC_VOLUME;
	req.name = name;

	if (ubi_mkvol(libubi, node, &req)) {
		failed("ubi_mkvol");
		return -1;
	}

	vol_id = req.vol_id;
	if (check_volume(vol_id, &req))
		goto remove;

	if (ubi_rmvol(libubi, node, vol_id)) {
		failed("ubi_rmvol");
		return -1;
	}

	/* Create static volume of maximum size */
	req.vol_id = UBI_VOL_NUM_AUTO;
	req.alignment = 1;
	req.bytes = dev_info.avail_bytes;
	req.vol_type = UBI_STATIC_VOLUME;
	req.name = name;

	if (ubi_mkvol(libubi, node, &req)) {
		failed("ubi_mkvol");
		return -1;
	}

	vol_id = req.vol_id;
	if (check_volume(vol_id, &req))
		goto remove;

	if (ubi_rmvol(libubi, node, vol_id)) {
		failed("ubi_rmvol");
		return -1;
	}

	/* Make sure volume does not exist */
	ret = ubi_get_vol_info1(libubi, dev_info.dev_num, vol_id, &vol_info);
	if (ret == 0) {
		errorm("removed volume %d exists", vol_id);
		goto remove;
	}

	return 0;

remove:
	ubi_rmvol(libubi, node, vol_id);
	return -1;
}
Пример #11
0
/*
 * Helper function for test_rsvol().
 */
static int test_rsvol1(struct ubi_vol_info *vol_info)
{
	long long bytes;
	struct ubi_vol_info vol_info1;
	char vol_node[strlen(UBI_VOLUME_PATTERN) + 100];
	unsigned char buf[vol_info->rsvd_bytes];
	int fd, i, ret;

	/* Make the volume smaller and check basic volume I/O */
	bytes = vol_info->rsvd_bytes - vol_info->leb_size;
	if (ubi_rsvol(libubi, node, vol_info->vol_id, bytes - 1)) {
		failed("ubi_rsvol");
		return -1;
	}

	if (ubi_get_vol_info1(libubi, vol_info->dev_num, vol_info->vol_id,
			     &vol_info1)) {
		failed("ubi_get_vol_info");
		return -1;
	}

	if (vol_info1.rsvd_bytes != bytes) {
		errorm("rsvd_bytes %lld, must be %lld",
		       vol_info1.rsvd_bytes, bytes);
		return -1;
	}

	if (vol_info1.rsvd_lebs != vol_info->rsvd_lebs - 1) {
		errorm("rsvd_lebs %d, must be %d",
		       vol_info1.rsvd_lebs, vol_info->rsvd_lebs - 1);
		return -1;
	}

	/* Write data to the volume */
	sprintf(vol_node, UBI_VOLUME_PATTERN, dev_info.dev_num,
			vol_info->vol_id);

	fd = open(vol_node, O_RDWR);
	if (fd == -1) {
		failed("open");
		errorm("cannot open \"%s\"\n", vol_node);
		return -1;
	}

	bytes = vol_info->rsvd_bytes - vol_info->leb_size - 1;
	if (ubi_update_start(libubi, fd, bytes)) {
		failed("ubi_update_start");
		goto close;
	}

	for (i = 0; i < bytes; i++)
		buf[i] = (unsigned char)i;

	ret = write(fd, buf, bytes);
	if (ret != bytes) {
		failed("write");
		goto close;
	}

	close(fd);

	if (ubi_rsvol(libubi, node, vol_info->vol_id, bytes)) {
		failed("ubi_rsvol");
		return -1;
	}

	if (ubi_rsvol(libubi, node, vol_info->vol_id,
		      (long long)vol_info->leb_size * dev_info.avail_lebs)) {
		failed("ubi_rsvol");
		return -1;
	}

	fd = open(vol_node, O_RDWR);
	if (fd == -1) {
		failed("open");
		errorm("cannot open \"%s\"\n", vol_node);
		return -1;
	}

	/* Read data back */
	if (lseek(fd, 0, SEEK_SET) != 0) {
		failed("seek");
		goto close;
	}
	memset(buf, 0, bytes);
	ret = read(fd, buf, bytes);
	if (ret != bytes) {
		failed("read");
		goto close;
	}

	for (i = 0; i < bytes; i++) {
		if (buf[i] != (unsigned char)i) {
			errorm("bad data");
			goto close;
		}
	}

	close(fd);
	return 0;

close:
	close(fd);
	return -1;
}
Пример #12
0
void scan_ubi_partitions(int mtd)
{
	struct flash_description *nand = get_flash_info();
	int err;
	libubi_t libubi = nand->libubi;
	struct ubi_part *ubi_part;
	struct mtd_ubi_info *mtd_info;
	int i;

	if (mtd < 0 || mtd > MAX_MTD_DEVICES)
		ERROR("wrong MTD device /dev/mtd%d", mtd);

	mtd_info = &nand->mtd_info[mtd];
	LIST_INIT(&mtd_info->ubi_partitions);

	/*
	 * The program is called directly after a boot,
	 * and a detach is not required. However,
	 * detaching at the beginning allows consecutive
	 * start of the program itself
	 */
	ubi_detach_mtd(libubi, DEFAULT_CTRL_DEV, mtd);

	mtd_info->req.dev_num = UBI_DEV_NUM_AUTO;
	mtd_info->req.mtd_num = mtd;
#if CONFIG_UBIVIDOFFSET
	mtd_info->req.vid_hdr_offset = CONFIG_UBIVIDOFFSET;
#else
	mtd_info->req.vid_hdr_offset = 0;
#endif
	mtd_info->req.mtd_dev_node = NULL;

	err = ubi_attach(libubi, DEFAULT_CTRL_DEV, &mtd_info->req);
	if (err) {
		TRACE("cannot attach mtd%d - maybe not a NAND or raw device", mtd);
		return;
	}

	err = ubi_get_dev_info1(libubi, mtd_info->req.dev_num, &mtd_info->dev_info);
	if (err) {
		TRACE("cannot get information about UBI device %d", mtd_info->req.dev_num);
		return;
	}

	for (i = mtd_info->dev_info.lowest_vol_id;
	     i <= mtd_info->dev_info.highest_vol_id; i++) {
		ubi_part = (struct ubi_part *)calloc(1, sizeof(struct ubi_part));
		if (!ubi_part)
			ERROR("No memory: malloc failed\n");

		err = ubi_get_vol_info1(libubi, mtd_info->dev_info.dev_num, i, &ubi_part->vol_info);
		if (err == -1) {
			if (errno == ENOENT)
				continue;

			TRACE("libubi failed to probe volume %d on ubi%d",
					  i, mtd_info->dev_info.dev_num);
			return;
		}

		LIST_INSERT_HEAD(&mtd_info->ubi_partitions, ubi_part, next);
		TRACE("mtd%d:\tVolume found : \t%s",
			mtd,
			ubi_part->vol_info.name);
	}

	mtd_info->scanned = 1;
}