Esempio n. 1
0
static int printf_loopdev(struct loopdev_cxt *lc)
{
	uint64_t x;
	dev_t dev = 0;
	ino_t ino = 0;
	char *fname = NULL;
	uint32_t type;

	fname = loopcxt_get_backing_file(lc);
	if (!fname)
		return -EINVAL;

	if (loopcxt_get_backing_devno(lc, &dev) == 0)
		loopcxt_get_backing_inode(lc, &ino);

	if (!dev && !ino) {
		/*
		 * Probably non-root user (no permissions to
		 * call LOOP_GET_STATUS ioctls).
		 */
		printf("%s: []: (%s)",
			loopcxt_get_device(lc), fname);

		if (loopcxt_get_offset(lc, &x) == 0 && x)
				printf(_(", offset %ju"), x);

		if (loopcxt_get_sizelimit(lc, &x) == 0 && x)
				printf(_(", sizelimit %ju"), x);
		printf("\n");
		return 0;
	}

	printf("%s: [%04d]:%" PRIu64 " (%s)",
		loopcxt_get_device(lc), (int) dev, ino, fname);

	if (loopcxt_get_offset(lc, &x) == 0 && x)
			printf(_(", offset %ju"), x);

	if (loopcxt_get_sizelimit(lc, &x) == 0 && x)
			printf(_(", sizelimit %ju"), x);

	if (loopcxt_get_encrypt_type(lc, &type) == 0) {
		const char *e = loopcxt_get_crypt_name(lc);

		if ((!e || !*e) && type == 1)
			e = "XOR";
		if (e && *e)
			printf(_(", encryption %s (type %u)"), e, type);
	}
	printf("\n");
	return 0;
}
Esempio n. 2
0
static void test_loop_info(const char *device, int flags, int debug)
{
	struct loopdev_cxt lc;
	char *p;
	uint64_t u64;

	loopcxt_init(&lc, flags);
	loopcxt_enable_debug(&lc, debug);

	if (loopcxt_set_device(&lc, device))
		err(EXIT_FAILURE, "failed to set device");

	p = loopcxt_get_backing_file(&lc);
	printf("\tBACKING FILE: %s\n", p);
	free(p);

	if (loopcxt_get_offset(&lc, &u64) == 0)
		printf("\tOFFSET: %jd\n", u64);

	if (loopcxt_get_sizelimit(&lc, &u64) == 0)
		printf("\tSIZE LIMIT: %jd\n", u64);

	printf("\tAUTOCLEAR: %s\n", loopcxt_is_autoclear(&lc) ? "YES" : "NOT");

	loopcxt_deinit(&lc);
}
Esempio n. 3
0
/*
 * @lc: context
 * @st: backing file stat or NULL
 * @backing_file: filename
 * @offset: offset
 * @flags: LOOPDEV_FL_OFFSET if @offset should not be ignored
 *
 * Returns 1 if the current @lc loopdev is associated with the given backing
 * file. Note that the preferred way is to use devno and inode number rather
 * than filename. The @backing_file filename is poor solution usable in case
 * that you don't have rights to call stat().
 *
 * Don't forget that old kernels provide very restricted (in size) backing
 * filename by LOOP_GET_STAT64 ioctl only.
 */
int loopcxt_is_used(struct loopdev_cxt *lc,
		    struct stat *st,
		    const char *backing_file,
		    uint64_t offset,
		    int flags)
{
	ino_t ino;
	dev_t dev;

	if (!lc)
		return 0;

	DBG(lc, loopdev_debug("checking %s vs. %s",
				loopcxt_get_device(lc),
				backing_file));

	if (st && loopcxt_get_backing_inode(lc, &ino) == 0 &&
		  loopcxt_get_backing_devno(lc, &dev) == 0) {

		if (ino == st->st_ino && dev == st->st_dev)
			goto found;

		/* don't use filename if we have devno and inode */
		return 0;
	}

	/* poor man's solution */
	if (backing_file) {
		char *name = loopcxt_get_backing_file(lc);
		int rc = name && strcmp(name, backing_file) == 0;

		free(name);
		if (rc)
			goto found;
	}

	return 0;
found:
	if (flags & LOOPDEV_FL_OFFSET) {
		uint64_t off;

		return loopcxt_get_offset(lc, &off) == 0 && off == offset;
	}
	return 1;
}
Esempio n. 4
0
/*
 * Same as loopcxt_set_device, but also checks if the device is
 * associeted with any file.
 *
 * Returns: <0 on error, 0 on success, 1 device does not match with
 *         LOOPITER_FL_{USED,FREE} flags.
 */
static int loopiter_set_device(struct loopdev_cxt *lc, const char *device)
{
	int rc = loopcxt_set_device(lc, device);
	int used;

	if (rc)
		return rc;

	if (!(lc->iter.flags & LOOPITER_FL_USED) &&
	    !(lc->iter.flags & LOOPITER_FL_FREE))
		return 0;	/* caller does not care about device status */

	used = loopcxt_get_offset(lc, NULL) == 0;

	if ((lc->iter.flags & LOOPITER_FL_USED) && used)
		return 0;

	if ((lc->iter.flags & LOOPITER_FL_FREE) && !used)
		return 0;

	DBG(lc, loopdev_debug("iter: setting device"));
	loopcxt_set_device(lc, NULL);
	return 1;
}