mirror of
https://github.com/systemd/systemd.git
synced 2026-08-03 22:50:29 +00:00
blockdev-util: split out partition device node generation from dissect-util.c
This commit is contained in:
@@ -904,3 +904,46 @@ int blockdev_get_root(int level, dev_t *ret) {
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
int partition_node_of(const char *node, unsigned nr, char **ret) {
|
||||
int r;
|
||||
|
||||
assert(node);
|
||||
assert(nr > 0);
|
||||
assert(ret);
|
||||
|
||||
/* Given a device node path to a block device returns the device node path to the partition block
|
||||
* device of the specified partition */
|
||||
|
||||
_cleanup_free_ char *fn = NULL;
|
||||
r = path_extract_filename(node, &fn);
|
||||
if (r < 0)
|
||||
return r;
|
||||
if (r == O_DIRECTORY)
|
||||
return -EISDIR;
|
||||
|
||||
_cleanup_free_ char *dn = NULL;
|
||||
r = path_extract_directory(node, &dn);
|
||||
if (r < 0 && r != -EDESTADDRREQ) /* allow if only filename is specified */
|
||||
return r;
|
||||
|
||||
size_t l = strlen(fn);
|
||||
assert(l > 0); /* underflow check for the subtraction below */
|
||||
|
||||
bool need_p = ascii_isdigit(fn[l-1]); /* Last char a digit? */
|
||||
|
||||
_cleanup_free_ char *subnode = NULL;
|
||||
if (asprintf(&subnode, "%s%s%u", fn, need_p ? "p" : "", nr) < 0)
|
||||
return -ENOMEM;
|
||||
|
||||
if (dn) {
|
||||
_cleanup_free_ char *j = path_join(dn, subnode);
|
||||
if (!j)
|
||||
return -ENOMEM;
|
||||
|
||||
*ret = TAKE_PTR(j);
|
||||
} else
|
||||
*ret = TAKE_PTR(subnode);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -57,3 +57,5 @@ int blockdev_get_sector_size(int fd, uint32_t *ret);
|
||||
int blockdev_get_device_size(int fd, uint64_t *ret);
|
||||
|
||||
int blockdev_get_root(int level, dev_t *ret);
|
||||
|
||||
int partition_node_of(const char *node, unsigned nr, char **ret);
|
||||
|
||||
@@ -627,14 +627,9 @@ static int make_partition_devname(
|
||||
if (!s)
|
||||
return -ENOMEM;
|
||||
} else {
|
||||
size_t l = strlen(whole_devname);
|
||||
if (l < 1) /* underflow check for the subtraction below */
|
||||
return -EINVAL;
|
||||
|
||||
bool need_p = ascii_isdigit(whole_devname[l-1]); /* Last char a digit? */
|
||||
|
||||
if (asprintf(&s, "%s%s%i", whole_devname, need_p ? "p" : "", nr) < 0)
|
||||
return -ENOMEM;
|
||||
r = partition_node_of(whole_devname, nr, &s);
|
||||
if (r < 0)
|
||||
return r;
|
||||
}
|
||||
} else {
|
||||
if (nr < 0) /* whole disk? */
|
||||
|
||||
@@ -77,4 +77,30 @@ TEST(partscan_enabled) {
|
||||
}
|
||||
}
|
||||
|
||||
static void test_partition_node_of_one(const char *main, unsigned partition, const char *result, int retval) {
|
||||
_cleanup_free_ char *s = NULL;
|
||||
int r;
|
||||
|
||||
r = partition_node_of(main, partition, &s);
|
||||
ASSERT_EQ(r, retval);
|
||||
if (r < 0)
|
||||
return;
|
||||
ASSERT_STREQ(s, result);
|
||||
|
||||
log_info("%s with %u → %s", main, partition, result);
|
||||
}
|
||||
|
||||
TEST(partition_node_of) {
|
||||
test_partition_node_of_one("/dev/sda", 2, "/dev/sda2", 0);
|
||||
test_partition_node_of_one("sda", 3, "sda3", 0);
|
||||
test_partition_node_of_one("/dev/nvme0n1", 7, "/dev/nvme0n1p7", 0);
|
||||
test_partition_node_of_one("nvme0n1", 8, "nvme0n1p8", 0);
|
||||
test_partition_node_of_one("/dev/loop1", 3, "/dev/loop1p3", 0);
|
||||
test_partition_node_of_one("", 1, NULL, -EINVAL);
|
||||
test_partition_node_of_one("/", 1, NULL, -EADDRNOTAVAIL);
|
||||
test_partition_node_of_one("/dev/", 1, NULL, -EISDIR);
|
||||
test_partition_node_of_one("/sda", 1, "/sda1", 0);
|
||||
test_partition_node_of_one(".", 1, NULL, -EADDRNOTAVAIL);
|
||||
}
|
||||
|
||||
DEFINE_TEST_MAIN(LOG_INFO);
|
||||
|
||||
Reference in New Issue
Block a user