Compare commits
No commits in common. "96a4ce9f1d4fe5e28dfe04d5002b6e1b04338b67" and "3f64046cdab77d1c49af6f361d596e78a597873a" have entirely different histories.
96a4ce9f1d
...
3f64046cda
1
TODO
1
TODO
|
@ -372,6 +372,7 @@ Features:
|
||||||
- in systemd's PAMName= logic: query passwords with ssh-askpassword, so that we can make "loginctl set-linger" mode work
|
- in systemd's PAMName= logic: query passwords with ssh-askpassword, so that we can make "loginctl set-linger" mode work
|
||||||
- fingerprint authentication, pattern authentication, …
|
- fingerprint authentication, pattern authentication, …
|
||||||
- make sure "classic" user records can also be managed by homed
|
- make sure "classic" user records can also be managed by homed
|
||||||
|
- description field for groups
|
||||||
- make size of $XDG_RUNTIME_DIR configurable in user record
|
- make size of $XDG_RUNTIME_DIR configurable in user record
|
||||||
- reuse pwquality magic in firstboot
|
- reuse pwquality magic in firstboot
|
||||||
- query password from kernel keyring first
|
- query password from kernel keyring first
|
||||||
|
|
|
@ -22,10 +22,6 @@ UNIX/glibc NSS `struct group`, or the shadow structure `struct sgrp`'s
|
||||||
`realm` → The "realm" the group belongs to, conceptually identical to the same
|
`realm` → The "realm" the group belongs to, conceptually identical to the same
|
||||||
field of user records. A string in DNS domain name syntax.
|
field of user records. A string in DNS domain name syntax.
|
||||||
|
|
||||||
`description` → A descriptive string for the group. This is similar to the
|
|
||||||
`realName` field of user records, and accepts arbitrary strings, as long as
|
|
||||||
they follow the same GECOS syntax requirements as `realName`.
|
|
||||||
|
|
||||||
`disposition` → The disposition of the group, conceptually identical to the
|
`disposition` → The disposition of the group, conceptually identical to the
|
||||||
same field of user records. A string.
|
same field of user records. A string.
|
||||||
|
|
||||||
|
|
|
@ -221,14 +221,12 @@ optional, when unset the user should not be considered part of any realm. A
|
||||||
user record with a realm set is never compatible (for the purpose of updates,
|
user record with a realm set is never compatible (for the purpose of updates,
|
||||||
see above) with a user record without one set, even if the `userName` field matches.
|
see above) with a user record without one set, even if the `userName` field matches.
|
||||||
|
|
||||||
`realName` → The real name of the user, a string. This should contain the
|
`realName` → The real name of the user, a string. This should contain the user's
|
||||||
user's real ("human") name, and corresponds loosely to the GECOS field of
|
real ("human") name, and corresponds loosely to the GECOS field of classic UNIX
|
||||||
classic UNIX user records. When converting a `struct passwd` to a JSON user
|
user records. When converting a `struct passwd` to a JSON user record this
|
||||||
record this field is initialized from GECOS (i.e. the `pw_gecos` field), and
|
field is initialized from GECOS (i.e. the `pw_gecos` field), and vice versa
|
||||||
vice versa when converting back. That said, unlike GECOS this field is supposed
|
when converting back. That said, unlike GECOS this field is supposed to contain
|
||||||
to contain only the real name and no other information. This field must not
|
only the real name and no other information.
|
||||||
contain control characters (such as `\n`) or colons (`:`), since those are used
|
|
||||||
as record separators in classic `/etc/passwd` files and similar formats.
|
|
||||||
|
|
||||||
`emailAddress` → The email address of the user, formatted as
|
`emailAddress` → The email address of the user, formatted as
|
||||||
string. [`pam_systemd`](https://www.freedesktop.org/software/systemd/man/pam_systemd.html)
|
string. [`pam_systemd`](https://www.freedesktop.org/software/systemd/man/pam_systemd.html)
|
||||||
|
|
|
@ -136,7 +136,6 @@ static int build_group_json(const char *group_name, gid_t gid, JsonVariant **ret
|
||||||
return json_build(ret, JSON_BUILD_OBJECT(
|
return json_build(ret, JSON_BUILD_OBJECT(
|
||||||
JSON_BUILD_PAIR("record", JSON_BUILD_OBJECT(
|
JSON_BUILD_PAIR("record", JSON_BUILD_OBJECT(
|
||||||
JSON_BUILD_PAIR("groupName", JSON_BUILD_STRING(group_name)),
|
JSON_BUILD_PAIR("groupName", JSON_BUILD_STRING(group_name)),
|
||||||
JSON_BUILD_PAIR("description", JSON_BUILD_STRING("Dynamic Group")),
|
|
||||||
JSON_BUILD_PAIR("gid", JSON_BUILD_UNSIGNED(gid)),
|
JSON_BUILD_PAIR("gid", JSON_BUILD_UNSIGNED(gid)),
|
||||||
JSON_BUILD_PAIR("service", JSON_BUILD_STRING("io.systemd.DynamicUser")),
|
JSON_BUILD_PAIR("service", JSON_BUILD_STRING("io.systemd.DynamicUser")),
|
||||||
JSON_BUILD_PAIR("disposition", JSON_BUILD_STRING("dynamic"))))));
|
JSON_BUILD_PAIR("disposition", JSON_BUILD_STRING("dynamic"))))));
|
||||||
|
|
|
@ -104,7 +104,7 @@ int user_record_synthesize(
|
||||||
}
|
}
|
||||||
|
|
||||||
int group_record_synthesize(GroupRecord *g, UserRecord *h) {
|
int group_record_synthesize(GroupRecord *g, UserRecord *h) {
|
||||||
_cleanup_free_ char *un = NULL, *rr = NULL, *group_name_and_realm = NULL, *description = NULL;
|
_cleanup_free_ char *un = NULL, *rr = NULL, *group_name_and_realm = NULL;
|
||||||
char smid[SD_ID128_STRING_MAX];
|
char smid[SD_ID128_STRING_MAX];
|
||||||
sd_id128_t mid;
|
sd_id128_t mid;
|
||||||
int r;
|
int r;
|
||||||
|
@ -133,15 +133,10 @@ int group_record_synthesize(GroupRecord *g, UserRecord *h) {
|
||||||
return -ENOMEM;
|
return -ENOMEM;
|
||||||
}
|
}
|
||||||
|
|
||||||
description = strjoin("Primary Group of User ", un);
|
|
||||||
if (!description)
|
|
||||||
return -ENOMEM;
|
|
||||||
|
|
||||||
r = json_build(&g->json,
|
r = json_build(&g->json,
|
||||||
JSON_BUILD_OBJECT(
|
JSON_BUILD_OBJECT(
|
||||||
JSON_BUILD_PAIR("groupName", JSON_BUILD_STRING(un)),
|
JSON_BUILD_PAIR("groupName", JSON_BUILD_STRING(un)),
|
||||||
JSON_BUILD_PAIR_CONDITION(!!rr, "realm", JSON_BUILD_STRING(rr)),
|
JSON_BUILD_PAIR_CONDITION(!!rr, "realm", JSON_BUILD_STRING(rr)),
|
||||||
JSON_BUILD_PAIR("description", JSON_BUILD_STRING(description)),
|
|
||||||
JSON_BUILD_PAIR("binding", JSON_BUILD_OBJECT(
|
JSON_BUILD_PAIR("binding", JSON_BUILD_OBJECT(
|
||||||
JSON_BUILD_PAIR(sd_id128_to_string(mid, smid), JSON_BUILD_OBJECT(
|
JSON_BUILD_PAIR(sd_id128_to_string(mid, smid), JSON_BUILD_OBJECT(
|
||||||
JSON_BUILD_PAIR("gid", JSON_BUILD_UNSIGNED(user_record_gid(h))))))),
|
JSON_BUILD_PAIR("gid", JSON_BUILD_UNSIGNED(user_record_gid(h))))))),
|
||||||
|
|
|
@ -93,8 +93,6 @@ static int user_lookup_name(Manager *m, const char *name, uid_t *ret_uid, char *
|
||||||
int r;
|
int r;
|
||||||
|
|
||||||
assert(m);
|
assert(m);
|
||||||
assert(ret_uid);
|
|
||||||
assert(ret_real_name);
|
|
||||||
|
|
||||||
if (!valid_user_group_name(name, 0))
|
if (!valid_user_group_name(name, 0))
|
||||||
return -ESRCH;
|
return -ESRCH;
|
||||||
|
@ -188,7 +186,7 @@ static int vl_method_get_user_record(Varlink *link, JsonVariant *parameters, Var
|
||||||
return varlink_reply(link, v);
|
return varlink_reply(link, v);
|
||||||
}
|
}
|
||||||
|
|
||||||
static int build_group_json(const char *group_name, gid_t gid, const char *description, JsonVariant **ret) {
|
static int build_group_json(const char *group_name, gid_t gid, JsonVariant **ret) {
|
||||||
assert(group_name);
|
assert(group_name);
|
||||||
assert(gid_is_valid(gid));
|
assert(gid_is_valid(gid));
|
||||||
assert(ret);
|
assert(ret);
|
||||||
|
@ -197,7 +195,6 @@ static int build_group_json(const char *group_name, gid_t gid, const char *descr
|
||||||
JSON_BUILD_PAIR("record", JSON_BUILD_OBJECT(
|
JSON_BUILD_PAIR("record", JSON_BUILD_OBJECT(
|
||||||
JSON_BUILD_PAIR("groupName", JSON_BUILD_STRING(group_name)),
|
JSON_BUILD_PAIR("groupName", JSON_BUILD_STRING(group_name)),
|
||||||
JSON_BUILD_PAIR("gid", JSON_BUILD_UNSIGNED(gid)),
|
JSON_BUILD_PAIR("gid", JSON_BUILD_UNSIGNED(gid)),
|
||||||
JSON_BUILD_PAIR_CONDITION(!isempty(description), "description", JSON_BUILD_STRING(description)),
|
|
||||||
JSON_BUILD_PAIR("service", JSON_BUILD_STRING("io.systemd.Machine")),
|
JSON_BUILD_PAIR("service", JSON_BUILD_STRING("io.systemd.Machine")),
|
||||||
JSON_BUILD_PAIR("disposition", JSON_BUILD_STRING("container"))))));
|
JSON_BUILD_PAIR("disposition", JSON_BUILD_STRING("container"))))));
|
||||||
}
|
}
|
||||||
|
@ -214,8 +211,8 @@ static bool group_match_lookup_parameters(LookupParameters *p, const char *name,
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int group_lookup_gid(Manager *m, gid_t gid, char **ret_name, char **ret_description) {
|
static int group_lookup_gid(Manager *m, gid_t gid, char **ret_name) {
|
||||||
_cleanup_free_ char *n = NULL, *d = NULL;
|
_cleanup_free_ char *n = NULL;
|
||||||
gid_t converted_gid;
|
gid_t converted_gid;
|
||||||
Machine *machine;
|
Machine *machine;
|
||||||
int r;
|
int r;
|
||||||
|
@ -223,7 +220,6 @@ static int group_lookup_gid(Manager *m, gid_t gid, char **ret_name, char **ret_d
|
||||||
assert(m);
|
assert(m);
|
||||||
assert(gid_is_valid(gid));
|
assert(gid_is_valid(gid));
|
||||||
assert(ret_name);
|
assert(ret_name);
|
||||||
assert(ret_description);
|
|
||||||
|
|
||||||
if (gid < 0x10000) /* Host GID range */
|
if (gid < 0x10000) /* Host GID range */
|
||||||
return -ESRCH;
|
return -ESRCH;
|
||||||
|
@ -240,27 +236,18 @@ static int group_lookup_gid(Manager *m, gid_t gid, char **ret_name, char **ret_d
|
||||||
if (!valid_user_group_name(n, 0))
|
if (!valid_user_group_name(n, 0))
|
||||||
return -ESRCH;
|
return -ESRCH;
|
||||||
|
|
||||||
if (asprintf(&d, "GID " GID_FMT " of Container %s", converted_gid, machine->name) < 0)
|
|
||||||
return -ENOMEM;
|
|
||||||
if (!valid_gecos(d))
|
|
||||||
d = mfree(d);
|
|
||||||
|
|
||||||
*ret_name = TAKE_PTR(n);
|
*ret_name = TAKE_PTR(n);
|
||||||
*ret_description = TAKE_PTR(d);
|
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int group_lookup_name(Manager *m, const char *name, gid_t *ret_gid, char **ret_description) {
|
static int group_lookup_name(Manager *m, const char *name, gid_t *ret_gid) {
|
||||||
_cleanup_free_ char *mn = NULL, *desc = NULL;
|
_cleanup_free_ char *mn = NULL;
|
||||||
gid_t gid, converted_gid;
|
gid_t gid, converted_gid;
|
||||||
Machine *machine;
|
Machine *machine;
|
||||||
const char *e, *d;
|
const char *e, *d;
|
||||||
int r;
|
int r;
|
||||||
|
|
||||||
assert(m);
|
assert(m);
|
||||||
assert(ret_gid);
|
|
||||||
assert(ret_description);
|
|
||||||
|
|
||||||
if (!valid_user_group_name(name, 0))
|
if (!valid_user_group_name(name, 0))
|
||||||
return -ESRCH;
|
return -ESRCH;
|
||||||
|
@ -291,13 +278,7 @@ static int group_lookup_name(Manager *m, const char *name, gid_t *ret_gid, char
|
||||||
if (r < 0)
|
if (r < 0)
|
||||||
return r;
|
return r;
|
||||||
|
|
||||||
if (asprintf(&desc, "GID " GID_FMT " of Container %s", gid, machine->name) < 0)
|
|
||||||
return -ENOMEM;
|
|
||||||
if (!valid_gecos(desc))
|
|
||||||
desc = mfree(desc);
|
|
||||||
|
|
||||||
*ret_gid = converted_gid;
|
*ret_gid = converted_gid;
|
||||||
*ret_description = desc;
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -314,7 +295,7 @@ static int vl_method_get_group_record(Varlink *link, JsonVariant *parameters, Va
|
||||||
LookupParameters p = {
|
LookupParameters p = {
|
||||||
.gid = GID_INVALID,
|
.gid = GID_INVALID,
|
||||||
};
|
};
|
||||||
_cleanup_free_ char *found_name = NULL, *found_description = NULL;
|
_cleanup_free_ char *found_name = NULL;
|
||||||
uid_t found_gid = GID_INVALID, gid;
|
uid_t found_gid = GID_INVALID, gid;
|
||||||
Manager *m = userdata;
|
Manager *m = userdata;
|
||||||
const char *gn;
|
const char *gn;
|
||||||
|
@ -331,9 +312,9 @@ static int vl_method_get_group_record(Varlink *link, JsonVariant *parameters, Va
|
||||||
return varlink_error(link, "io.systemd.UserDatabase.BadService", NULL);
|
return varlink_error(link, "io.systemd.UserDatabase.BadService", NULL);
|
||||||
|
|
||||||
if (gid_is_valid(p.gid))
|
if (gid_is_valid(p.gid))
|
||||||
r = group_lookup_gid(m, p.gid, &found_name, &found_description);
|
r = group_lookup_gid(m, p.gid, &found_name);
|
||||||
else if (p.group_name)
|
else if (p.group_name)
|
||||||
r = group_lookup_name(m, p.group_name, (uid_t*) &found_gid, &found_description);
|
r = group_lookup_name(m, p.group_name, (uid_t*) &found_gid);
|
||||||
else
|
else
|
||||||
return varlink_error(link, "io.systemd.UserDatabase.EnumerationNotSupported", NULL);
|
return varlink_error(link, "io.systemd.UserDatabase.EnumerationNotSupported", NULL);
|
||||||
if (r == -ESRCH)
|
if (r == -ESRCH)
|
||||||
|
@ -347,7 +328,7 @@ static int vl_method_get_group_record(Varlink *link, JsonVariant *parameters, Va
|
||||||
if (!group_match_lookup_parameters(&p, gn, gid))
|
if (!group_match_lookup_parameters(&p, gn, gid))
|
||||||
return varlink_error(link, "io.systemd.UserDatabase.ConflictingRecordFound", NULL);
|
return varlink_error(link, "io.systemd.UserDatabase.ConflictingRecordFound", NULL);
|
||||||
|
|
||||||
r = build_group_json(gn, gid, found_description, &v);
|
r = build_group_json(gn, gid, &v);
|
||||||
if (r < 0)
|
if (r < 0)
|
||||||
return r;
|
return r;
|
||||||
|
|
||||||
|
|
|
@ -68,9 +68,6 @@ void group_record_show(GroupRecord *gr, bool show_full_user_info) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (gr->description && !streq(gr->description, gr->group_name))
|
|
||||||
printf(" Description: %s\n", gr->description);
|
|
||||||
|
|
||||||
if (!strv_isempty(gr->hashed_password))
|
if (!strv_isempty(gr->hashed_password))
|
||||||
printf(" Passwords: %zu\n", strv_length(gr->hashed_password));
|
printf(" Passwords: %zu\n", strv_length(gr->hashed_password));
|
||||||
|
|
||||||
|
|
|
@ -28,7 +28,6 @@ static GroupRecord *group_record_free(GroupRecord *g) {
|
||||||
free(g->group_name);
|
free(g->group_name);
|
||||||
free(g->realm);
|
free(g->realm);
|
||||||
free(g->group_name_and_realm_auto);
|
free(g->group_name_and_realm_auto);
|
||||||
free(g->description);
|
|
||||||
|
|
||||||
strv_free(g->members);
|
strv_free(g->members);
|
||||||
free(g->service);
|
free(g->service);
|
||||||
|
@ -193,7 +192,6 @@ int group_record_load(
|
||||||
static const JsonDispatch group_dispatch_table[] = {
|
static const JsonDispatch group_dispatch_table[] = {
|
||||||
{ "groupName", JSON_VARIANT_STRING, json_dispatch_user_group_name, offsetof(GroupRecord, group_name), JSON_RELAX},
|
{ "groupName", JSON_VARIANT_STRING, json_dispatch_user_group_name, offsetof(GroupRecord, group_name), JSON_RELAX},
|
||||||
{ "realm", JSON_VARIANT_STRING, json_dispatch_realm, offsetof(GroupRecord, realm), 0 },
|
{ "realm", JSON_VARIANT_STRING, json_dispatch_realm, offsetof(GroupRecord, realm), 0 },
|
||||||
{ "description", JSON_VARIANT_STRING, json_dispatch_gecos, offsetof(GroupRecord, description), 0 },
|
|
||||||
{ "disposition", JSON_VARIANT_STRING, json_dispatch_user_disposition, offsetof(GroupRecord, disposition), 0 },
|
{ "disposition", JSON_VARIANT_STRING, json_dispatch_user_disposition, offsetof(GroupRecord, disposition), 0 },
|
||||||
{ "service", JSON_VARIANT_STRING, json_dispatch_string, offsetof(GroupRecord, service), JSON_SAFE },
|
{ "service", JSON_VARIANT_STRING, json_dispatch_string, offsetof(GroupRecord, service), JSON_SAFE },
|
||||||
{ "lastChangeUSec", JSON_VARIANT_UNSIGNED, json_dispatch_uint64, offsetof(GroupRecord, last_change_usec), 0 },
|
{ "lastChangeUSec", JSON_VARIANT_UNSIGNED, json_dispatch_uint64, offsetof(GroupRecord, last_change_usec), 0 },
|
||||||
|
|
|
@ -13,8 +13,6 @@ typedef struct GroupRecord {
|
||||||
char *realm;
|
char *realm;
|
||||||
char *group_name_and_realm_auto;
|
char *group_name_and_realm_auto;
|
||||||
|
|
||||||
char *description;
|
|
||||||
|
|
||||||
UserDisposition disposition;
|
UserDisposition disposition;
|
||||||
uint64_t last_change_usec;
|
uint64_t last_change_usec;
|
||||||
|
|
||||||
|
|
|
@ -203,7 +203,7 @@ int json_dispatch_realm(const char *name, JsonVariant *variant, JsonDispatchFlag
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
int json_dispatch_gecos(const char *name, JsonVariant *variant, JsonDispatchFlags flags, void *userdata) {
|
static int json_dispatch_gecos(const char *name, JsonVariant *variant, JsonDispatchFlags flags, void *userdata) {
|
||||||
char **s = userdata;
|
char **s = userdata;
|
||||||
const char *n;
|
const char *n;
|
||||||
|
|
||||||
|
|
|
@ -388,7 +388,6 @@ int user_record_test_password_change_required(UserRecord *h);
|
||||||
|
|
||||||
/* The following six are user by group-record.c, that's why we export them here */
|
/* The following six are user by group-record.c, that's why we export them here */
|
||||||
int json_dispatch_realm(const char *name, JsonVariant *variant, JsonDispatchFlags flags, void *userdata);
|
int json_dispatch_realm(const char *name, JsonVariant *variant, JsonDispatchFlags flags, void *userdata);
|
||||||
int json_dispatch_gecos(const char *name, JsonVariant *variant, JsonDispatchFlags flags, void *userdata);
|
|
||||||
int json_dispatch_user_group_list(const char *name, JsonVariant *variant, JsonDispatchFlags flags, void *userdata);
|
int json_dispatch_user_group_list(const char *name, JsonVariant *variant, JsonDispatchFlags flags, void *userdata);
|
||||||
int json_dispatch_user_disposition(const char *name, JsonVariant *variant, JsonDispatchFlags flags, void *userdata);
|
int json_dispatch_user_disposition(const char *name, JsonVariant *variant, JsonDispatchFlags flags, void *userdata);
|
||||||
|
|
||||||
|
|
|
@ -232,7 +232,6 @@ static int show_group(GroupRecord *gr, Table *table) {
|
||||||
TABLE_STRING, gr->group_name,
|
TABLE_STRING, gr->group_name,
|
||||||
TABLE_STRING, user_disposition_to_string(group_record_disposition(gr)),
|
TABLE_STRING, user_disposition_to_string(group_record_disposition(gr)),
|
||||||
TABLE_GID, gr->gid,
|
TABLE_GID, gr->gid,
|
||||||
TABLE_STRING, gr->description,
|
|
||||||
TABLE_INT, (int) group_record_disposition(gr));
|
TABLE_INT, (int) group_record_disposition(gr));
|
||||||
if (r < 0)
|
if (r < 0)
|
||||||
return table_log_add_error(r);
|
return table_log_add_error(r);
|
||||||
|
@ -256,14 +255,13 @@ static int display_group(int argc, char *argv[], void *userdata) {
|
||||||
arg_output = argc > 1 ? OUTPUT_FRIENDLY : OUTPUT_TABLE;
|
arg_output = argc > 1 ? OUTPUT_FRIENDLY : OUTPUT_TABLE;
|
||||||
|
|
||||||
if (arg_output == OUTPUT_TABLE) {
|
if (arg_output == OUTPUT_TABLE) {
|
||||||
table = table_new("name", "disposition", "gid", "description", "disposition-numeric");
|
table = table_new("name", "disposition", "gid", "disposition-numeric");
|
||||||
if (!table)
|
if (!table)
|
||||||
return log_oom();
|
return log_oom();
|
||||||
|
|
||||||
(void) table_set_align_percent(table, table_get_cell(table, 0, 2), 100);
|
(void) table_set_align_percent(table, table_get_cell(table, 0, 2), 100);
|
||||||
(void) table_set_empty_string(table, "-");
|
|
||||||
(void) table_set_sort(table, (size_t) 3, (size_t) 2, (size_t) -1);
|
(void) table_set_sort(table, (size_t) 3, (size_t) 2, (size_t) -1);
|
||||||
(void) table_set_display(table, (size_t) 0, (size_t) 1, (size_t) 2, (size_t) 3, (size_t) -1);
|
(void) table_set_display(table, (size_t) 0, (size_t) 1, (size_t) 2, (size_t) -1);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (argc > 1) {
|
if (argc > 1) {
|
||||||
|
|
|
@ -12,7 +12,7 @@ Description=Enforce Volatile Root File Systems
|
||||||
Documentation=man:systemd-volatile-root.service(8)
|
Documentation=man:systemd-volatile-root.service(8)
|
||||||
DefaultDependencies=no
|
DefaultDependencies=no
|
||||||
Conflicts=shutdown.target
|
Conflicts=shutdown.target
|
||||||
After=sysroot.mount systemd-repart.service
|
After=sysroot.mount
|
||||||
Before=initrd-root-fs.target shutdown.target
|
Before=initrd-root-fs.target shutdown.target
|
||||||
AssertPathExists=/etc/initrd-release
|
AssertPathExists=/etc/initrd-release
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue