Exemple #1
0
static void test_loop_scan(int flags, int debug)
{
	struct loopdev_cxt lc;
	int rc;

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

	if (loopcxt_init_iterator(&lc, flags))
		err(EXIT_FAILURE, "iterator initlization failed");

	while((rc = loopcxt_next(&lc)) == 0) {
		const char *device = loopcxt_get_device(&lc);

		if (flags & LOOPITER_FL_USED) {
			char *backing = loopcxt_get_backing_file(&lc);
			printf("\t%s: %s\n", device, backing);
			free(backing);
		} else
			printf("\t%s\n", device);
	}

	if (rc < 0)
		err(EXIT_FAILURE, "loopdevs scanning failed");

	loopcxt_deinit(&lc);
}
Exemple #2
0
/**
 * mnt_pretty_path:
 * @path: any path
 * @cache: NULL or pointer to the cache
 *
 * Converts path:
 *	- to the absolute path
 *	- /dev/dm-N to /dev/mapper/name
 *	- /dev/loopN to the loop backing filename
 *	- empty path (NULL) to 'none'
 *
 * Returns: newly allocated string with path, result always has to be deallocated
 *          by free().
 */
char *mnt_pretty_path(const char *path, struct libmnt_cache *cache)
{
	char *pretty = mnt_resolve_path(path, cache);

	if (!pretty)
		return strdup("none");

#ifdef __linux__
	/* users assume backing file name rather than /dev/loopN in
	 * output if the device has been initialized by mount(8).
	 */
	if (strncmp(pretty, "/dev/loop", 9) == 0) {
		struct loopdev_cxt lc;

		if (loopcxt_init(&lc, 0) || loopcxt_set_device(&lc, pretty))
			goto done;

		if (loopcxt_is_autoclear(&lc)) {
			char *tmp = loopcxt_get_backing_file(&lc);
			if (tmp) {
				if (!cache)
					free(pretty);	/* not cached, deallocate */
				return tmp;		/* return backing file */
			}
		}
		loopcxt_deinit(&lc);

	}
#endif

done:
	/* don't return pointer to the cache, allocate a new string */
	return cache ? strdup(pretty) : pretty;
}
Exemple #3
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);
}
Exemple #4
0
/*
 * Returns number of loop devices associated with @file, if only one loop
 * device is associeted with the given @filename and @loopdev is not NULL then
 * @loopdev returns name of the device.
 */
int loopdev_count_by_backing_file(const char *filename, char **loopdev)
{
	struct loopdev_cxt lc;
	int count = 0;

	if (!filename)
		return -1;

	loopcxt_init(&lc, 0);
	if (loopcxt_init_iterator(&lc, LOOPITER_FL_USED))
		return -1;

	while(loopcxt_next(&lc) == 0) {
		char *backing = loopcxt_get_backing_file(&lc);

		if (!backing || strcmp(backing, filename)) {
			free(backing);
			continue;
		}

		free(backing);
		if (loopdev && count == 0)
			*loopdev = loopcxt_strdup_device(&lc);
		count++;
	}

	loopcxt_deinit(&lc);

	if (loopdev && count > 1) {
		free(*loopdev);
		*loopdev = NULL;
	}
	return count;
}
Exemple #5
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;
}
Exemple #6
0
char *loopdev_get_backing_file(const char *device)
{
	struct loopdev_cxt lc;
	char *res;

	if (!device)
		return NULL;

	loopcxt_init(&lc, 0);
	loopcxt_set_device(&lc, device);
	res = loopcxt_get_backing_file(&lc);
	loopcxt_deinit(&lc);

	return res;
}
Exemple #7
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;
}