mirror of
https://github.com/systemd/systemd.git
synced 2024-12-22 17:35:35 +03:00
Merge pull request #21331 from poettering/luks-extra-mount-options
homed: allow per-user additional LUKS mount options
This commit is contained in:
commit
b1beb00406
@ -476,6 +476,9 @@ executed to make sure the image matches the selected option.
|
||||
to trim/allocate the file system/backing file when deactivating the home
|
||||
directory.
|
||||
|
||||
`luksExtraMountOptions` → A string with additional mount options to append to
|
||||
the default mount options for the file system in the LUKS volume.
|
||||
|
||||
`luksCipher` → A string, indicating the cipher to use for the LUKS storage mechanism.
|
||||
|
||||
`luksCipherMode` → A string, selecting the cipher mode to use for the LUKS storage mechanism.
|
||||
|
@ -656,6 +656,14 @@
|
||||
to on, to ensure disk space is minimized while a user is not logged in.</para></listitem>
|
||||
</varlistentry>
|
||||
|
||||
<varlistentry>
|
||||
<term><option>--luks-extra-mount-options=</option><replaceable>OPTIONS</replaceable></term>
|
||||
|
||||
<listitem><para>Takes a string containing additional mount options to use when mounting the LUKS
|
||||
volume. If specified, this string will be appended to the default, built-in mount
|
||||
options.</para></listitem>
|
||||
</varlistentry>
|
||||
|
||||
<varlistentry>
|
||||
<term><option>--luks-cipher=</option><replaceable>CIPHER</replaceable></term>
|
||||
<term><option>--luks-cipher-mode=</option><replaceable>MODE</replaceable></term>
|
||||
|
@ -2153,6 +2153,8 @@ static int help(int argc, char *argv[], void *userdata) {
|
||||
" Memory cost for PBKDF in bytes\n"
|
||||
" --luks-pbkdf-parallel-threads=NUMBER\n"
|
||||
" Number of parallel threads for PKBDF\n"
|
||||
" --luks-extra-mount-options=OPTIONS\n"
|
||||
" LUKS extra mount options\n"
|
||||
"\n%4$sMounting User Record Properties:%5$s\n"
|
||||
" --nosuid=BOOL Control the 'nosuid' flag of the home mount\n"
|
||||
" --nodev=BOOL Control the 'nodev' flag of the home mount\n"
|
||||
@ -2251,6 +2253,7 @@ static int parse_argv(int argc, char *argv[]) {
|
||||
ARG_AND_RESIZE,
|
||||
ARG_AND_CHANGE_PASSWORD,
|
||||
ARG_DROP_CACHES,
|
||||
ARG_LUKS_EXTRA_MOUNT_OPTIONS,
|
||||
};
|
||||
|
||||
static const struct option options[] = {
|
||||
@ -2335,6 +2338,7 @@ static int parse_argv(int argc, char *argv[]) {
|
||||
{ "and-resize", required_argument, NULL, ARG_AND_RESIZE },
|
||||
{ "and-change-password", required_argument, NULL, ARG_AND_CHANGE_PASSWORD },
|
||||
{ "drop-caches", required_argument, NULL, ARG_DROP_CACHES },
|
||||
{ "luks-extra-mount-options", required_argument, NULL, ARG_LUKS_EXTRA_MOUNT_OPTIONS },
|
||||
{}
|
||||
};
|
||||
|
||||
@ -2452,7 +2456,8 @@ static int parse_argv(int argc, char *argv[]) {
|
||||
case ARG_ICON_NAME:
|
||||
case ARG_CIFS_USER_NAME:
|
||||
case ARG_CIFS_DOMAIN:
|
||||
case ARG_CIFS_EXTRA_MOUNT_OPTIONS: {
|
||||
case ARG_CIFS_EXTRA_MOUNT_OPTIONS:
|
||||
case ARG_LUKS_EXTRA_MOUNT_OPTIONS: {
|
||||
|
||||
const char *field =
|
||||
c == ARG_EMAIL_ADDRESS ? "emailAddress" :
|
||||
@ -2461,6 +2466,7 @@ static int parse_argv(int argc, char *argv[]) {
|
||||
c == ARG_CIFS_USER_NAME ? "cifsUserName" :
|
||||
c == ARG_CIFS_DOMAIN ? "cifsDomain" :
|
||||
c == ARG_CIFS_EXTRA_MOUNT_OPTIONS ? "cifsExtraMountOptions" :
|
||||
c == ARG_LUKS_EXTRA_MOUNT_OPTIONS ? "luksExtraMountOptions" :
|
||||
NULL;
|
||||
|
||||
assert(field);
|
||||
|
@ -1352,7 +1352,7 @@ int home_setup_luks(
|
||||
if (r < 0)
|
||||
return r;
|
||||
|
||||
r = home_unshare_and_mount(setup->dm_node, fstype, user_record_luks_discard(h), user_record_mount_flags(h));
|
||||
r = home_unshare_and_mount(setup->dm_node, fstype, user_record_luks_discard(h), user_record_mount_flags(h), h->luks_extra_mount_options);
|
||||
if (r < 0)
|
||||
return r;
|
||||
|
||||
@ -2223,7 +2223,7 @@ int home_create_luks(
|
||||
|
||||
log_info("Formatting file system completed.");
|
||||
|
||||
r = home_unshare_and_mount(setup->dm_node, fstype, user_record_luks_discard(h), user_record_mount_flags(h));
|
||||
r = home_unshare_and_mount(setup->dm_node, fstype, user_record_luks_discard(h), user_record_mount_flags(h), h->luks_extra_mount_options);
|
||||
if (r < 0)
|
||||
return r;
|
||||
|
||||
@ -2413,7 +2413,13 @@ static int can_resize_fs(int fd, uint64_t old_size, uint64_t new_size) {
|
||||
return CAN_RESIZE_ONLINE;
|
||||
}
|
||||
|
||||
static int ext4_offline_resize_fs(HomeSetup *setup, uint64_t new_size, bool discard, unsigned long flags) {
|
||||
static int ext4_offline_resize_fs(
|
||||
HomeSetup *setup,
|
||||
uint64_t new_size,
|
||||
bool discard,
|
||||
unsigned long flags,
|
||||
const char *extra_mount_options) {
|
||||
|
||||
_cleanup_free_ char *size_str = NULL;
|
||||
bool re_open = false, re_mount = false;
|
||||
pid_t resize_pid, fsck_pid;
|
||||
@ -2488,7 +2494,7 @@ static int ext4_offline_resize_fs(HomeSetup *setup, uint64_t new_size, bool disc
|
||||
|
||||
/* Re-establish mounts and reopen the directory */
|
||||
if (re_mount) {
|
||||
r = home_mount_node(setup->dm_node, "ext4", discard, flags);
|
||||
r = home_mount_node(setup->dm_node, "ext4", discard, flags, extra_mount_options);
|
||||
if (r < 0)
|
||||
return r;
|
||||
|
||||
@ -2930,7 +2936,7 @@ int home_resize_luks(
|
||||
if (r < 0)
|
||||
return log_error_errno(r, "Failed to resize file system: %m");
|
||||
} else {
|
||||
r = ext4_offline_resize_fs(setup, new_fs_size, user_record_luks_discard(h), user_record_mount_flags(h));
|
||||
r = ext4_offline_resize_fs(setup, new_fs_size, user_record_luks_discard(h), user_record_mount_flags(h), h->luks_extra_mount_options);
|
||||
if (r < 0)
|
||||
return r;
|
||||
}
|
||||
|
@ -40,28 +40,35 @@ static const char *mount_options_for_fstype(const char *fstype) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
int home_mount_node(const char *node, const char *fstype, bool discard, unsigned long flags) {
|
||||
int home_mount_node(
|
||||
const char *node,
|
||||
const char *fstype,
|
||||
bool discard,
|
||||
unsigned long flags,
|
||||
const char *extra_mount_options) {
|
||||
|
||||
_cleanup_free_ char *joined = NULL;
|
||||
const char *options, *discard_option;
|
||||
const char *default_options;
|
||||
int r;
|
||||
|
||||
assert(node);
|
||||
assert(fstype);
|
||||
|
||||
options = mount_options_for_fstype(fstype);
|
||||
|
||||
discard_option = discard ? "discard" : "nodiscard";
|
||||
|
||||
if (options) {
|
||||
joined = strjoin(options, ",", discard_option);
|
||||
if (!joined)
|
||||
default_options = mount_options_for_fstype(fstype);
|
||||
if (default_options) {
|
||||
if (!strextend_with_separator(&joined, ",", default_options))
|
||||
return log_oom();
|
||||
}
|
||||
|
||||
options = joined;
|
||||
} else
|
||||
options = discard_option;
|
||||
if (!strextend_with_separator(&joined, ",", discard ? "discard" : "nodiscard"))
|
||||
return log_oom();
|
||||
|
||||
r = mount_nofollow_verbose(LOG_ERR, node, HOME_RUNTIME_WORK_DIR, fstype, flags|MS_RELATIME, strempty(options));
|
||||
if (extra_mount_options) {
|
||||
if (!strextend_with_separator(&joined, ",", extra_mount_options))
|
||||
return log_oom();
|
||||
}
|
||||
|
||||
r = mount_nofollow_verbose(LOG_ERR, node, HOME_RUNTIME_WORK_DIR, fstype, flags|MS_RELATIME, joined);
|
||||
if (r < 0)
|
||||
return r;
|
||||
|
||||
@ -85,7 +92,13 @@ int home_unshare_and_mkdir(void) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
int home_unshare_and_mount(const char *node, const char *fstype, bool discard, unsigned long flags) {
|
||||
int home_unshare_and_mount(
|
||||
const char *node,
|
||||
const char *fstype,
|
||||
bool discard,
|
||||
unsigned long flags,
|
||||
const char *extra_mount_options) {
|
||||
|
||||
int r;
|
||||
|
||||
assert(node);
|
||||
@ -95,7 +108,7 @@ int home_unshare_and_mount(const char *node, const char *fstype, bool discard, u
|
||||
if (r < 0)
|
||||
return r;
|
||||
|
||||
r = home_mount_node(node, fstype, discard, flags);
|
||||
r = home_mount_node(node, fstype, discard, flags, extra_mount_options);
|
||||
if (r < 0)
|
||||
return r;
|
||||
|
||||
|
@ -3,8 +3,8 @@
|
||||
|
||||
#include <stdbool.h>
|
||||
|
||||
int home_mount_node(const char *node, const char *fstype, bool discard, unsigned long flags);
|
||||
int home_mount_node(const char *node, const char *fstype, bool discard, unsigned long flags, const char *extra_mount_options);
|
||||
int home_unshare_and_mkdir(void);
|
||||
int home_unshare_and_mount(const char *node, const char *fstype, bool discard, unsigned long flags);
|
||||
int home_unshare_and_mount(const char *node, const char *fstype, bool discard, unsigned long flags, const char *extra_mount_options);
|
||||
int home_move_mount(const char *user_name_and_realm, const char *target);
|
||||
int home_shift_uid(int dir_fd, const char *target, uid_t stored_uid, uid_t exposed_uid, int *ret_mount_fd);
|
||||
|
@ -284,6 +284,9 @@ void user_record_show(UserRecord *hr, bool show_full_group_info) {
|
||||
if (hr->file_system_type)
|
||||
printf(" File System: %s\n", user_record_file_system_type(hr));
|
||||
|
||||
if (hr->luks_extra_mount_options)
|
||||
printf("LUKS MntOpts: %s\n", hr->luks_extra_mount_options);
|
||||
|
||||
if (hr->luks_cipher)
|
||||
printf(" LUKS Cipher: %s\n", hr->luks_cipher);
|
||||
if (hr->luks_cipher_mode)
|
||||
|
@ -285,6 +285,7 @@ static UserRecord* user_record_free(UserRecord *h) {
|
||||
free(h->luks_cipher_mode);
|
||||
free(h->luks_pbkdf_hash_algorithm);
|
||||
free(h->luks_pbkdf_type);
|
||||
free(h->luks_extra_mount_options);
|
||||
|
||||
free(h->state);
|
||||
free(h->service);
|
||||
@ -1287,6 +1288,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 },
|
||||
{ "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 },
|
||||
{ "rateLimitIntervalUSec", JSON_VARIANT_UNSIGNED, json_dispatch_uint64, offsetof(UserRecord, ratelimit_interval_usec), 0 },
|
||||
{ "rateLimitBurst", JSON_VARIANT_UNSIGNED, json_dispatch_uint64, offsetof(UserRecord, ratelimit_burst), 0 },
|
||||
@ -1634,6 +1636,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 },
|
||||
{ "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 },
|
||||
{ "service", JSON_VARIANT_STRING, json_dispatch_string, offsetof(UserRecord, service), JSON_SAFE },
|
||||
{ "rateLimitIntervalUSec", JSON_VARIANT_UNSIGNED, json_dispatch_uint64, offsetof(UserRecord, ratelimit_interval_usec), 0 },
|
||||
|
@ -331,6 +331,7 @@ typedef struct UserRecord {
|
||||
uint64_t luks_pbkdf_time_cost_usec;
|
||||
uint64_t luks_pbkdf_memory_cost;
|
||||
uint64_t luks_pbkdf_parallel_threads;
|
||||
char *luks_extra_mount_options;
|
||||
|
||||
uint64_t disk_usage;
|
||||
uint64_t disk_free;
|
||||
|
Loading…
Reference in New Issue
Block a user