Implement --luks-sector-size for homed

This commit is contained in:
Aidan Dang
2022-10-07 16:36:04 +02:00
committed by Luca Boccassi
parent b25e08a752
commit fd83c98e8a
12 changed files with 98 additions and 14 deletions
+18 -3
View File
@@ -123,6 +123,17 @@ static int loop_configure_verify(int fd, const struct loop_config *c) {
assert(fd >= 0);
assert(c);
if (c->block_size != 0) {
int z;
if (ioctl(fd, BLKSSZGET, &z) < 0)
return -errno;
assert(z >= 0);
if ((uint32_t) z != c->block_size)
log_debug("LOOP_CONFIGURE didn't honour requested block size %u, got %i instead. Ignoring.", c->block_size, z);
}
if (c->info.lo_sizelimit != 0) {
/* Kernel 5.8 vanilla doesn't properly propagate the size limit into the
* block device. If it's used, let's immediately check if it had the desired
@@ -133,7 +144,7 @@ static int loop_configure_verify(int fd, const struct loop_config *c) {
return -errno;
if (z != c->info.lo_sizelimit) {
log_debug("LOOP_CONFIGURE is broken, doesn't honour .lo_sizelimit. Falling back to LOOP_SET_STATUS64.");
log_debug("LOOP_CONFIGURE is broken, doesn't honour .info.lo_sizelimit. Falling back to LOOP_SET_STATUS64.");
broken = true;
}
}
@@ -171,7 +182,7 @@ static int loop_configure_fallback(int fd, const struct loop_config *c) {
info_copy.lo_flags &= LOOP_SET_STATUS_SETTABLE_FLAGS;
/* Since kernel commit 5db470e229e22b7eda6e23b5566e532c96fb5bc3 (kernel v5.0) the LOOP_SET_STATUS64
* ioctl can return EAGAIN in case we change the lo_offset field, if someone else is accessing the
* ioctl can return EAGAIN in case we change the info.lo_offset field, if someone else is accessing the
* block device while we try to reconfigure it. This is a pretty common case, since udev might
* instantly start probing the device as soon as we attach an fd to it. Hence handle it in two ways:
* first, let's take the BSD lock to ensure that udev will not step in between the point in
@@ -391,6 +402,7 @@ static int loop_device_make_internal(
int open_flags,
uint64_t offset,
uint64_t size,
uint32_t block_size,
uint32_t loop_flags,
int lock_op,
LoopDevice **ret) {
@@ -463,6 +475,7 @@ static int loop_device_make_internal(
config = (struct loop_config) {
.fd = fd,
.block_size = block_size,
.info = {
/* Use the specified flags, but configure the read-only flag from the open flags, and force autoclear */
.lo_flags = (loop_flags & ~LO_FLAGS_READ_ONLY) | ((open_flags & O_ACCMODE) == O_RDONLY ? LO_FLAGS_READ_ONLY : 0) | LO_FLAGS_AUTOCLEAR,
@@ -546,6 +559,7 @@ int loop_device_make(
int open_flags,
uint64_t offset,
uint64_t size,
uint32_t block_size,
uint32_t loop_flags,
int lock_op,
LoopDevice **ret) {
@@ -559,6 +573,7 @@ int loop_device_make(
open_flags,
offset,
size,
block_size,
loop_flags_mangle(loop_flags),
lock_op,
ret);
@@ -622,7 +637,7 @@ int loop_device_make_by_path(
direct ? "enabled" : "disabled",
direct != (direct_flags != 0) ? " (O_DIRECT was requested but not supported)" : "");
return loop_device_make_internal(path, fd, open_flags, 0, 0, loop_flags, lock_op, ret);
return loop_device_make_internal(path, fd, open_flags, 0, 0, 0, loop_flags, lock_op, ret);
}
static LoopDevice* loop_device_free(LoopDevice *d) {
+1 -1
View File
@@ -28,7 +28,7 @@ struct LoopDevice {
/* Returns true if LoopDevice object is not actually a loopback device but some other block device we just wrap */
#define LOOP_DEVICE_IS_FOREIGN(d) ((d)->nr < 0)
int loop_device_make(int fd, int open_flags, uint64_t offset, uint64_t size, uint32_t loop_flags, int lock_op, LoopDevice **ret);
int loop_device_make(int fd, int open_flags, uint64_t offset, uint64_t size, uint32_t block_size, uint32_t loop_flags, int lock_op, LoopDevice **ret);
int loop_device_make_by_path(const char *path, int open_flags, uint32_t loop_flags, int lock_op, LoopDevice **ret);
int loop_device_open(sd_device *dev, int open_flags, int lock_op, LoopDevice **ret);
int loop_device_open_from_fd(int fd, int open_flags, int lock_op, LoopDevice **ret);
+2
View File
@@ -321,6 +321,8 @@ void user_record_show(UserRecord *hr, bool show_full_group_info) {
if (hr->luks_pbkdf_parallel_threads != UINT64_MAX)
printf("PBKDF Thread: %" PRIu64 "\n", hr->luks_pbkdf_parallel_threads);
if (hr->luks_sector_size != UINT64_MAX)
printf(" Sector Size: %" PRIu64 "\n", hr->luks_sector_size);
} else if (storage == USER_CIFS) {
+13
View File
@@ -58,6 +58,7 @@ UserRecord* user_record_new(void) {
.luks_pbkdf_time_cost_usec = UINT64_MAX,
.luks_pbkdf_memory_cost = UINT64_MAX,
.luks_pbkdf_parallel_threads = UINT64_MAX,
.luks_sector_size = UINT64_MAX,
.disk_usage = UINT64_MAX,
.disk_free = UINT64_MAX,
.disk_ceiling = UINT64_MAX,
@@ -1215,6 +1216,7 @@ static int dispatch_per_machine(const char *name, JsonVariant *variant, JsonDisp
{ "luksPbkdfTimeCostUSec", JSON_VARIANT_UNSIGNED, json_dispatch_uint64, offsetof(UserRecord, luks_pbkdf_time_cost_usec), 0 },
{ "luksPbkdfMemoryCost", JSON_VARIANT_UNSIGNED, json_dispatch_uint64, offsetof(UserRecord, luks_pbkdf_memory_cost), 0 },
{ "luksPbkdfParallelThreads", JSON_VARIANT_UNSIGNED, json_dispatch_uint64, offsetof(UserRecord, luks_pbkdf_parallel_threads), 0 },
{ "luksSectorSize", JSON_VARIANT_UNSIGNED, json_dispatch_uint64, offsetof(UserRecord, luks_sector_size), 0 },
{ "luksExtraMountOptions", JSON_VARIANT_STRING, json_dispatch_string, offsetof(UserRecord, luks_extra_mount_options), 0 },
{ "dropCaches", JSON_VARIANT_BOOLEAN, json_dispatch_tristate, offsetof(UserRecord, drop_caches), 0 },
{ "autoResizeMode", _JSON_VARIANT_TYPE_INVALID, dispatch_auto_resize_mode, offsetof(UserRecord, auto_resize_mode), 0 },
@@ -1567,6 +1569,7 @@ int user_record_load(UserRecord *h, JsonVariant *v, UserRecordLoadFlags load_fla
{ "luksPbkdfTimeCostUSec", JSON_VARIANT_UNSIGNED, json_dispatch_uint64, offsetof(UserRecord, luks_pbkdf_time_cost_usec), 0 },
{ "luksPbkdfMemoryCost", JSON_VARIANT_UNSIGNED, json_dispatch_uint64, offsetof(UserRecord, luks_pbkdf_memory_cost), 0 },
{ "luksPbkdfParallelThreads", JSON_VARIANT_UNSIGNED, json_dispatch_uint64, offsetof(UserRecord, luks_pbkdf_parallel_threads), 0 },
{ "luksSectorSize", JSON_VARIANT_UNSIGNED, json_dispatch_uint64, offsetof(UserRecord, luks_sector_size), 0 },
{ "luksExtraMountOptions", JSON_VARIANT_STRING, json_dispatch_string, offsetof(UserRecord, luks_extra_mount_options), 0 },
{ "dropCaches", JSON_VARIANT_BOOLEAN, json_dispatch_tristate, offsetof(UserRecord, drop_caches), 0 },
{ "autoResizeMode", _JSON_VARIANT_TYPE_INVALID, dispatch_auto_resize_mode, offsetof(UserRecord, auto_resize_mode), 0 },
@@ -1871,6 +1874,16 @@ uint64_t user_record_luks_pbkdf_parallel_threads(UserRecord *h) {
return MIN(h->luks_pbkdf_parallel_threads, UINT32_MAX);
}
uint64_t user_record_luks_sector_size(UserRecord *h) {
assert(h);
if (h->luks_sector_size == UINT64_MAX)
return 512;
/* Allow up to 4K due to dm-crypt support and 4K alignment by the homed LUKS backend */
return CLAMP(UINT64_C(1) << (63 - __builtin_clzl(h->luks_sector_size)), 512U, 4096U);
}
const char *user_record_luks_pbkdf_hash_algorithm(UserRecord *h) {
assert(h);
+2
View File
@@ -312,6 +312,7 @@ typedef struct UserRecord {
uint64_t luks_pbkdf_time_cost_usec;
uint64_t luks_pbkdf_memory_cost;
uint64_t luks_pbkdf_parallel_threads;
uint64_t luks_sector_size;
char *luks_extra_mount_options;
uint64_t disk_usage;
@@ -396,6 +397,7 @@ const char* user_record_luks_pbkdf_type(UserRecord *h);
usec_t user_record_luks_pbkdf_time_cost_usec(UserRecord *h);
uint64_t user_record_luks_pbkdf_memory_cost(UserRecord *h);
uint64_t user_record_luks_pbkdf_parallel_threads(UserRecord *h);
uint64_t user_record_luks_sector_size(UserRecord *h);
const char *user_record_luks_pbkdf_hash_algorithm(UserRecord *h);
gid_t user_record_gid(UserRecord *h);
UserDisposition user_record_disposition(UserRecord *h);