ref: 0a0dc432673d0c5f0902b0d053e08c8fe41a0eea
dir: /partitioner/linux.c/
#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;
}