#include #include #include static uint64_t device_logical_size(const char* dev) { int fd; uint8_t buf[SECTOR_SIZE]; struct cbd_header header; uint64_t lblk_total; fd = open(dev, O_RDONLY); if (fd < 0) { error("Cannot open device\n"); } if (read(fd, buf, sizeof(buf)) != sizeof(buf)) { error("Cannot read device\n"); } close(fd); cbd_header_get(buf, &header); if (memcmp(header.magic, CBD_MAGIC, sizeof(header.magic)) != 0) { error("Bad magic\n"); } lblk_total = header.params.lblk_per_zone * header.params.nr_zones; return lblk_total * lblk_size(&header.params); } int cbd_open(const char* dev, const char* name, uint64_t cache_pages, bool sync) { int ret; struct stat st; uint64_t lsize; char optbuf[80]; char params[256]; struct dm_task* dmt; uint32_t cookie = 0; ret = stat(dev, &st); if (ret) { error("Failed to stat device\n"); } if (!S_ISBLK(st.st_mode)) { error("Not a block device\n"); } lsize = device_logical_size(dev); strcpy(params, dev); if (cache_pages) { sprintf(optbuf, " cache_pages=%lu", (unsigned long)cache_pages); strcat(params, optbuf); } if (sync) { strcat(params, " sync"); } dmt = dm_task_create(DM_DEVICE_CREATE); if (!dmt) { error("dm_task_create failed\n"); } ret = dm_task_set_name(dmt, name); if (ret == 0) { error("dm_task_set_name failed\n"); } printf("%s: start_sector=0 num_sectors=%lu\n", __func__, (unsigned long)(lsize / SECTOR_SIZE)); ret = dm_task_add_target(dmt, 0, lsize / SECTOR_SIZE, "compress", params); if (ret == 0) { error("dm_task_add_target failed\n"); } ret = dm_task_set_cookie(dmt, &cookie, 0); if (ret == 0) { error("dm_task_set_cookie failed\n"); } ret = dm_task_run(dmt); if (ret == 0) { error("dm_task_run failed\n"); } dm_udev_wait(cookie); dm_task_destroy(dmt); return 0; }