Exemplo n.º 1
0
static int pb_complete(int argc, char **argv)
{
    int i, ret, fd;

    while ((i = getopt(argc, argv, "d:m:")) != EOF) {
        switch (i) {
        case 'd':
            device = optarg;
            break;
        case 'm':
            mount_point = optarg;
            break;
        default:
            usage_complete();
            return SYSEXIT_PARAM;
        }
    }

    argc -= optind;
    argv += optind;

    GET_DD(argc, argv);
    if (argc != 0 || fill_opts()) {
        usage_complete();
        return SYSEXIT_PARAM;
    }

    ret = get_balloon(mount_point, NULL, &fd);
    if (ret)
        return ret;

    return ploop_balloon_complete(device);
}
Exemplo n.º 2
0
static int pb_change(int argc, char **argv)
{
    int    fd;
    int    i, ret;
    off_t  new_size = 0;
    int    new_size_set = 0;

    while ((i = getopt(argc, argv, "s:d:m:")) != EOF) {
        switch (i) {
        case 's':
            /* NB: currently, new_size is in 'sector' units */
            if (parse_size(optarg, &new_size, "-s")) {
                usage_change();
                return SYSEXIT_PARAM;
            }
            new_size_set++;
            break;
        case 'd':
            device = optarg;
            break;
        case 'm':
            mount_point = optarg;
            break;
        default:
            usage_change();
            return SYSEXIT_PARAM;
        }
    }

    argc -= optind;
    argv += optind;

    GET_DD(argc, argv);
    if (argc != 0 || !new_size_set || fill_opts()) {
        usage_change();
        return SYSEXIT_PARAM;
    }
    ret = get_balloon(mount_point, NULL, &fd);
    if (ret)
        return ret;

    return ploop_balloon_change_size(device, fd, new_size);
}
Exemplo n.º 3
0
int ploop_discard_get_stat_by_dev(const char *device, const char *mount_point,
		struct ploop_discard_stat *pd_stat)
{
	int		err;
	struct statfs	stfs;
	struct stat	st, balloon_stat;
	off_t		ploop_size;
	char		image[PATH_MAX];

	err = get_balloon(mount_point, &balloon_stat, NULL);
	if (err)
		return err;

	err = statfs(mount_point, &stfs);
	if (err == -1) {
		ploop_err(errno, "statfs(%s) failed", mount_point);
		return 1;
	}

	err = ploop_get_size(device, &ploop_size);
	if (err)
		return 1;

	err = ploop_find_top_delta_name_and_format(device, image, sizeof(image), NULL, 0);
	if (err)
		return 1;

	err = stat(image, &st);
	if (err == -1) {
		ploop_err(errno, "stat(%s) failed", image);
		return 1;
	}

	pd_stat->ploop_size = S2B(ploop_size) - balloon_stat.st_size;
	pd_stat->image_size = st.st_size;
	pd_stat->data_size = pd_stat->ploop_size - stfs.f_bfree * stfs.f_bsize;
	pd_stat->balloon_size = balloon_stat.st_size;

	return 0;
}
Exemplo n.º 4
0
static int pb_clear(int argc, char **argv)
{
    int i, ret;
    int fd2;

    while ((i = getopt(argc, argv, "d:m:")) != EOF) {
        switch (i) {
        case 'd':
            device = optarg;
            break;
        case 'm':
            mount_point = optarg;
            break;
        default:
            usage_clear();
            return SYSEXIT_PARAM;
        }
    }

    argc -= optind;
    argv += optind;

    GET_DD(argc, argv);
    if (argc != 0 || fill_opts()) {
        usage_clear();
        return SYSEXIT_PARAM;
    }

    ret = get_balloon(mount_point, NULL, &fd2);
    if (ret)
        return ret;

    ret = ploop_balloon_clear_state(device);
    if (ret)
        return ret;
    fprintf(stdout, "Current state of in-kernel maintenance is OFF now\n");
    return 0;
}
Exemplo n.º 5
0
static int pb_show(int argc, char **argv)
{
    int i, ret;
    struct stat st;

    while ((i = getopt(argc, argv, "fd:m:")) != EOF) {
        switch (i) {
        case 'f':
            force = 1;
            break;
        case 'd':
            device = optarg;
            break;
        case 'm':
            mount_point = optarg;
            break;
        default:
            usage_show();
            return SYSEXIT_PARAM;
        }
    }

    argc -= optind;
    argv += optind;

    GET_DD(argc, argv);
    if (argc != 0 || fill_opts()) {
        usage_show();
        return SYSEXIT_PARAM;
    }

    ret = get_balloon(mount_point, &st, NULL);
    if (ret)
        return ret;
    fprintf(stdout, "Current size of hidden balloon is %llu bytes\n",
            (unsigned long long) st.st_size);
    return 0;
}
Exemplo n.º 6
0
int ploop_balloon_check_and_repair(const char *device, const char *mount_point, int repair)
{
	int   ret, fd = -1;
	int   balloonfd = -1;
	__u32 n_free_blocks;
	__u32 freezed_a_h;
	__u32 dev_start;  /* /sys/block/ploop0/ploop0p1/start */
	struct ploop_balloon_ctl    b_ctl;
	struct stat		    st;
	struct pfiemap		   *pfiemap  = NULL;
	struct freemap		   *freemap  = NULL;
	struct freemap		   *rangemap = NULL;
	struct relocmap		   *relocmap = NULL;
	struct ploop_freeblks_ctl  *freeblks = NULL;
	struct ploop_relocblks_ctl *relocblks= NULL;
	char *msg = repair ? "repair" : "check";
	__u32 *reverse_map = NULL;
	__u32  reverse_map_len;
	int top_level;
	int entries_used;
	struct delta delta = {};
	int drop_state = 0;

	ret = get_balloon(mount_point, &st, &balloonfd);
	if (ret)
		return ret;

	if (st.st_size == 0) {
		ploop_log(0, "Nothing to do: hidden balloon is empty");
		close(balloonfd);
		return 0;
	}

	pfiemap = fiemap_alloc(128);
	freemap = freemap_alloc(128);
	rangemap = freemap_alloc(128);
	relocmap = relocmap_alloc(128);
	if (!pfiemap || !freemap || !rangemap || !relocmap) {
		ret = SYSEXIT_MALLOC;
		goto err;
	}

	fd = open_device(device);
	if (fd == -1) {
		ret = SYSEXIT_OPEN;
		goto err;
	}

	memset(&b_ctl, 0, sizeof(b_ctl));
	/* block other maintenance ops even if we only check balloon */
	b_ctl.inflate = 1;
	ret = ioctl_device(fd, PLOOP_IOC_BALLOON, &b_ctl);
	if (ret)
		goto err;

	switch (b_ctl.mntn_type) {
	case PLOOP_MNTN_BALLOON:
		drop_state = 1;
		ret = open_top_delta(device, &delta, &top_level);
		if (ret)
			goto err;
		reverse_map_len = delta.l2_size + delta.l2_size;
		reverse_map = alloc_reverse_map(reverse_map_len);
		if (reverse_map == NULL) {
			ret = SYSEXIT_MALLOC;
			goto err;
		}
		break;
	case PLOOP_MNTN_MERGE:
	case PLOOP_MNTN_GROW:
	case PLOOP_MNTN_TRACK:
		ploop_err(0, "Can't %s hidden balloon while another "
		       "maintenance operation is in progress (%s)",
			msg, mntn2str(b_ctl.mntn_type));
		ret = SYSEXIT_EBUSY;
		goto err;
	case PLOOP_MNTN_FBLOADED:
	case PLOOP_MNTN_RELOC:
		ploop_err(0, "Can't %s hidden balloon before previous "
			"balloon operation (%s) is completed. Use "
			"\"ploop-balloon complete\".",
			msg, mntn2str(b_ctl.mntn_type));
		ret = SYSEXIT_EBUSY;
		goto err;
	case PLOOP_MNTN_OFF:
		ploop_err(0, "Error: mntn_type is PLOOP_MNTN_OFF after "
			"IOC_BALLOON");
		ret = SYSEXIT_PROTOCOL;
		goto err;
	default:
		ploop_err(0, "Error: unknown mntn_type (%u)",
			b_ctl.mntn_type);
		ret = SYSEXIT_PROTOCOL;
		goto err;
	}

	if (dev_num2dev_start(device, st.st_dev, &dev_start)) {
		ploop_err(0, "Can't find out offset from start of ploop "
			"device (%s) to start of partition where fs (%s) "
			"resides", device, mount_point);
		ret = SYSEXIT_SYSFS;
		goto err;
	}

	ret = fiemap_get(balloonfd, S2B(dev_start), 0, st.st_size, &pfiemap);
	if (ret)
		goto err;
	fiemap_adjust(pfiemap, delta.blocksize);

	ret = fiemap_build_rmap(pfiemap, reverse_map, reverse_map_len, &delta);
	if (ret)
		goto err;

	ret = rmap2freemap(reverse_map, 0, reverse_map_len, &freemap, &entries_used);
	if (ret)
		goto err;
	if (entries_used == 0) {
		ploop_log(0, "No free blocks found");
		goto err;
	}

	ret = freemap2freeblks(freemap, top_level, &freeblks, &n_free_blocks);
	if (ret)
		goto err;
	if (!repair) {
		ploop_log(0, "Found %u free blocks. Consider using "
		       "\"ploop-balloon repair\"", n_free_blocks);
		ret = 0;
		goto err;
	} else {
		ploop_log(0, "Found %u free blocks", n_free_blocks);
	}

	ret = ioctl_device(fd, PLOOP_IOC_FREEBLKS, freeblks);
	if (ret)
		goto err;
	drop_state = 0;
	freezed_a_h = freeblks->alloc_head;
	if (freezed_a_h > reverse_map_len) {
		ploop_err(0, "Image corrupted: a_h=%u > rlen=%u",
			freezed_a_h, reverse_map_len);
		ret = SYSEXIT_PLOOPFMT;
		goto err;
	}

	ret = range_build(freezed_a_h, n_free_blocks, reverse_map, reverse_map_len,
		    &delta, freemap, &rangemap, &relocmap);
	if (ret)
		goto err;

	ret = relocmap2relocblks(relocmap, top_level, freezed_a_h, n_free_blocks,
			   &relocblks);
	if (ret)
		goto err;
	ret = ioctl_device(fd, PLOOP_IOC_RELOCBLKS, relocblks);
	if (ret)
		goto err;

	ploop_log(0, "TRUNCATED: %u cluster-blocks (%llu bytes)",
			relocblks->alloc_head,
			(unsigned long long)(relocblks->alloc_head * S2B(delta.blocksize)));

err:
	if (drop_state) {
		memset(&b_ctl, 0, sizeof(b_ctl));
		(void)ioctl_device(fd, PLOOP_IOC_BALLOON, &b_ctl);
	}

	// FIXME: close_delta()
	if (balloonfd >= 0)
		close(balloonfd);
	if (fd >= 0)
		close(fd);
	free(pfiemap);
	free(freemap);
	free(rangemap);
	free(relocmap);
	free(reverse_map);
	free(freeblks);
	free(relocblks);

	return ret;
}