mirror of
https://github.com/systemd/systemd-stable.git
synced 2025-01-05 09:17:44 +03:00
homework: make it safe to invoke home_setup_luks() twice in a row
Being able to invoke the call twice on the same HomeSetup object will simplify auto-growing/auto-shrinking since we can issue a resize operatio directly from activate/deactivate
This commit is contained in:
parent
5813fca61f
commit
34081f6be7
@ -1164,55 +1164,67 @@ int home_setup_luks(
|
||||
PasswordCache *cache,
|
||||
UserRecord **ret_luks_home) {
|
||||
|
||||
sd_id128_t found_partition_uuid, found_luks_uuid, found_fs_uuid;
|
||||
sd_id128_t found_partition_uuid = SD_ID128_NULL, found_luks_uuid = SD_ID128_NULL, found_fs_uuid = SD_ID128_NULL;
|
||||
_cleanup_(user_record_unrefp) UserRecord *luks_home = NULL;
|
||||
_cleanup_(erase_and_freep) void *volume_key = NULL;
|
||||
size_t volume_key_size = 0;
|
||||
uint64_t offset, size;
|
||||
struct stat st;
|
||||
int r;
|
||||
|
||||
assert(h);
|
||||
assert(setup);
|
||||
assert(setup->dm_name);
|
||||
assert(setup->dm_node);
|
||||
assert(setup->root_fd < 0);
|
||||
assert(!setup->crypt_device);
|
||||
assert(!setup->loop);
|
||||
|
||||
assert(user_record_storage(h) == USER_LUKS);
|
||||
|
||||
r = dlopen_cryptsetup();
|
||||
if (r < 0)
|
||||
return r;
|
||||
|
||||
r = make_dm_names(h, setup);
|
||||
if (r < 0)
|
||||
return r;
|
||||
|
||||
/* Reuse the image fd if it has already been opened by an earlier step */
|
||||
if (setup->image_fd < 0) {
|
||||
setup->image_fd = open_image_file(h, force_image_path, &st);
|
||||
if (setup->image_fd < 0)
|
||||
return setup->image_fd;
|
||||
} else if (fstat(setup->image_fd, &st) < 0)
|
||||
return log_error_errno(errno, "Failed to stat image: %m");
|
||||
|
||||
if (FLAGS_SET(flags, HOME_SETUP_ALREADY_ACTIVATED)) {
|
||||
struct loop_info64 info;
|
||||
const char *n;
|
||||
|
||||
r = luks_open(h,
|
||||
setup,
|
||||
cache,
|
||||
&found_luks_uuid,
|
||||
&volume_key,
|
||||
&volume_key_size);
|
||||
if (r < 0)
|
||||
return r;
|
||||
if (!setup->crypt_device) {
|
||||
r = luks_open(h,
|
||||
setup,
|
||||
cache,
|
||||
&found_luks_uuid,
|
||||
&volume_key,
|
||||
&volume_key_size);
|
||||
if (r < 0)
|
||||
return r;
|
||||
}
|
||||
|
||||
r = luks_validate_home_record(setup->crypt_device, h, volume_key, cache, &luks_home);
|
||||
if (r < 0)
|
||||
return r;
|
||||
if (ret_luks_home) {
|
||||
r = luks_validate_home_record(setup->crypt_device, h, volume_key, cache, &luks_home);
|
||||
if (r < 0)
|
||||
return r;
|
||||
}
|
||||
|
||||
n = sym_crypt_get_device_name(setup->crypt_device);
|
||||
if (!n)
|
||||
return log_error_errno(SYNTHETIC_ERRNO(EINVAL), "Failed to determine backing device for DM %s.", setup->dm_name);
|
||||
|
||||
r = loop_device_open(n, O_RDWR, &setup->loop);
|
||||
if (r < 0)
|
||||
return log_error_errno(r, "Failed to open loopback device %s: %m", n);
|
||||
if (!setup->loop) {
|
||||
r = loop_device_open(n, O_RDWR, &setup->loop);
|
||||
if (r < 0)
|
||||
return log_error_errno(r, "Failed to open loopback device %s: %m", n);
|
||||
}
|
||||
|
||||
if (ioctl(setup->loop->fd, LOOP_GET_STATUS64, &info) < 0) {
|
||||
_cleanup_free_ char *sysfs = NULL;
|
||||
struct stat st;
|
||||
|
||||
if (!IN_SET(errno, ENOTTY, EINVAL))
|
||||
return log_error_errno(errno, "Failed to get block device metrics of %s: %m", n);
|
||||
@ -1264,14 +1276,20 @@ int home_setup_luks(
|
||||
|
||||
log_info("Discovered used loopback device %s.", setup->loop->node);
|
||||
|
||||
setup->root_fd = open(user_record_home_directory(h), O_RDONLY|O_CLOEXEC|O_DIRECTORY|O_NOFOLLOW);
|
||||
if (setup->root_fd < 0)
|
||||
return log_error_errno(errno, "Failed to open home directory: %m");
|
||||
if (setup->root_fd < 0) {
|
||||
setup->root_fd = open(user_record_home_directory(h), O_RDONLY|O_CLOEXEC|O_DIRECTORY|O_NOFOLLOW);
|
||||
if (setup->root_fd < 0)
|
||||
return log_error_errno(errno, "Failed to open home directory: %m");
|
||||
}
|
||||
} else {
|
||||
_cleanup_free_ char *fstype = NULL, *subdir = NULL;
|
||||
bool has_stat = false;
|
||||
const char *ip;
|
||||
struct stat st;
|
||||
|
||||
/* When we aren't reopening the home directory we are allocating it fresh, hence the relevant
|
||||
* objects can't be allocated yet. */
|
||||
assert(setup->root_fd < 0);
|
||||
assert(!setup->crypt_device);
|
||||
assert(!setup->loop);
|
||||
|
||||
ip = force_image_path ?: user_record_image_path(h);
|
||||
|
||||
@ -1279,15 +1297,6 @@ int home_setup_luks(
|
||||
if (!subdir)
|
||||
return log_oom();
|
||||
|
||||
/* Reuse the image fd if it has already been opened by an earlier step */
|
||||
if (setup->image_fd < 0) {
|
||||
setup->image_fd = open_image_file(h, force_image_path, &st);
|
||||
if (setup->image_fd < 0)
|
||||
return setup->image_fd;
|
||||
|
||||
has_stat = true;
|
||||
}
|
||||
|
||||
r = luks_validate(setup->image_fd, user_record_user_name_and_realm(h), h->partition_uuid, &found_partition_uuid, &offset, &size);
|
||||
if (r < 0)
|
||||
return log_error_errno(r, "Failed to validate disk label: %m");
|
||||
@ -1298,7 +1307,7 @@ int home_setup_luks(
|
||||
setup->do_mark_clean = true;
|
||||
|
||||
if (!user_record_luks_discard(h)) {
|
||||
r = run_fallocate(setup->image_fd, has_stat ? &st : NULL);
|
||||
r = run_fallocate(setup->image_fd, &st);
|
||||
if (r < 0)
|
||||
return r;
|
||||
}
|
||||
@ -1331,9 +1340,11 @@ int home_setup_luks(
|
||||
|
||||
setup->undo_dm = true;
|
||||
|
||||
r = luks_validate_home_record(setup->crypt_device, h, volume_key, cache, &luks_home);
|
||||
if (r < 0)
|
||||
return r;
|
||||
if (ret_luks_home) {
|
||||
r = luks_validate_home_record(setup->crypt_device, h, volume_key, cache, &luks_home);
|
||||
if (r < 0)
|
||||
return r;
|
||||
}
|
||||
|
||||
r = fs_validate(setup->dm_node, h->file_system_uuid, &fstype, &found_fs_uuid);
|
||||
if (r < 0)
|
||||
@ -1359,13 +1370,21 @@ int home_setup_luks(
|
||||
setup->do_offline_fallocate = !(setup->do_offline_fitrim = user_record_luks_offline_discard(h));
|
||||
}
|
||||
|
||||
setup->found_partition_uuid = found_partition_uuid;
|
||||
setup->found_luks_uuid = found_luks_uuid;
|
||||
setup->found_fs_uuid = found_fs_uuid;
|
||||
if (!sd_id128_is_null(found_partition_uuid))
|
||||
setup->found_partition_uuid = found_partition_uuid;
|
||||
if (!sd_id128_is_null(found_luks_uuid))
|
||||
setup->found_luks_uuid = found_luks_uuid;
|
||||
if (!sd_id128_is_null(found_fs_uuid))
|
||||
setup->found_fs_uuid = found_fs_uuid;
|
||||
|
||||
setup->partition_offset = offset;
|
||||
setup->partition_size = size;
|
||||
setup->volume_key = TAKE_PTR(volume_key);
|
||||
setup->volume_key_size = volume_key_size;
|
||||
|
||||
if (volume_key) {
|
||||
erase_and_free(setup->volume_key);
|
||||
setup->volume_key = TAKE_PTR(volume_key);
|
||||
setup->volume_key_size = volume_key_size;
|
||||
}
|
||||
|
||||
if (ret_luks_home)
|
||||
*ret_luks_home = TAKE_PTR(luks_home);
|
||||
|
Loading…
Reference in New Issue
Block a user