int make_fs(const char *device, const char *fstype, unsigned int fsblocksize) { char part_device[64]; char fsblock_size[14]; char *argv[10]; char ext_opts[1024]; __u64 max_online_resize; fsblocksize = fsblocksize != 0 ? fsblocksize : 4096; if (get_partition_device_name(device, part_device, sizeof(part_device))) return SYSEXIT_MKFS; argv[0] = "mkfs"; argv[1] = "-t"; argv[2] = (char*)fstype; argv[3] = "-j"; snprintf(fsblock_size, sizeof(fsblock_size), "-b%u", fsblocksize); argv[4] = fsblock_size; /* Reserve enough space so that the block group descriptor table can grow to 16T * Note: the max_online_resize is __u32 in mkfs.ext4 */ max_online_resize = PLOOP_MAX_FS_SIZE / fsblocksize; if (max_online_resize > (__u32)~0) max_online_resize = (__u32)~0; snprintf(ext_opts, sizeof(ext_opts), "-Elazy_itable_init,resize=%llu", max_online_resize); argv[5] = ext_opts; /* Set the journal size to 128M to allow online resize up to 16T * independly on the initial image size */ argv[6] = "-Jsize=128"; argv[7] = "-i16384"; /* 1 inode per 16K disk space */ argv[8] = part_device; argv[9] = NULL; if (run_prg(argv)) return SYSEXIT_MKFS; argv[0] = get_prog(tune2fs_progs); argv[1] = "-ouser_xattr,acl"; argv[2] = "-c0"; argv[3] = "-i0"; argv[4] = "-eremount-ro"; argv[5] = part_device; argv[6] = NULL; if (run_prg(argv)) return SYSEXIT_MKFS; return 0; }
int ploop_copy_init(struct ploop_disk_images_data *di, struct ploop_copy_param *param, struct ploop_copy_handle **h) { int ret, err; int blocksize; char *image = NULL; char *format = NULL; char device[64]; char partdev[64]; struct ploop_copy_handle *_h = NULL; int is_remote; char mnt[PATH_MAX] = ""; is_remote = is_fd_socket(param->ofd); if (is_remote < 0) { ploop_err(0, "Invalid output fd %d: must be a file, " "a pipe or a socket", param->ofd); return SYSEXIT_PARAM; } if (param->ofd == STDOUT_FILENO) ploop_set_verbose_level(PLOOP_LOG_NOSTDOUT); else if (param->ofd == STDERR_FILENO) ploop_set_verbose_level(PLOOP_LOG_NOCONSOLE); if (ploop_lock_dd(di)) return SYSEXIT_LOCK; if (ploop_find_dev_by_dd(di, device, sizeof(device))) { ploop_err(0, "Can't find running ploop device"); ret = SYSEXIT_SYS; goto err; } ret = get_image_info(device, &image, &format, &blocksize); if (ret) goto err; _h = alloc_ploop_copy_handle(S2B(blocksize)); if (_h == NULL) { ploop_err(0, "alloc_ploop_copy_handle"); ret = SYSEXIT_MALLOC; goto err; } _h->raw = strcmp(format, "raw") == 0; _h->ofd = param->ofd; _h->is_remote = is_remote; _h->async = param->async; _h->devfd = open(device, O_RDONLY|O_CLOEXEC); if (_h->devfd == -1) { ploop_err(errno, "Can't open device %s", device); ret = SYSEXIT_DEVICE; goto err; } ret = get_partition_device_name(device, partdev, sizeof(partdev)); if (ret) goto err; _h->partfd = open(partdev, O_RDONLY|O_CLOEXEC); if (_h->partfd == -1) { ploop_err(errno, "Can't open device %s", partdev); ret = SYSEXIT_DEVICE; goto err; } ret = SYSEXIT_OPEN; err = ploop_get_mnt_by_dev(device, mnt, sizeof(mnt)); if (err == -1) goto err; else if (err == 0) { _h->mntfd = open(mnt, O_RDONLY|O_NONBLOCK|O_DIRECTORY); if (_h->mntfd < 0) { ploop_err(errno, "Can't open %s", mnt); goto err; } } ploop_log(0, "Send image %s dev=%s mnt=%s fmt=%s blocksize=%d local=%d", image, device, mnt, format, blocksize, !is_remote); if (open_delta(&_h->idelta, image, O_RDONLY|O_DIRECT, OD_ALLOW_DIRTY)) { ret = SYSEXIT_OPEN; goto err; } ret = complete_running_operation(di, device); if (ret) goto err; _h->cl = register_cleanup_hook(cancel_sender, _h); pthread_mutex_lock(&_h->sd.wait_mutex); err: if (ret) { ploop_copy_release(_h); free_ploop_copy_handle(_h); } else *h = _h; free(image); ploop_unlock_dd(di); return ret; }