shithub: neoventi

ref: d42b5ae9b1b41d92fb88cffa6bdb930c2b476570
dir: /partitioner/linux.c/

View raw version
#include "platform.h"
#include "partitioner.h"
#include <stdio.h>
#include <sys/stat.h>
#include <sys/sysmacros.h>

static const char *types[] = { "unknown", "bad", "disk", "partition", "file", };

/* Resolves partition to disk offset */
static void
probepart(Region *r)
{
	char *startpath = aprintf("/sys/class/block/%s/start", r->uuid);
	char *str = readfile(startpath, NULL);
	free(startpath);
	r->offset = atoll(str);
	free(str);
	r->type = disk;
}

static char*
extract(char *file, char *key)
{
	char *val = strstr(file, key);
	val += strlen(key) + 1;
	return strndup(val, strchr(val, '\n') - val);
}

static void
probeblock(Region *r, struct stat buf)
{
	char *devpath = aprintf("/sys/dev/block/%d:%d/uevent", major(buf.st_rdev), minor(buf.st_rdev));
	char *contents = readfile(devpath, NULL);
	char *devtype;
	free(devpath);
	devtype = extract(contents, "DEVTYPE");
	r->uuid = extract(contents, "DEVNAME");
	free(contents);
	r->type = streql(devtype, "disk") ? disk : part;
	if(r->type == part)
		probepart(r);
}

void
proberegiontype(Region *r)
{
	struct stat buf;
	if(stat(r->path, &buf) != 0 || !(buf.st_mode & (S_IFMT | S_IFBLK)))
		r->type = bad;
	else if(buf.st_mode & S_IFREG)
		r->type = file;
	else
		probeblock(r, buf);
}

void
proberegionredundancy(Region *r)
{
	/* TODO: integrate with mdadm? LUKS? cryptsetup? All of the above? */
	(void)r;
}

int
ispartofdisk(Region *maybedisk, Region *maybepart)
{
	if(maybedisk->type != disk || maybepart->type != disk)
		return 0;
	char *partpath = aprintf("/sys/class/block/%s/%s/partition", maybedisk->uuid, maybepart->uuid);
	char *contents = readfile(partpath, NULL);
	free(partpath);
	free(contents);
	return contents != NULL;
}