Skip to content

Commit b1beb00

Browse files
authored
Merge pull request systemd#21331 from poettering/luks-extra-mount-options
homed: allow per-user additional LUKS mount options
2 parents 9cc6154 + 5dd57a0 commit b1beb00

File tree

9 files changed

+65
-22
lines changed

9 files changed

+65
-22
lines changed

docs/USER_RECORD.md

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -476,6 +476,9 @@ executed to make sure the image matches the selected option.
476476
to trim/allocate the file system/backing file when deactivating the home
477477
directory.
478478

479+
`luksExtraMountOptions` → A string with additional mount options to append to
480+
the default mount options for the file system in the LUKS volume.
481+
479482
`luksCipher` → A string, indicating the cipher to use for the LUKS storage mechanism.
480483

481484
`luksCipherMode` → A string, selecting the cipher mode to use for the LUKS storage mechanism.

man/homectl.xml

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -656,6 +656,14 @@
656656
to on, to ensure disk space is minimized while a user is not logged in.</para></listitem>
657657
</varlistentry>
658658

659+
<varlistentry>
660+
<term><option>--luks-extra-mount-options=</option><replaceable>OPTIONS</replaceable></term>
661+
662+
<listitem><para>Takes a string containing additional mount options to use when mounting the LUKS
663+
volume. If specified, this string will be appended to the default, built-in mount
664+
options.</para></listitem>
665+
</varlistentry>
666+
659667
<varlistentry>
660668
<term><option>--luks-cipher=</option><replaceable>CIPHER</replaceable></term>
661669
<term><option>--luks-cipher-mode=</option><replaceable>MODE</replaceable></term>

src/home/homectl.c

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2153,6 +2153,8 @@ static int help(int argc, char *argv[], void *userdata) {
21532153
" Memory cost for PBKDF in bytes\n"
21542154
" --luks-pbkdf-parallel-threads=NUMBER\n"
21552155
" Number of parallel threads for PKBDF\n"
2156+
" --luks-extra-mount-options=OPTIONS\n"
2157+
" LUKS extra mount options\n"
21562158
"\n%4$sMounting User Record Properties:%5$s\n"
21572159
" --nosuid=BOOL Control the 'nosuid' flag of the home mount\n"
21582160
" --nodev=BOOL Control the 'nodev' flag of the home mount\n"
@@ -2251,6 +2253,7 @@ static int parse_argv(int argc, char *argv[]) {
22512253
ARG_AND_RESIZE,
22522254
ARG_AND_CHANGE_PASSWORD,
22532255
ARG_DROP_CACHES,
2256+
ARG_LUKS_EXTRA_MOUNT_OPTIONS,
22542257
};
22552258

22562259
static const struct option options[] = {
@@ -2335,6 +2338,7 @@ static int parse_argv(int argc, char *argv[]) {
23352338
{ "and-resize", required_argument, NULL, ARG_AND_RESIZE },
23362339
{ "and-change-password", required_argument, NULL, ARG_AND_CHANGE_PASSWORD },
23372340
{ "drop-caches", required_argument, NULL, ARG_DROP_CACHES },
2341+
{ "luks-extra-mount-options", required_argument, NULL, ARG_LUKS_EXTRA_MOUNT_OPTIONS },
23382342
{}
23392343
};
23402344

@@ -2452,7 +2456,8 @@ static int parse_argv(int argc, char *argv[]) {
24522456
case ARG_ICON_NAME:
24532457
case ARG_CIFS_USER_NAME:
24542458
case ARG_CIFS_DOMAIN:
2455-
case ARG_CIFS_EXTRA_MOUNT_OPTIONS: {
2459+
case ARG_CIFS_EXTRA_MOUNT_OPTIONS:
2460+
case ARG_LUKS_EXTRA_MOUNT_OPTIONS: {
24562461

24572462
const char *field =
24582463
c == ARG_EMAIL_ADDRESS ? "emailAddress" :
@@ -2461,6 +2466,7 @@ static int parse_argv(int argc, char *argv[]) {
24612466
c == ARG_CIFS_USER_NAME ? "cifsUserName" :
24622467
c == ARG_CIFS_DOMAIN ? "cifsDomain" :
24632468
c == ARG_CIFS_EXTRA_MOUNT_OPTIONS ? "cifsExtraMountOptions" :
2469+
c == ARG_LUKS_EXTRA_MOUNT_OPTIONS ? "luksExtraMountOptions" :
24642470
NULL;
24652471

24662472
assert(field);

src/home/homework-luks.c

Lines changed: 11 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1352,7 +1352,7 @@ int home_setup_luks(
13521352
if (r < 0)
13531353
return r;
13541354

1355-
r = home_unshare_and_mount(setup->dm_node, fstype, user_record_luks_discard(h), user_record_mount_flags(h));
1355+
r = home_unshare_and_mount(setup->dm_node, fstype, user_record_luks_discard(h), user_record_mount_flags(h), h->luks_extra_mount_options);
13561356
if (r < 0)
13571357
return r;
13581358

@@ -2223,7 +2223,7 @@ int home_create_luks(
22232223

22242224
log_info("Formatting file system completed.");
22252225

2226-
r = home_unshare_and_mount(setup->dm_node, fstype, user_record_luks_discard(h), user_record_mount_flags(h));
2226+
r = home_unshare_and_mount(setup->dm_node, fstype, user_record_luks_discard(h), user_record_mount_flags(h), h->luks_extra_mount_options);
22272227
if (r < 0)
22282228
return r;
22292229

@@ -2413,7 +2413,13 @@ static int can_resize_fs(int fd, uint64_t old_size, uint64_t new_size) {
24132413
return CAN_RESIZE_ONLINE;
24142414
}
24152415

2416-
static int ext4_offline_resize_fs(HomeSetup *setup, uint64_t new_size, bool discard, unsigned long flags) {
2416+
static int ext4_offline_resize_fs(
2417+
HomeSetup *setup,
2418+
uint64_t new_size,
2419+
bool discard,
2420+
unsigned long flags,
2421+
const char *extra_mount_options) {
2422+
24172423
_cleanup_free_ char *size_str = NULL;
24182424
bool re_open = false, re_mount = false;
24192425
pid_t resize_pid, fsck_pid;
@@ -2488,7 +2494,7 @@ static int ext4_offline_resize_fs(HomeSetup *setup, uint64_t new_size, bool disc
24882494

24892495
/* Re-establish mounts and reopen the directory */
24902496
if (re_mount) {
2491-
r = home_mount_node(setup->dm_node, "ext4", discard, flags);
2497+
r = home_mount_node(setup->dm_node, "ext4", discard, flags, extra_mount_options);
24922498
if (r < 0)
24932499
return r;
24942500

@@ -2930,7 +2936,7 @@ int home_resize_luks(
29302936
if (r < 0)
29312937
return log_error_errno(r, "Failed to resize file system: %m");
29322938
} else {
2933-
r = ext4_offline_resize_fs(setup, new_fs_size, user_record_luks_discard(h), user_record_mount_flags(h));
2939+
r = ext4_offline_resize_fs(setup, new_fs_size, user_record_luks_discard(h), user_record_mount_flags(h), h->luks_extra_mount_options);
29342940
if (r < 0)
29352941
return r;
29362942
}

src/home/homework-mount.c

Lines changed: 27 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -40,28 +40,35 @@ static const char *mount_options_for_fstype(const char *fstype) {
4040
return NULL;
4141
}
4242

43-
int home_mount_node(const char *node, const char *fstype, bool discard, unsigned long flags) {
43+
int home_mount_node(
44+
const char *node,
45+
const char *fstype,
46+
bool discard,
47+
unsigned long flags,
48+
const char *extra_mount_options) {
49+
4450
_cleanup_free_ char *joined = NULL;
45-
const char *options, *discard_option;
51+
const char *default_options;
4652
int r;
4753

4854
assert(node);
4955
assert(fstype);
5056

51-
options = mount_options_for_fstype(fstype);
57+
default_options = mount_options_for_fstype(fstype);
58+
if (default_options) {
59+
if (!strextend_with_separator(&joined, ",", default_options))
60+
return log_oom();
61+
}
5262

53-
discard_option = discard ? "discard" : "nodiscard";
63+
if (!strextend_with_separator(&joined, ",", discard ? "discard" : "nodiscard"))
64+
return log_oom();
5465

55-
if (options) {
56-
joined = strjoin(options, ",", discard_option);
57-
if (!joined)
66+
if (extra_mount_options) {
67+
if (!strextend_with_separator(&joined, ",", extra_mount_options))
5868
return log_oom();
69+
}
5970

60-
options = joined;
61-
} else
62-
options = discard_option;
63-
64-
r = mount_nofollow_verbose(LOG_ERR, node, HOME_RUNTIME_WORK_DIR, fstype, flags|MS_RELATIME, strempty(options));
71+
r = mount_nofollow_verbose(LOG_ERR, node, HOME_RUNTIME_WORK_DIR, fstype, flags|MS_RELATIME, joined);
6572
if (r < 0)
6673
return r;
6774

@@ -85,7 +92,13 @@ int home_unshare_and_mkdir(void) {
8592
return 0;
8693
}
8794

88-
int home_unshare_and_mount(const char *node, const char *fstype, bool discard, unsigned long flags) {
95+
int home_unshare_and_mount(
96+
const char *node,
97+
const char *fstype,
98+
bool discard,
99+
unsigned long flags,
100+
const char *extra_mount_options) {
101+
89102
int r;
90103

91104
assert(node);
@@ -95,7 +108,7 @@ int home_unshare_and_mount(const char *node, const char *fstype, bool discard, u
95108
if (r < 0)
96109
return r;
97110

98-
r = home_mount_node(node, fstype, discard, flags);
111+
r = home_mount_node(node, fstype, discard, flags, extra_mount_options);
99112
if (r < 0)
100113
return r;
101114

src/home/homework-mount.h

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3,8 +3,8 @@
33

44
#include <stdbool.h>
55

6-
int home_mount_node(const char *node, const char *fstype, bool discard, unsigned long flags);
6+
int home_mount_node(const char *node, const char *fstype, bool discard, unsigned long flags, const char *extra_mount_options);
77
int home_unshare_and_mkdir(void);
8-
int home_unshare_and_mount(const char *node, const char *fstype, bool discard, unsigned long flags);
8+
int home_unshare_and_mount(const char *node, const char *fstype, bool discard, unsigned long flags, const char *extra_mount_options);
99
int home_move_mount(const char *user_name_and_realm, const char *target);
1010
int home_shift_uid(int dir_fd, const char *target, uid_t stored_uid, uid_t exposed_uid, int *ret_mount_fd);

src/shared/user-record-show.c

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -284,6 +284,9 @@ void user_record_show(UserRecord *hr, bool show_full_group_info) {
284284
if (hr->file_system_type)
285285
printf(" File System: %s\n", user_record_file_system_type(hr));
286286

287+
if (hr->luks_extra_mount_options)
288+
printf("LUKS MntOpts: %s\n", hr->luks_extra_mount_options);
289+
287290
if (hr->luks_cipher)
288291
printf(" LUKS Cipher: %s\n", hr->luks_cipher);
289292
if (hr->luks_cipher_mode)

src/shared/user-record.c

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -285,6 +285,7 @@ static UserRecord* user_record_free(UserRecord *h) {
285285
free(h->luks_cipher_mode);
286286
free(h->luks_pbkdf_hash_algorithm);
287287
free(h->luks_pbkdf_type);
288+
free(h->luks_extra_mount_options);
288289

289290
free(h->state);
290291
free(h->service);
@@ -1287,6 +1288,7 @@ static int dispatch_per_machine(const char *name, JsonVariant *variant, JsonDisp
12871288
{ "luksPbkdfTimeCostUSec", JSON_VARIANT_UNSIGNED, json_dispatch_uint64, offsetof(UserRecord, luks_pbkdf_time_cost_usec), 0 },
12881289
{ "luksPbkdfMemoryCost", JSON_VARIANT_UNSIGNED, json_dispatch_uint64, offsetof(UserRecord, luks_pbkdf_memory_cost), 0 },
12891290
{ "luksPbkdfParallelThreads", JSON_VARIANT_UNSIGNED, json_dispatch_uint64, offsetof(UserRecord, luks_pbkdf_parallel_threads), 0 },
1291+
{ "luksExtraMountOptions", JSON_VARIANT_STRING, json_dispatch_string, offsetof(UserRecord, luks_extra_mount_options), 0 },
12901292
{ "dropCaches", JSON_VARIANT_BOOLEAN, json_dispatch_tristate, offsetof(UserRecord, drop_caches), 0 },
12911293
{ "rateLimitIntervalUSec", JSON_VARIANT_UNSIGNED, json_dispatch_uint64, offsetof(UserRecord, ratelimit_interval_usec), 0 },
12921294
{ "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
16341636
{ "luksPbkdfTimeCostUSec", JSON_VARIANT_UNSIGNED, json_dispatch_uint64, offsetof(UserRecord, luks_pbkdf_time_cost_usec), 0 },
16351637
{ "luksPbkdfMemoryCost", JSON_VARIANT_UNSIGNED, json_dispatch_uint64, offsetof(UserRecord, luks_pbkdf_memory_cost), 0 },
16361638
{ "luksPbkdfParallelThreads", JSON_VARIANT_UNSIGNED, json_dispatch_uint64, offsetof(UserRecord, luks_pbkdf_parallel_threads), 0 },
1639+
{ "luksExtraMountOptions", JSON_VARIANT_STRING, json_dispatch_string, offsetof(UserRecord, luks_extra_mount_options), 0 },
16371640
{ "dropCaches", JSON_VARIANT_BOOLEAN, json_dispatch_tristate, offsetof(UserRecord, drop_caches), 0 },
16381641
{ "service", JSON_VARIANT_STRING, json_dispatch_string, offsetof(UserRecord, service), JSON_SAFE },
16391642
{ "rateLimitIntervalUSec", JSON_VARIANT_UNSIGNED, json_dispatch_uint64, offsetof(UserRecord, ratelimit_interval_usec), 0 },

src/shared/user-record.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -331,6 +331,7 @@ typedef struct UserRecord {
331331
uint64_t luks_pbkdf_time_cost_usec;
332332
uint64_t luks_pbkdf_memory_cost;
333333
uint64_t luks_pbkdf_parallel_threads;
334+
char *luks_extra_mount_options;
334335

335336
uint64_t disk_usage;
336337
uint64_t disk_free;

0 commit comments

Comments
 (0)