static int open_top_delta(const char *device, struct delta *delta, int *lvl) { char *image = NULL; char *fmt = NULL; if (ploop_get_attr(device, "top", lvl)) { ploop_err(0, "Can't find top delta"); return(SYSEXIT_SYSFS); } if (find_delta_names(device, *lvl, *lvl, &image, &fmt)) return(SYSEXIT_SYSFS); if (strcmp(fmt, "raw") == 0) { ploop_err(0, "Ballooning for raw format is not supported"); return(SYSEXIT_PARAM); } if (open_delta(delta, image, O_RDONLY|O_DIRECT, OD_ALLOW_DIRTY)) { ploop_err(errno, "open_delta"); return(SYSEXIT_OPEN); } 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; }