/*
 * device-mapper (dm) topology
 * -- this is fallback for old systems where the toplogy information are not
 *    exported by sysfs
 *
 * Copyright (C) 2009 Karel Zak <kzak@redhat.com>
 *
 * This file may be redistributed under the terms of the
 * GNU Lesser General Public License.
 *
 */
#include <errno.h>
#include <fcntl.h>
#include <stdint.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/stat.h>
#include <sys/types.h>
#include <unistd.h>

#include "topology.h"

static int is_dm_device(dev_t devno)
{
	return blkid_driver_has_major("device-mapper", major(devno));
}

static int probe_dm_tp(blkid_probe pr, const struct blkid_idmag *mag)
{
	const char *paths[] = {
		"/usr/local/sbin/dmsetup",
		"/usr/sbin/dmsetup",
		"/sbin/dmsetup"
	};
	int i, dmpipe[] = { -1, -1 }, stripes, stripesize;
	char *cmd = NULL;
	FILE *stream = NULL;
	long long  offset, size;
	dev_t devno = blkid_probe_get_devno(pr);

	if (!devno)
		goto nothing;		/* probably not a block device */
	if (!is_dm_device(devno))
		goto nothing;

	for (i = 0; i < ARRAY_SIZE(paths); i++) {
		struct stat sb;
		if (stat(paths[i], &sb) == 0) {
			cmd = (char *) paths[i];
			break;
		}
	}

	if (!cmd)
		goto nothing;
	if (pipe(dmpipe) < 0) {
		DBG(DEBUG_LOWPROBE,
			printf("Failed to open pipe: errno=%d", errno));
		goto nothing;
	}

	switch (fork()) {
	case 0:
	{
		char *dmargv[7], maj[16], min[16];

		/* Plumbing */
		close(dmpipe[0]);

		if (dmpipe[1] != STDOUT_FILENO)
			dup2(dmpipe[1], STDOUT_FILENO);

		/* The libblkid library could linked with setuid programs */
		if (setgid(getgid()) < 0)
			 exit(1);
		if (setuid(getuid()) < 0)
			 exit(1);

		snprintf(maj, sizeof(maj), "%d", major(devno));
		snprintf(min, sizeof(min), "%d", minor(devno));

		dmargv[0] = cmd;
		dmargv[1] = "table";
		dmargv[2] = "-j";
		dmargv[3] = maj;
		dmargv[4] = "-m";
		dmargv[5] = min;
		dmargv[6] = NULL;

		execv(dmargv[0], dmargv);

		DBG(DEBUG_LOWPROBE,
			printf("Failed to execute %s: errno=%d", cmd, errno));
		exit(1);
	}
	case -1:
		DBG(DEBUG_LOWPROBE,
			printf("Failed to forking: errno=%d", errno));
		goto nothing;
	default:
		break;
	}

	stream = fdopen(dmpipe[0], "r");
	if (!stream)
		goto nothing;

	i = fscanf(stream, "%lld %lld striped %d %d ",
			&offset, &size, &stripes, &stripesize);
	if (i != 4)
		goto nothing;

	blkid_topology_set_minimum_io_size(pr, stripesize << 9);
	blkid_topology_set_optimal_io_size(pr, (stripes * stripesize) << 9);

	fclose(stream);
	close(dmpipe[1]);
	return 0;

nothing:
	if (stream)
		fclose(stream);
	else if (dmpipe[0] != -1)
		close(dmpipe[0]);
	if (dmpipe[1] != -1)
		close(dmpipe[1]);
	return 1;
}

const struct blkid_idinfo dm_tp_idinfo =
{
	.name		= "dm",
	.probefunc	= probe_dm_tp,
	.magics		= BLKID_NONE_MAGIC
};

