⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 libubi.c

📁 mtd-utils 是一套更改linux mtd設備的工具
💻 C
📖 第 1 页 / 共 2 页
字号:
	lib->dev_max_ec = mkpath(lib->ubi_dev, DEV_MAX_EC);	if (!lib->dev_max_ec)		goto out_error;	lib->dev_bad_rsvd = mkpath(lib->ubi_dev, DEV_MAX_RSVD);	if (!lib->dev_bad_rsvd)		goto out_error;	lib->dev_max_vols = mkpath(lib->ubi_dev, DEV_MAX_VOLS);	if (!lib->dev_max_vols)		goto out_error;	lib->dev_min_io_size = mkpath(lib->ubi_dev, DEV_MIN_IO_SIZE);	if (!lib->dev_min_io_size)		goto out_error;	lib->dev_mtd_num = mkpath(lib->ubi_dev, DEV_MTD_NUM);	if (!lib->dev_mtd_num)		goto out_error;	lib->ubi_vol = mkpath(lib->sysfs_ubi, UBI_VOL_NAME_PATT);	if (!lib->ubi_vol)		goto out_error;	lib->vol_type = mkpath(lib->ubi_vol, VOL_TYPE);	if (!lib->vol_type)		goto out_error;	lib->vol_dev = mkpath(lib->ubi_vol, VOL_DEV);	if (!lib->vol_dev)		goto out_error;	lib->vol_alignment = mkpath(lib->ubi_vol, VOL_ALIGNMENT);	if (!lib->vol_alignment)		goto out_error;	lib->vol_data_bytes = mkpath(lib->ubi_vol, VOL_DATA_BYTES);	if (!lib->vol_data_bytes)		goto out_error;	lib->vol_rsvd_ebs = mkpath(lib->ubi_vol, VOL_RSVD_EBS);	if (!lib->vol_rsvd_ebs)		goto out_error;	lib->vol_eb_size = mkpath(lib->ubi_vol, VOL_EB_SIZE);	if (!lib->vol_eb_size)		goto out_error;	lib->vol_corrupted = mkpath(lib->ubi_vol, VOL_CORRUPTED);	if (!lib->vol_corrupted)		goto out_error;	lib->vol_name = mkpath(lib->ubi_vol, VOL_NAME);	if (!lib->vol_name)		goto out_error;	if (read_positive_int(lib->ubi_version, &version))		goto out_error;	if (version != LIBUBI_UBI_VERSION) {		errmsg("this library was made for UBI version %d, but UBI "		       "version %d is detected\n", LIBUBI_UBI_VERSION, version);		goto out_error;	}	return lib;out_error:	libubi_close((libubi_t)lib);	return NULL;}void libubi_close(libubi_t desc){	struct libubi *lib = (struct libubi *)desc;	free(lib->vol_name);	free(lib->vol_corrupted);	free(lib->vol_eb_size);	free(lib->vol_rsvd_ebs);	free(lib->vol_data_bytes);	free(lib->vol_alignment);	free(lib->vol_dev);	free(lib->vol_type);	free(lib->ubi_vol);	free(lib->dev_mtd_num);	free(lib->dev_min_io_size);	free(lib->dev_max_vols);	free(lib->dev_bad_rsvd);	free(lib->dev_max_ec);	free(lib->dev_eb_size);	free(lib->dev_bad_count);	free(lib->dev_total_ebs);	free(lib->dev_avail_ebs);	free(lib->dev_dev);	free(lib->ubi_version);	free(lib->ubi_dev);	free(lib->sysfs_ubi);	free(lib->ctrl_dev);	free(lib->sysfs_ctrl);	free(lib->sysfs);	free(lib);}int ubi_attach_mtd(libubi_t desc, const char *node,		   struct ubi_attach_request *req){	int fd, ret;	struct ubi_attach_req r;	memset(&r, sizeof(struct ubi_attach_req), '\0');	desc = desc;	r.ubi_num = req->dev_num;	r.mtd_num = req->mtd_num;	r.vid_hdr_offset = req->vid_hdr_offset;	fd = open(node, O_RDONLY);	if (fd == -1)		return -1;	ret = ioctl(fd, UBI_IOCATT, &r);	close(fd);	if (ret == -1)		return -1;	req->dev_num = r.ubi_num;#ifdef UDEV_SETTLE_HACK	if (system("udevsettle") == -1)		return -1;	if (system("udevsettle") == -1)		return -1;#endif	return ret;}int ubi_detach_mtd(libubi_t desc, const char *node, int mtd_num){	int ret, ubi_dev;	ret = mtd_num2ubi_dev(desc, mtd_num, &ubi_dev);	if (ret == -1) {		errno = ENODEV;		return ret;	}	return ubi_remove_dev(desc, node, ubi_dev);}int ubi_remove_dev(libubi_t desc, const char *node, int ubi_dev){	int fd, ret;	desc = desc;	fd = open(node, O_RDONLY);	if (fd == -1)		return -1;	ret = ioctl(fd, UBI_IOCDET, &ubi_dev);	if (ret == -1)		goto out_close;#ifdef UDEV_SETTLE_HACK	if (system("udevsettle") == -1)		return -1;#endifout_close:	close(fd);	return ret;}int ubi_node_type(libubi_t desc, const char *node){	struct stat st;	struct ubi_info info;	int i, fd, major, minor;	struct libubi *lib = (struct libubi *)desc;	char file[strlen(lib->ubi_vol) + 100];	if (stat(node, &st))		return -1;	if (!S_ISCHR(st.st_mode)) {		errno = EINVAL;		return -1;	}	major = major(st.st_rdev);	minor = minor(st.st_rdev);	if (ubi_get_info((libubi_t *)lib, &info))		return -1;	for (i = info.lowest_dev_num; i <= info.highest_dev_num; i++) {		int major1, minor1, ret;		ret = dev_get_major(lib, i, &major1, &minor1);		if (ret) {			if (errno == ENOENT)				continue;			return -1;		}		if (major1 == major)			break;	}	if (i > info.highest_dev_num) {		/*		 * The character device node does not correspond to any		 * existing UBI device or volume, but we do not want to return		 * any error number in this case, to indicate the fact that it		 * could be a UBI device/volume, but it doesn't.		 */		errno = 0;		return -1;	}	if (minor == 0)		return 1;	/* This is supposdely an UBI volume device node */	sprintf(file, lib->ubi_vol, i, minor - 1);	fd = open(file, O_RDONLY);	if (fd == -1) {		errno = 0;		return -1;	}	return 2;}int ubi_get_info(libubi_t desc, struct ubi_info *info){	DIR *sysfs_ubi;	struct dirent *dirent;	struct libubi *lib = (struct libubi *)desc;	memset(info, '\0', sizeof(struct ubi_info));	if (read_major(lib->ctrl_dev, &info->ctrl_major, &info->ctrl_minor)) {		/*		 * Older UBI versions did not have control device, so we do not		 * panic here for compatibility reasons. May be few years later		 * we could return -1 here, but for now just set major:minor to		 * -1.		 */		info->ctrl_major = info->ctrl_minor = -1;	}	/*	 * We have to scan the UBI sysfs directory to identify how many UBI	 * devices are present.	 */	sysfs_ubi = opendir(lib->sysfs_ubi);	if (!sysfs_ubi)		return sys_errmsg("cannot open %s", lib->sysfs_ubi);	info->lowest_dev_num = INT_MAX;	while (1) {		int dev_num, ret;		char tmp_buf[256];		errno = 0;		dirent = readdir(sysfs_ubi);		if (!dirent)			break;		if (strlen(dirent->d_name) > 256) {			errmsg("invalid entry in %s: \"%s\"",			       lib->sysfs_ubi, dirent->d_name);			goto out_close;		}		ret = sscanf(dirent->d_name, UBI_DEV_NAME_PATT"%s",			     &dev_num, tmp_buf);		if (ret == 1) {			info->dev_count += 1;			if (dev_num > info->highest_dev_num)				info->highest_dev_num = dev_num;			if (dev_num < info->lowest_dev_num)				info->lowest_dev_num = dev_num;		}	}	if (!dirent && errno) {		sys_errmsg("readdir failed on \"%s\"", lib->sysfs_ubi);		goto out_close;	}	if (closedir(sysfs_ubi))		return sys_errmsg("closedir failed on \"%s\"", lib->sysfs_ubi);	if (info->lowest_dev_num == INT_MAX)		info->lowest_dev_num = 0;	if (read_positive_int(lib->ubi_version, &info->version))		return -1;	return 0;out_close:	closedir(sysfs_ubi);	return -1;}int ubi_mkvol(libubi_t desc, const char *node, struct ubi_mkvol_request *req){	int fd, ret;	struct ubi_mkvol_req r;	size_t n;	memset(&r, sizeof(struct ubi_mkvol_req), '\0');	desc = desc;	r.vol_id = req->vol_id;	r.alignment = req->alignment;	r.bytes = req->bytes;	r.vol_type = req->vol_type;	n = strlen(req->name);	if (n > UBI_MAX_VOLUME_NAME)		return -1;	strncpy(r.name, req->name, UBI_MAX_VOLUME_NAME + 1);	r.name_len = n;	fd = open(node, O_RDONLY);	if (fd == -1)		return -1;	ret = ioctl(fd, UBI_IOCMKVOL, &r);	if (ret == -1)		goto out_close;	req->vol_id = r.vol_id;#ifdef UDEV_SETTLE_HACK	if (system("udevsettle") == -1)		return -1;#endifout_close:	close(fd);	return ret;}int ubi_rmvol(libubi_t desc, const char *node, int vol_id){	int fd, ret;	desc = desc;	fd = open(node, O_RDONLY);	if (fd == -1)		return -1;	ret = ioctl(fd, UBI_IOCRMVOL, &vol_id);	if (ret == -1)		goto out_close;#ifdef UDEV_SETTLE_HACK	if (system("udevsettle") == -1)		return -1;#endifout_close:	close(fd);	return ret;}int ubi_rsvol(libubi_t desc, const char *node, int vol_id, long long bytes){	int fd, ret;	struct ubi_rsvol_req req;	desc = desc;	fd = open(node, O_RDONLY);	if (fd == -1)		return -1;	req.bytes = bytes;	req.vol_id = vol_id;	ret = ioctl(fd, UBI_IOCRSVOL, &req);	close(fd);	return ret;}int ubi_update_start(libubi_t desc, int fd, long long bytes){	desc = desc;	if (ioctl(fd, UBI_IOCVOLUP, &bytes))		return -1;	return 0;}int ubi_leb_change_start(libubi_t desc, int fd, int lnum, int bytes, int dtype){	struct ubi_leb_change_req req;	desc = desc;	memset(&req, 0, sizeof(struct ubi_leb_change_req));	req.lnum = lnum;	req.bytes = bytes;	req.dtype = dtype;	if (ioctl(fd, UBI_IOCEBCH, &req))		return -1;	return 0;}int ubi_get_dev_info1(libubi_t desc, int dev_num, struct ubi_dev_info *info){	DIR *sysfs_ubi;	struct dirent *dirent;	struct libubi *lib = (struct libubi *)desc;	memset(info, '\0', sizeof(struct ubi_dev_info));	info->dev_num = dev_num;	sysfs_ubi = opendir(lib->sysfs_ubi);	if (!sysfs_ubi)		return -1;	info->lowest_vol_num = INT_MAX;	while (1) {		int vol_id, ret, devno;		char tmp_buf[256];		errno = 0;		dirent = readdir(sysfs_ubi);		if (!dirent)			break;		if (strlen(dirent->d_name) > 256) {			errmsg("invalid entry in %s: \"%s\"",			       lib->sysfs_ubi, dirent->d_name);			goto out_close;		}		ret = sscanf(dirent->d_name, UBI_VOL_NAME_PATT"%s", &devno, &vol_id, tmp_buf);		if (ret == 2 && devno == dev_num) {			info->vol_count += 1;			if (vol_id > info->highest_vol_num)				info->highest_vol_num = vol_id;			if (vol_id < info->lowest_vol_num)				info->lowest_vol_num = vol_id;		}	}	if (!dirent && errno) {		sys_errmsg("readdir failed on \"%s\"", lib->sysfs_ubi);		goto out_close;	}	if (closedir(sysfs_ubi))		return sys_errmsg("closedir failed on \"%s\"", lib->sysfs_ubi);	if (info->lowest_vol_num == INT_MAX)		info->lowest_vol_num = 0;	if (dev_get_major(lib, dev_num, &info->major, &info->minor))		return -1;	if (dev_read_int(lib->dev_avail_ebs, dev_num, &info->avail_lebs))		return -1;	if (dev_read_int(lib->dev_total_ebs, dev_num, &info->total_lebs))		return -1;	if (dev_read_int(lib->dev_bad_count, dev_num, &info->bad_count))		return -1;	if (dev_read_int(lib->dev_eb_size, dev_num, &info->leb_size))		return -1;	if (dev_read_int(lib->dev_bad_rsvd, dev_num, &info->bad_rsvd))		return -1;	if (dev_read_ll(lib->dev_max_ec, dev_num, &info->max_ec))		return -1;	if (dev_read_int(lib->dev_max_vols, dev_num, &info->max_vol_count))		return -1;	if (dev_read_int(lib->dev_min_io_size, dev_num, &info->min_io_size))		return -1;	info->avail_bytes = info->avail_lebs * info->leb_size;	info->total_bytes = info->total_lebs * info->leb_size;	return 0;out_close:	closedir(sysfs_ubi);	return -1;}int ubi_get_dev_info(libubi_t desc, const char *node, struct ubi_dev_info *info){	int dev_num;	struct libubi *lib = (struct libubi *)desc;	if (dev_node2num(lib, node, &dev_num))		return -1;	return ubi_get_dev_info1(desc, dev_num, info);}int ubi_get_vol_info1(libubi_t desc, int dev_num, int vol_id,		      struct ubi_vol_info *info){	int ret;	struct libubi *lib = (struct libubi *)desc;	char buf[50];	memset(info, '\0', sizeof(struct ubi_vol_info));	info->dev_num = dev_num;	info->vol_id = vol_id;	if (dev_get_major(lib, dev_num, &info->dev_major, &info->dev_minor))		return -1;	if (vol_get_major(lib, dev_num, vol_id, &info->major, &info->minor))		return -1;	ret = vol_read_data(lib->vol_type, dev_num, vol_id, buf, 50);	if (ret < 0)		return -1;	if (strncmp(buf, "static\n", ret) == 0)		info->type = UBI_STATIC_VOLUME;	else if (strncmp(buf, "dynamic\n", ret) == 0)		info->type = UBI_DYNAMIC_VOLUME;	else {		errmsg("bad value at \"%s\"", buf);		errno = EINVAL;		return -1;	}	ret = vol_read_int(lib->vol_alignment, dev_num, vol_id,			   &info->alignment);	if (ret)		return -1;	ret = vol_read_ll(lib->vol_data_bytes, dev_num, vol_id,			  &info->data_bytes);	if (ret)		return -1;	ret = vol_read_int(lib->vol_rsvd_ebs, dev_num, vol_id, &info->rsvd_lebs);	if (ret)		return -1;	ret = vol_read_int(lib->vol_eb_size, dev_num, vol_id, &info->leb_size);	if (ret)		return -1;	ret = vol_read_int(lib->vol_corrupted, dev_num, vol_id,			   &info->corrupted);	if (ret)		return -1;	info->rsvd_bytes = info->leb_size * info->rsvd_lebs;	ret = vol_read_data(lib->vol_name, dev_num, vol_id, &info->name,			    UBI_VOL_NAME_MAX + 2);	if (ret < 0)		return -1;	info->name[ret - 1] = '\0';	return 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);}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -