summaryrefslogtreecommitdiff
path: root/src/grp-initprogs
diff options
context:
space:
mode:
authorLuke Shumaker <lukeshu@sbcglobal.net>2016-12-17 03:11:52 -0500
committerLuke Shumaker <lukeshu@sbcglobal.net>2016-12-17 03:11:52 -0500
commitb849891b5dde5ee14ab8b7b7db74e65a4a38d993 (patch)
tree29bb0e6fda9b4b170041913de495da057bbe3621 /src/grp-initprogs
parent004efebf9cc559ea131bb9460ee0ee198e2d5da7 (diff)
parent881228ff72434a0e3401a16bd87f179ef0ab1619 (diff)
Merge branch 'notsystemd/postmove' into notsystemd/master
# Conflicts: # src/grp-journal/libjournal-core/.gitignore # src/grp-system/libcore/include/core/mount.h
Diffstat (limited to 'src/grp-initprogs')
-rw-r--r--src/grp-initprogs/grp-sleep/systemd-hibernate-resume-generator/hibernate-resume-generator.c4
-rw-r--r--src/grp-initprogs/systemd-backlight/backlight.c2
-rw-r--r--src/grp-initprogs/systemd-detect-virt/detect-virt.c31
-rw-r--r--src/grp-initprogs/systemd-detect-virt/systemd-detect-virt.xml23
-rw-r--r--src/grp-initprogs/systemd-fsck/fsck.c4
-rw-r--r--src/grp-initprogs/systemd-modules-load/modules-load.c6
-rw-r--r--src/grp-initprogs/systemd-quotacheck/quotacheck.c4
-rw-r--r--src/grp-initprogs/systemd-random-seed/systemd-random-seed.service.in1
-rw-r--r--src/grp-initprogs/systemd-sysctl/sysctl.c78
-rw-r--r--src/grp-initprogs/systemd-sysctl/systemd-sysctl.service.in2
-rw-r--r--src/grp-initprogs/systemd-sysusers/sysusers.c79
-rw-r--r--src/grp-initprogs/systemd-tmpfiles/tmpfiles.d.xml6
-rw-r--r--src/grp-initprogs/systemd-update-done/update-done.c79
-rw-r--r--src/grp-initprogs/systemd-update-utmp/update-utmp.c3
-rw-r--r--src/grp-initprogs/systemd-vconsole-setup/90-vconsole.rules.in2
-rw-r--r--src/grp-initprogs/systemd-vconsole-setup/Makefile3
-rw-r--r--src/grp-initprogs/systemd-vconsole-setup/systemd-vconsole-setup.service.in3
-rw-r--r--src/grp-initprogs/systemd-vconsole-setup/systemd-vconsole-setup.service.xml62
-rw-r--r--src/grp-initprogs/systemd-vconsole-setup/vconsole-setup.c279
-rw-r--r--src/grp-initprogs/systemd-vconsole-setup/vconsole.conf.xml47
20 files changed, 384 insertions, 334 deletions
diff --git a/src/grp-initprogs/grp-sleep/systemd-hibernate-resume-generator/hibernate-resume-generator.c b/src/grp-initprogs/grp-sleep/systemd-hibernate-resume-generator/hibernate-resume-generator.c
index 6774df21c5..de440853db 100644
--- a/src/grp-initprogs/grp-sleep/systemd-hibernate-resume-generator/hibernate-resume-generator.c
+++ b/src/grp-initprogs/grp-sleep/systemd-hibernate-resume-generator/hibernate-resume-generator.c
@@ -33,7 +33,7 @@
static const char *arg_dest = "/tmp";
static char *arg_resume_dev = NULL;
-static int parse_proc_cmdline_item(const char *key, const char *value) {
+static int parse_proc_cmdline_item(const char *key, const char *value, void *data) {
if (streq(key, "resume") && value) {
free(arg_resume_dev);
@@ -88,7 +88,7 @@ int main(int argc, char *argv[]) {
if (!in_initrd())
return EXIT_SUCCESS;
- r = parse_proc_cmdline(parse_proc_cmdline_item);
+ r = parse_proc_cmdline(parse_proc_cmdline_item, NULL, false);
if (r < 0)
log_warning_errno(r, "Failed to parse kernel command line, ignoring: %m");
diff --git a/src/grp-initprogs/systemd-backlight/backlight.c b/src/grp-initprogs/systemd-backlight/backlight.c
index 3fd47ad611..f5b80c395e 100644
--- a/src/grp-initprogs/systemd-backlight/backlight.c
+++ b/src/grp-initprogs/systemd-backlight/backlight.c
@@ -167,7 +167,7 @@ static bool validate_device(struct udev *udev, struct udev_device *device) {
continue;
v = udev_device_get_sysattr_value(other, "type");
- if (!streq_ptr(v, "platform") && !streq_ptr(v, "firmware"))
+ if (!STRPTR_IN_SET(v, "platform", "firmware"))
continue;
/* OK, so there's another backlight device, and it's a
diff --git a/src/grp-initprogs/systemd-detect-virt/detect-virt.c b/src/grp-initprogs/systemd-detect-virt/detect-virt.c
index 80f4f72fab..484f689c4c 100644
--- a/src/grp-initprogs/systemd-detect-virt/detect-virt.c
+++ b/src/grp-initprogs/systemd-detect-virt/detect-virt.c
@@ -31,6 +31,7 @@ static enum {
ONLY_VM,
ONLY_CONTAINER,
ONLY_CHROOT,
+ ONLY_PRIVATE_USERS,
} arg_mode = ANY_VIRTUALIZATION;
static void help(void) {
@@ -41,6 +42,7 @@ static void help(void) {
" -c --container Only detect whether we are run in a container\n"
" -v --vm Only detect whether we are run in a VM\n"
" -r --chroot Detect whether we are run in a chroot() environment\n"
+ " --private-users Only detect whether we are running in a user namespace\n"
" -q --quiet Don't output anything, just set return value\n"
, program_invocation_short_name);
}
@@ -48,16 +50,18 @@ static void help(void) {
static int parse_argv(int argc, char *argv[]) {
enum {
- ARG_VERSION = 0x100
+ ARG_VERSION = 0x100,
+ ARG_PRIVATE_USERS,
};
static const struct option options[] = {
- { "help", no_argument, NULL, 'h' },
- { "version", no_argument, NULL, ARG_VERSION },
- { "container", no_argument, NULL, 'c' },
- { "vm", no_argument, NULL, 'v' },
- { "chroot", no_argument, NULL, 'r' },
- { "quiet", no_argument, NULL, 'q' },
+ { "help", no_argument, NULL, 'h' },
+ { "version", no_argument, NULL, ARG_VERSION },
+ { "container", no_argument, NULL, 'c' },
+ { "vm", no_argument, NULL, 'v' },
+ { "chroot", no_argument, NULL, 'r' },
+ { "private-users", no_argument, NULL, ARG_PRIVATE_USERS },
+ { "quiet", no_argument, NULL, 'q' },
{}
};
@@ -85,6 +89,10 @@ static int parse_argv(int argc, char *argv[]) {
arg_mode = ONLY_CONTAINER;
break;
+ case ARG_PRIVATE_USERS:
+ arg_mode = ONLY_PRIVATE_USERS;
+ break;
+
case 'v':
arg_mode = ONLY_VM;
break;
@@ -151,6 +159,15 @@ int main(int argc, char *argv[]) {
return r ? EXIT_SUCCESS : EXIT_FAILURE;
+ case ONLY_PRIVATE_USERS:
+ r = running_in_userns();
+ if (r < 0) {
+ log_error_errno(r, "Failed to check for user namespace: %m");
+ return EXIT_FAILURE;
+ }
+
+ return r ? EXIT_SUCCESS : EXIT_FAILURE;
+
case ANY_VIRTUALIZATION:
default:
r = detect_virtualization();
diff --git a/src/grp-initprogs/systemd-detect-virt/systemd-detect-virt.xml b/src/grp-initprogs/systemd-detect-virt/systemd-detect-virt.xml
index 2b7f4e69ab..996c2fa256 100644
--- a/src/grp-initprogs/systemd-detect-virt/systemd-detect-virt.xml
+++ b/src/grp-initprogs/systemd-detect-virt/systemd-detect-virt.xml
@@ -50,7 +50,8 @@
<refsynopsisdiv>
<cmdsynopsis>
- <command>systemd-detect-virt <arg choice="opt" rep="repeat">OPTIONS</arg></command>
+ <command>systemd-detect-virt</command>
+ <arg choice="opt" rep="repeat">OPTIONS</arg>
</cmdsynopsis>
</refsynopsisdiv>
@@ -88,7 +89,7 @@
</thead>
<tbody>
<row>
- <entry valign="top" morerows="9">VM</entry>
+ <entry valign="top" morerows="10">VM</entry>
<entry><varname>qemu</varname></entry>
<entry>QEMU software virtualization</entry>
</row>
@@ -138,6 +139,11 @@
<entry>Parallels Desktop, Parallels Server</entry>
</row>
+ <row>
+ <entry><varname>bhyve</varname></entry>
+ <entry>bhyve, FreeBSD hypervisor</entry>
+ </row>
+
<row>
<entry valign="top" morerows="5">Container</entry>
<entry><varname>openvz</varname></entry>
@@ -213,6 +219,16 @@
</varlistentry>
<varlistentry>
+ <term><option>--private-users</option></term>
+
+ <listitem><para>Detect whether invoked in a user namespace. In this mode, no
+ output is written, but the return value indicates whether the process was invoked
+ inside of a user namespace or not. See
+ <citerefentry project='man-pages'><refentrytitle>user_namespaces</refentrytitle><manvolnum>7</manvolnum></citerefentry>
+ for more information.</para></listitem>
+ </varlistentry>
+
+ <varlistentry>
<term><option>-q</option></term>
<term><option>--quiet</option></term>
@@ -238,7 +254,8 @@
<para>
<citerefentry><refentrytitle>systemd</refentrytitle><manvolnum>1</manvolnum></citerefentry>,
<citerefentry><refentrytitle>systemd-nspawn</refentrytitle><manvolnum>1</manvolnum></citerefentry>,
- <citerefentry><refentrytitle>chroot</refentrytitle><manvolnum>2</manvolnum></citerefentry>
+ <citerefentry><refentrytitle>chroot</refentrytitle><manvolnum>2</manvolnum></citerefentry>,
+ <citerefentry project='man-pages'><refentrytitle>namespaces</refentrytitle><manvolnum>7</manvolnum></citerefentry>
</para>
</refsect1>
diff --git a/src/grp-initprogs/systemd-fsck/fsck.c b/src/grp-initprogs/systemd-fsck/fsck.c
index c33d199ef5..df6f96096b 100644
--- a/src/grp-initprogs/systemd-fsck/fsck.c
+++ b/src/grp-initprogs/systemd-fsck/fsck.c
@@ -94,7 +94,7 @@ static void start_target(const char *target, const char *mode) {
log_error("Failed to start unit: %s", bus_error_message(&error, r));
}
-static int parse_proc_cmdline_item(const char *key, const char *value) {
+static int parse_proc_cmdline_item(const char *key, const char *value, void *data) {
int r;
assert(key);
@@ -293,7 +293,7 @@ int main(int argc, char *argv[]) {
umask(0022);
- r = parse_proc_cmdline(parse_proc_cmdline_item);
+ r = parse_proc_cmdline(parse_proc_cmdline_item, NULL, true);
if (r < 0)
log_warning_errno(r, "Failed to parse kernel command line, ignoring: %m");
diff --git a/src/grp-initprogs/systemd-modules-load/modules-load.c b/src/grp-initprogs/systemd-modules-load/modules-load.c
index 13f6ac529d..077561e2ba 100644
--- a/src/grp-initprogs/systemd-modules-load/modules-load.c
+++ b/src/grp-initprogs/systemd-modules-load/modules-load.c
@@ -59,10 +59,10 @@ static int add_modules(const char *p) {
return 0;
}
-static int parse_proc_cmdline_item(const char *key, const char *value) {
+static int parse_proc_cmdline_item(const char *key, const char *value, void *data) {
int r;
- if (STR_IN_SET(key, "modules-load", "rd.modules-load") && value) {
+ if (streq(key, "modules-load") && value) {
r = add_modules(value);
if (r < 0)
return r;
@@ -226,7 +226,7 @@ int main(int argc, char *argv[]) {
umask(0022);
- r = parse_proc_cmdline(parse_proc_cmdline_item);
+ r = parse_proc_cmdline(parse_proc_cmdline_item, NULL, true);
if (r < 0)
log_warning_errno(r, "Failed to parse kernel command line, ignoring: %m");
diff --git a/src/grp-initprogs/systemd-quotacheck/quotacheck.c b/src/grp-initprogs/systemd-quotacheck/quotacheck.c
index eadd78c9da..7687354ad6 100644
--- a/src/grp-initprogs/systemd-quotacheck/quotacheck.c
+++ b/src/grp-initprogs/systemd-quotacheck/quotacheck.c
@@ -32,7 +32,7 @@
static bool arg_skip = false;
static bool arg_force = false;
-static int parse_proc_cmdline_item(const char *key, const char *value) {
+static int parse_proc_cmdline_item(const char *key, const char *value, void *data) {
if (streq(key, "quotacheck.mode") && value) {
@@ -88,7 +88,7 @@ int main(int argc, char *argv[]) {
umask(0022);
- r = parse_proc_cmdline(parse_proc_cmdline_item);
+ r = parse_proc_cmdline(parse_proc_cmdline_item, NULL, false);
if (r < 0)
log_warning_errno(r, "Failed to parse kernel command line, ignoring: %m");
diff --git a/src/grp-initprogs/systemd-random-seed/systemd-random-seed.service.in b/src/grp-initprogs/systemd-random-seed/systemd-random-seed.service.in
index 115233268d..b244a8ce43 100644
--- a/src/grp-initprogs/systemd-random-seed/systemd-random-seed.service.in
+++ b/src/grp-initprogs/systemd-random-seed/systemd-random-seed.service.in
@@ -13,6 +13,7 @@ RequiresMountsFor=@RANDOM_SEED@
Conflicts=shutdown.target
After=systemd-remount-fs.service
Before=sysinit.target shutdown.target
+ConditionVirtualization=!container
[Service]
Type=oneshot
diff --git a/src/grp-initprogs/systemd-sysctl/sysctl.c b/src/grp-initprogs/systemd-sysctl/sysctl.c
index c5d666904d..de047890f6 100644
--- a/src/grp-initprogs/systemd-sysctl/sysctl.c
+++ b/src/grp-initprogs/systemd-sysctl/sysctl.c
@@ -41,29 +41,56 @@ static char **arg_prefixes = NULL;
static const char conf_file_dirs[] = CONF_PATHS_NULSTR("sysctl.d");
-static int apply_all(Hashmap *sysctl_options) {
+static int apply_all(OrderedHashmap *sysctl_options) {
char *property, *value;
Iterator i;
int r = 0;
- HASHMAP_FOREACH_KEY(value, property, sysctl_options, i) {
+ ORDERED_HASHMAP_FOREACH_KEY(value, property, sysctl_options, i) {
int k;
k = sysctl_write(property, value);
if (k < 0) {
- log_full_errno(k == -ENOENT ? LOG_INFO : LOG_WARNING, k,
- "Couldn't write '%s' to '%s', ignoring: %m", value, property);
-
- if (r == 0 && k != -ENOENT)
- r = k;
+ /* If the sysctl is not available in the kernel or we are running with reduced privileges and
+ * cannot write it, then log about the issue at LOG_NOTICE level, and proceed without
+ * failing. (EROFS is treated as a permission problem here, since that's how container managers
+ * usually protected their sysctls.) In all other cases log an error and make the tool fail. */
+
+ if (IN_SET(k, -EPERM, -EACCES, -EROFS, -ENOENT))
+ log_notice_errno(k, "Couldn't write '%s' to '%s', ignoring: %m", value, property);
+ else {
+ log_error_errno(k, "Couldn't write '%s' to '%s': %m", value, property);
+ if (r == 0)
+ r = k;
+ }
}
}
return r;
}
-static int parse_file(Hashmap *sysctl_options, const char *path, bool ignore_enoent) {
+static bool test_prefix(const char *p) {
+ char **i;
+
+ if (strv_isempty(arg_prefixes))
+ return true;
+
+ STRV_FOREACH(i, arg_prefixes) {
+ const char *t;
+
+ t = path_startswith(*i, "/proc/sys/");
+ if (!t)
+ t = *i;
+ if (path_startswith(p, t))
+ return true;
+ }
+
+ return false;
+}
+
+static int parse_file(OrderedHashmap *sysctl_options, const char *path, bool ignore_enoent) {
_cleanup_fclose_ FILE *f = NULL;
+ unsigned c = 0;
int r;
assert(path);
@@ -77,7 +104,7 @@ static int parse_file(Hashmap *sysctl_options, const char *path, bool ignore_eno
}
log_debug("Parsing %s", path);
- while (!feof(f)) {
+ for (;;) {
char l[LINE_MAX], *p, *value, *new_value, *property, *existing;
void *v;
int k;
@@ -89,6 +116,8 @@ static int parse_file(Hashmap *sysctl_options, const char *path, bool ignore_eno
return log_error_errno(errno, "Failed to read file '%s', ignoring: %m", path);
}
+ c++;
+
p = strstrip(l);
if (!*p)
continue;
@@ -98,7 +127,7 @@ static int parse_file(Hashmap *sysctl_options, const char *path, bool ignore_eno
value = strchr(p, '=');
if (!value) {
- log_error("Line is not an assignment in file '%s': %s", path, value);
+ log_error("Line is not an assignment at '%s:%u': %s", path, c, value);
if (r == 0)
r = -EINVAL;
@@ -111,27 +140,16 @@ static int parse_file(Hashmap *sysctl_options, const char *path, bool ignore_eno
p = sysctl_normalize(strstrip(p));
value = strstrip(value);
- if (!strv_isempty(arg_prefixes)) {
- char **i, *t;
- STRV_FOREACH(i, arg_prefixes) {
- t = path_startswith(*i, "/proc/sys/");
- if (t == NULL)
- t = *i;
- if (path_startswith(p, t))
- goto found;
- }
- /* not found */
+ if (!test_prefix(p))
continue;
- }
-found:
- existing = hashmap_get2(sysctl_options, p, &v);
+ existing = ordered_hashmap_get2(sysctl_options, p, &v);
if (existing) {
if (streq(value, existing))
continue;
- log_debug("Overwriting earlier assignment of %s in file '%s'.", p, path);
- free(hashmap_remove(sysctl_options, p));
+ log_debug("Overwriting earlier assignment of %s at '%s:%u'.", p, path, c);
+ free(ordered_hashmap_remove(sysctl_options, p));
free(v);
}
@@ -145,7 +163,7 @@ found:
return log_oom();
}
- k = hashmap_put(sysctl_options, property, new_value);
+ k = ordered_hashmap_put(sysctl_options, property, new_value);
if (k < 0) {
log_error_errno(k, "Failed to add sysctl variable %s to hashmap: %m", property);
free(property);
@@ -229,12 +247,12 @@ static int parse_argv(int argc, char *argv[]) {
}
int main(int argc, char *argv[]) {
+ OrderedHashmap *sysctl_options = NULL;
int r = 0, k;
- Hashmap *sysctl_options;
r = parse_argv(argc, argv);
if (r <= 0)
- return r < 0 ? EXIT_FAILURE : EXIT_SUCCESS;
+ goto finish;
log_set_target(LOG_TARGET_AUTO);
log_parse_environment();
@@ -242,7 +260,7 @@ int main(int argc, char *argv[]) {
umask(0022);
- sysctl_options = hashmap_new(&string_hash_ops);
+ sysctl_options = ordered_hashmap_new(&string_hash_ops);
if (!sysctl_options) {
r = log_oom();
goto finish;
@@ -280,7 +298,7 @@ int main(int argc, char *argv[]) {
r = k;
finish:
- hashmap_free_free_free(sysctl_options);
+ ordered_hashmap_free_free_free(sysctl_options);
strv_free(arg_prefixes);
return r < 0 ? EXIT_FAILURE : EXIT_SUCCESS;
diff --git a/src/grp-initprogs/systemd-sysctl/systemd-sysctl.service.in b/src/grp-initprogs/systemd-sysctl/systemd-sysctl.service.in
index d784c6426d..980f611df2 100644
--- a/src/grp-initprogs/systemd-sysctl/systemd-sysctl.service.in
+++ b/src/grp-initprogs/systemd-sysctl/systemd-sysctl.service.in
@@ -12,7 +12,7 @@ DefaultDependencies=no
Conflicts=shutdown.target
After=systemd-modules-load.service
Before=sysinit.target shutdown.target
-ConditionPathIsReadWrite=/proc/sys/
+ConditionPathIsReadWrite=/proc/sys/net/
[Service]
Type=oneshot
diff --git a/src/grp-initprogs/systemd-sysusers/sysusers.c b/src/grp-initprogs/systemd-sysusers/sysusers.c
index 020ddbdf5e..fc1ae6df3a 100644
--- a/src/grp-initprogs/systemd-sysusers/sysusers.c
+++ b/src/grp-initprogs/systemd-sysusers/sysusers.c
@@ -190,7 +190,8 @@ static int load_group_database(void) {
static int make_backup(const char *target, const char *x) {
_cleanup_close_ int src = -1;
_cleanup_fclose_ FILE *dst = NULL;
- char *backup, *temp;
+ _cleanup_free_ char *temp = NULL;
+ char *backup;
struct timespec ts[2];
struct stat st;
int r;
@@ -1189,6 +1190,7 @@ static void item_free(Item *i) {
free(i->uid_path);
free(i->gid_path);
free(i->description);
+ free(i->home);
free(i);
}
@@ -1299,81 +1301,6 @@ static bool item_equal(Item *a, Item *b) {
return true;
}
-static bool valid_user_group_name(const char *u) {
- const char *i;
- long sz;
-
- if (isempty(u))
- return false;
-
- if (!(u[0] >= 'a' && u[0] <= 'z') &&
- !(u[0] >= 'A' && u[0] <= 'Z') &&
- u[0] != '_')
- return false;
-
- for (i = u+1; *i; i++) {
- if (!(*i >= 'a' && *i <= 'z') &&
- !(*i >= 'A' && *i <= 'Z') &&
- !(*i >= '0' && *i <= '9') &&
- *i != '_' &&
- *i != '-')
- return false;
- }
-
- sz = sysconf(_SC_LOGIN_NAME_MAX);
- assert_se(sz > 0);
-
- if ((size_t) (i-u) > (size_t) sz)
- return false;
-
- if ((size_t) (i-u) > UT_NAMESIZE - 1)
- return false;
-
- return true;
-}
-
-static bool valid_gecos(const char *d) {
-
- if (!d)
- return false;
-
- if (!utf8_is_valid(d))
- return false;
-
- if (string_has_cc(d, NULL))
- return false;
-
- /* Colons are used as field separators, and hence not OK */
- if (strchr(d, ':'))
- return false;
-
- return true;
-}
-
-static bool valid_home(const char *p) {
-
- if (isempty(p))
- return false;
-
- if (!utf8_is_valid(p))
- return false;
-
- if (string_has_cc(p, NULL))
- return false;
-
- if (!path_is_absolute(p))
- return false;
-
- if (!path_is_safe(p))
- return false;
-
- /* Colons are used as field separators, and hence not OK */
- if (strchr(p, ':'))
- return false;
-
- return true;
-}
-
static int parse_line(const char *fname, unsigned line, const char *buffer) {
static const Specifier specifier_table[] = {
diff --git a/src/grp-initprogs/systemd-tmpfiles/tmpfiles.d.xml b/src/grp-initprogs/systemd-tmpfiles/tmpfiles.d.xml
index 957475d2bd..e040a1636d 100644
--- a/src/grp-initprogs/systemd-tmpfiles/tmpfiles.d.xml
+++ b/src/grp-initprogs/systemd-tmpfiles/tmpfiles.d.xml
@@ -626,7 +626,7 @@
<example>
<title>Create directories with specific mode and ownership</title>
<para>
- <citerefentry><refentrytitle>screen</refentrytitle><manvolnum>1</manvolnum></citerefentry>,
+ <citerefentry project='die-net'><refentrytitle>screen</refentrytitle><manvolnum>1</manvolnum></citerefentry>,
needs two directories created at boot with specific modes and ownership:</para>
<programlisting># /usr/lib/tmpfiles.d/screen.conf
@@ -644,7 +644,7 @@ d /run/uscreens 0755 root screen 10d12h
t /run/cups - - - - security.SMACK64=printing user.attr-with-spaces="foo bar"
</programlisting>
- <para>The direcory will be owned by root and have default mode. It's contents are
+ <para>The directory will be owned by root and have default mode. Its contents are
not subject to time based cleanup, but will be obliterated when
<command>systemd-tmpfiles --remove</command> runs.</para>
</example>
@@ -652,7 +652,7 @@ t /run/cups - - - - security.SMACK64=printing user.attr-with-spaces="foo bar"
<example>
<title>Create a directory and prevent its contents from cleanup</title>
<para>
- <citerefentry><refentrytitle>abrt</refentrytitle><manvolnum>1</manvolnum></citerefentry>,
+ <citerefentry project='die-net'><refentrytitle>abrt</refentrytitle><manvolnum>1</manvolnum></citerefentry>,
needs a directory created at boot with specific mode and ownership and its content
should be preserved from the automatic cleanup applied to the contents of
<filename>/var/tmp</filename>:</para>
diff --git a/src/grp-initprogs/systemd-update-done/update-done.c b/src/grp-initprogs/systemd-update-done/update-done.c
index 79f755b909..f35e293e3d 100644
--- a/src/grp-initprogs/systemd-update-done/update-done.c
+++ b/src/grp-initprogs/systemd-update-done/update-done.c
@@ -18,72 +18,65 @@
***/
#include "systemd-basic/fd-util.h"
+#include "systemd-basic/fileio.h"
#include "systemd-basic/io-util.h"
#include "systemd-basic/selinux-util.h"
#include "systemd-basic/util.h"
#define MESSAGE \
- "This file was created by systemd-update-done. Its only \n" \
- "purpose is to hold a timestamp of the time this directory\n" \
- "was updated. See systemd-update-done.service(8).\n"
+ "# This file was created by systemd-update-done. Its only \n" \
+ "# purpose is to hold a timestamp of the time this directory\n" \
+ "# was updated. See systemd-update-done.service(8).\n"
static int apply_timestamp(const char *path, struct timespec *ts) {
struct timespec twice[2] = {
*ts,
*ts
};
- struct stat st;
+ _cleanup_fclose_ FILE *f = NULL;
+ int fd = -1;
+ int r;
assert(path);
assert(ts);
- if (stat(path, &st) >= 0) {
- /* Is the timestamp file already newer than the OS? If
- * so, there's nothing to do. We ignore the nanosecond
- * component of the timestamp, since some file systems
- * do not support any better accuracy than 1s and we
- * have no way to identify the accuracy
- * available. Most notably ext4 on small disks (where
- * 128 byte inodes are used) does not support better
- * accuracy than 1s. */
- if (st.st_mtim.tv_sec > ts->tv_sec)
- return 0;
-
- /* It is older? Then let's update it */
- if (utimensat(AT_FDCWD, path, twice, AT_SYMLINK_NOFOLLOW) < 0) {
-
- if (errno == EROFS)
- return log_debug("Can't update timestamp file %s, file system is read-only.", path);
+ /*
+ * We store the timestamp both as mtime of the file and in the file itself,
+ * to support filesystems which cannot store nanosecond-precision timestamps.
+ * Hence, don't bother updating the file, let's just rewrite it.
+ */
- return log_error_errno(errno, "Failed to update timestamp on %s: %m", path);
- }
+ r = mac_selinux_create_file_prepare(path, S_IFREG);
+ if (r < 0)
+ return log_error_errno(r, "Failed to set SELinux context for %s: %m", path);
- } else if (errno == ENOENT) {
- _cleanup_close_ int fd = -1;
- int r;
+ fd = open(path, O_CREAT|O_WRONLY|O_TRUNC|O_CLOEXEC|O_NOCTTY|O_NOFOLLOW, 0644);
+ mac_selinux_create_file_clear();
- /* The timestamp file doesn't exist yet? Then let's create it. */
+ if (fd < 0) {
+ if (errno == EROFS)
+ return log_debug("Can't create timestamp file %s, file system is read-only.", path);
- r = mac_selinux_create_file_prepare(path, S_IFREG);
- if (r < 0)
- return log_error_errno(r, "Failed to set SELinux context for %s: %m", path);
-
- fd = open(path, O_CREAT|O_EXCL|O_WRONLY|O_TRUNC|O_CLOEXEC|O_NOCTTY|O_NOFOLLOW, 0644);
- mac_selinux_create_file_clear();
+ return log_error_errno(errno, "Failed to create/open timestamp file %s: %m", path);
+ }
- if (fd < 0) {
- if (errno == EROFS)
- return log_debug("Can't create timestamp file %s, file system is read-only.", path);
+ f = fdopen(fd, "we");
+ if (!f) {
+ safe_close(fd);
+ return log_error_errno(errno, "Failed to fdopen() timestamp file %s: %m", path);
+ }
- return log_error_errno(errno, "Failed to create timestamp file %s: %m", path);
- }
+ (void) fprintf(f,
+ MESSAGE
+ "TIMESTAMP_NSEC=" NSEC_FMT "\n",
+ timespec_load_nsec(ts));
- (void) loop_write(fd, MESSAGE, strlen(MESSAGE), false);
+ r = fflush_and_check(f);
+ if (r < 0)
+ return log_error_errno(r, "Failed to write timestamp file: %m");
- if (futimens(fd, twice) < 0)
- return log_error_errno(errno, "Failed to update timestamp on %s: %m", path);
- } else
- log_error_errno(errno, "Failed to stat() timestamp file %s: %m", path);
+ if (futimens(fd, twice) < 0)
+ return log_error_errno(errno, "Failed to update timestamp on %s: %m", path);
return 0;
}
diff --git a/src/grp-initprogs/systemd-update-utmp/update-utmp.c b/src/grp-initprogs/systemd-update-utmp/update-utmp.c
index ccb8543cfe..8f622caa64 100644
--- a/src/grp-initprogs/systemd-update-utmp/update-utmp.c
+++ b/src/grp-initprogs/systemd-update-utmp/update-utmp.c
@@ -34,6 +34,7 @@
#include "systemd-basic/log.h"
#include "systemd-basic/macro.h"
#include "systemd-basic/special.h"
+#include "systemd-basic/strv.h"
#include "systemd-basic/unit-name.h"
#include "systemd-basic/util.h"
#include "systemd-shared/utmp-wtmp.h"
@@ -107,7 +108,7 @@ static int get_current_runlevel(Context *c) {
if (r < 0)
return log_warning_errno(r, "Failed to get state: %s", bus_error_message(&error, r));
- if (streq(state, "active") || streq(state, "reloading"))
+ if (STR_IN_SET(state, "active", "reloading"))
return table[i].runlevel;
}
diff --git a/src/grp-initprogs/systemd-vconsole-setup/90-vconsole.rules.in b/src/grp-initprogs/systemd-vconsole-setup/90-vconsole.rules.in
index 35b9ad5151..84b4d575bd 100644
--- a/src/grp-initprogs/systemd-vconsole-setup/90-vconsole.rules.in
+++ b/src/grp-initprogs/systemd-vconsole-setup/90-vconsole.rules.in
@@ -7,4 +7,4 @@
# Each vtcon keeps its own state of fonts.
#
-ACTION=="add", SUBSYSTEM=="vtconsole", KERNEL=="vtcon*", RUN+="@rootlibexecdir@/systemd-vconsole-setup"
+ACTION=="add", SUBSYSTEM=="vtconsole", KERNEL=="vtcon*", ATTR{name}!="*dummy device", RUN+="@rootlibexecdir@/systemd-vconsole-setup"
diff --git a/src/grp-initprogs/systemd-vconsole-setup/Makefile b/src/grp-initprogs/systemd-vconsole-setup/Makefile
index 5a93ae780b..d1918d968e 100644
--- a/src/grp-initprogs/systemd-vconsole-setup/Makefile
+++ b/src/grp-initprogs/systemd-vconsole-setup/Makefile
@@ -38,9 +38,6 @@ nodist_udevrules_DATA += \
nodist_systemunit_DATA += \
units/systemd-vconsole-setup.service
-
-SYSINIT_TARGET_WANTS += \
- systemd-vconsole-setup.service
endif # ENABLE_VCONSOLE
EXTRA_DIST += \
diff --git a/src/grp-initprogs/systemd-vconsole-setup/systemd-vconsole-setup.service.in b/src/grp-initprogs/systemd-vconsole-setup/systemd-vconsole-setup.service.in
index 6160361871..2bd1fd1a5d 100644
--- a/src/grp-initprogs/systemd-vconsole-setup/systemd-vconsole-setup.service.in
+++ b/src/grp-initprogs/systemd-vconsole-setup/systemd-vconsole-setup.service.in
@@ -9,11 +9,8 @@
Description=Setup Virtual Console
Documentation=man:systemd-vconsole-setup.service(8) man:vconsole.conf(5)
DefaultDependencies=no
-Conflicts=shutdown.target
-Before=sysinit.target shutdown.target
ConditionPathExists=/dev/tty0
[Service]
Type=oneshot
-RemainAfterExit=yes
ExecStart=@rootlibexecdir@/systemd-vconsole-setup
diff --git a/src/grp-initprogs/systemd-vconsole-setup/systemd-vconsole-setup.service.xml b/src/grp-initprogs/systemd-vconsole-setup/systemd-vconsole-setup.service.xml
index ff079761c1..f2da2a7b77 100644
--- a/src/grp-initprogs/systemd-vconsole-setup/systemd-vconsole-setup.service.xml
+++ b/src/grp-initprogs/systemd-vconsole-setup/systemd-vconsole-setup.service.xml
@@ -43,61 +43,39 @@
<refnamediv>
<refname>systemd-vconsole-setup.service</refname>
<refname>systemd-vconsole-setup</refname>
- <refpurpose>Configure the virtual console at boot</refpurpose>
+ <refpurpose>Configure the virtual consoles</refpurpose>
</refnamediv>
<refsynopsisdiv>
<para><filename>systemd-vconsole-setup.service</filename></para>
- <para><filename>/usr/lib/systemd/systemd-vconsole-setup</filename></para>
+ <cmdsynopsis>
+ <command>/usr/lib/systemd/systemd-vconsole-setup</command>
+ <arg choice="opt">TTY</arg>
+ </cmdsynopsis>
</refsynopsisdiv>
<refsect1>
<title>Description</title>
- <para><filename>systemd-vconsole-setup.service</filename> is an
- early boot service that configures the virtual console font and
- console keymap. Internally it calls
- <citerefentry project='mankier'><refentrytitle>loadkeys</refentrytitle><manvolnum>1</manvolnum></citerefentry>
- and
- <citerefentry project='die-net'><refentrytitle>setfont</refentrytitle><manvolnum>8</manvolnum></citerefentry>.</para>
-
- <para>See
- <citerefentry><refentrytitle>vconsole.conf</refentrytitle><manvolnum>5</manvolnum></citerefentry>
- for information about the configuration files understood by this
- service.</para>
-
-
- </refsect1>
-
- <refsect1>
- <title>Kernel Command Line</title>
-
- <para>A few configuration parameters from
- <filename>vconsole.conf</filename> may be overridden on the kernel
- command line:</para>
-
- <variablelist class='kernel-commandline-options'>
- <varlistentry>
- <term><varname>vconsole.keymap=</varname></term>
- <term><varname>vconsole.keymap.toggle=</varname></term>
-
- <listitem><para>Overrides the key mapping table for the
- keyboard and the second toggle keymap.</para></listitem>
- </varlistentry>
- <varlistentry>
-
- <term><varname>vconsole.font=</varname></term>
- <term><varname>vconsole.font.map=</varname></term>
- <term><varname>vconsole.font.unimap=</varname></term>
+ <para><filename>systemd-vconsole-setup</filename> is a helper used to prepare either all virtual consoles, or — if
+ the optional <replaceable>TTY</replaceable> parameter is provided — a specific one. When the system is booting up
+ it's called by <citerefentry><command>udev</command></citerefentry> during vtconsole subsystem initialization.
+ <productname>Systemd</productname> also calls it internally as needed via
+ <filename>systemd-vconsole-setup.service</filename>. The helper calls
+ <citerefentry project='mankier'><refentrytitle>loadkeys</refentrytitle><manvolnum>1</manvolnum></citerefentry> and
+ <citerefentry project='die-net'><refentrytitle>setfont</refentrytitle><manvolnum>8</manvolnum></citerefentry>
+ internally.
+ </para>
- <listitem><para>Configures the console font, the console map,
- and the unicode font map.</para></listitem>
- </varlistentry>
- </variablelist>
+ <para>
+ You may want to use this helper whenever you change <filename>vconsole.conf</filename> to
+ refresh the settings on your consoles — either through the <command>systemctl restart</command> /
+ <command>systemctl start</command> command or directly through the executable.
+ </para>
<para>See
<citerefentry><refentrytitle>vconsole.conf</refentrytitle><manvolnum>5</manvolnum></citerefentry>
- for information about these settings.</para>
+ for information about the configuration files and kernel command line options understood by this program.</para>
</refsect1>
<refsect1>
diff --git a/src/grp-initprogs/systemd-vconsole-setup/vconsole-setup.c b/src/grp-initprogs/systemd-vconsole-setup/vconsole-setup.c
index 7edab74051..ad6a4283fc 100644
--- a/src/grp-initprogs/systemd-vconsole-setup/vconsole-setup.c
+++ b/src/grp-initprogs/systemd-vconsole-setup/vconsole-setup.c
@@ -2,6 +2,7 @@
This file is part of systemd.
Copyright 2010 Kay Sievers
+ Copyright 2016 Michal Soltys <soltys@ziu.info>
systemd is free software; you can redistribute it and/or modify it
under the terms of the GNU Lesser General Public License as published by
@@ -24,6 +25,7 @@
#include <stdio.h>
#include <stdlib.h>
#include <sys/ioctl.h>
+#include <termios.h>
#include <unistd.h>
#include <linux/kd.h>
@@ -51,67 +53,85 @@ static bool is_vconsole(int fd) {
return ioctl(fd, TIOCLINUX, data) >= 0;
}
-static int disable_utf8(int fd) {
- int r = 0, k;
+static bool is_allocated(unsigned int idx) {
+ char vcname[strlen("/dev/vcs") + DECIMAL_STR_MAX(int)];
- if (ioctl(fd, KDSKBMODE, K_XLATE) < 0)
- r = -errno;
-
- k = loop_write(fd, "\033%@", 3, false);
- if (k < 0)
- r = k;
+ xsprintf(vcname, "/dev/vcs%i", idx);
+ return access(vcname, F_OK) == 0;
+}
- k = write_string_file("/sys/module/vt/parameters/default_utf8", "0", 0);
- if (k < 0)
- r = k;
+static bool is_allocated_byfd(int fd) {
+ struct vt_stat vcs = {};
- if (r < 0)
- log_warning_errno(r, "Failed to disable UTF-8: %m");
+ if (ioctl(fd, VT_GETSTATE, &vcs) < 0) {
+ log_warning_errno(errno, "VT_GETSTATE failed: %m");
+ return false;
+ }
+ return is_allocated(vcs.v_active);
+}
- return r;
+static bool is_settable(int fd) {
+ int r, curr_mode;
+
+ r = ioctl(fd, KDGKBMODE, &curr_mode);
+ /*
+ * Make sure we only adjust consoles in K_XLATE or K_UNICODE mode.
+ * Otherwise we would (likely) interfere with X11's processing of the
+ * key events.
+ *
+ * http://lists.freedesktop.org/archives/systemd-devel/2013-February/008573.html
+ */
+ return r == 0 && IN_SET(curr_mode, K_XLATE, K_UNICODE);
}
-static int enable_utf8(int fd) {
- int r = 0, k;
- long current = 0;
-
- if (ioctl(fd, KDGKBMODE, &current) < 0 || current == K_XLATE) {
- /*
- * Change the current keyboard to unicode, unless it
- * is currently in raw or off mode anyway. We
- * shouldn't interfere with X11's processing of the
- * key events.
- *
- * http://lists.freedesktop.org/archives/systemd-devel/2013-February/008573.html
- *
- */
-
- if (ioctl(fd, KDSKBMODE, K_UNICODE) < 0)
- r = -errno;
+static int toggle_utf8(const char *name, int fd, bool utf8) {
+ int r;
+ struct termios tc = {};
+
+ assert(name);
+
+ r = ioctl(fd, KDSKBMODE, utf8 ? K_UNICODE : K_XLATE);
+ if (r < 0)
+ return log_warning_errno(errno, "Failed to %s UTF-8 kbdmode on %s: %m", enable_disable(utf8), name);
+
+ r = loop_write(fd, utf8 ? "\033%G" : "\033%@", 3, false);
+ if (r < 0)
+ return log_warning_errno(r, "Failed to %s UTF-8 term processing on %s: %m", enable_disable(utf8), name);
+
+ r = tcgetattr(fd, &tc);
+ if (r >= 0) {
+ if (utf8)
+ tc.c_iflag |= IUTF8;
+ else
+ tc.c_iflag &= ~IUTF8;
+ r = tcsetattr(fd, TCSANOW, &tc);
}
+ if (r < 0)
+ return log_warning_errno(errno, "Failed to %s iutf8 flag on %s: %m", enable_disable(utf8), name);
- k = loop_write(fd, "\033%G", 3, false);
- if (k < 0)
- r = k;
+ log_debug("UTF-8 kbdmode %sd on %s", enable_disable(utf8), name);
+ return 0;
+}
- k = write_string_file("/sys/module/vt/parameters/default_utf8", "1", 0);
- if (k < 0)
- r = k;
+static int toggle_utf8_sysfs(bool utf8) {
+ int r;
+ r = write_string_file("/sys/module/vt/parameters/default_utf8", one_zero(utf8), 0);
if (r < 0)
- log_warning_errno(r, "Failed to enable UTF-8: %m");
+ return log_warning_errno(r, "Failed to %s sysfs UTF-8 flag: %m", enable_disable(utf8));
- return r;
+ log_debug("Sysfs UTF-8 flag %sd", enable_disable(utf8));
+ return 0;
}
static int keyboard_load_and_wait(const char *vc, const char *map, const char *map_toggle, bool utf8) {
const char *args[8];
- int i = 0, r;
+ int i = 0;
pid_t pid;
/* An empty map means kernel map */
if (isempty(map))
- return 1;
+ return 0;
args[i++] = KBD_LOADKEYS;
args[i++] = "-q";
@@ -136,34 +156,31 @@ static int keyboard_load_and_wait(const char *vc, const char *map, const char *m
_exit(EXIT_FAILURE);
}
- r = wait_for_terminate_and_warn(KBD_LOADKEYS, pid, true);
- if (r < 0)
- return r;
-
- return r == 0;
+ return wait_for_terminate_and_warn(KBD_LOADKEYS, pid, true);
}
static int font_load_and_wait(const char *vc, const char *font, const char *map, const char *unimap) {
const char *args[9];
- int i = 0, r;
+ int i = 0;
pid_t pid;
- /* An empty font means kernel font */
- if (isempty(font))
- return 1;
+ /* Any part can be set independently */
+ if (isempty(font) && isempty(map) && isempty(unimap))
+ return 0;
args[i++] = KBD_SETFONT;
args[i++] = "-C";
args[i++] = vc;
- args[i++] = font;
- if (map) {
+ if (!isempty(map)) {
args[i++] = "-m";
args[i++] = map;
}
- if (unimap) {
+ if (!isempty(unimap)) {
args[i++] = "-u";
args[i++] = unimap;
}
+ if (!isempty(font))
+ args[i++] = font;
args[i++] = NULL;
pid = fork();
@@ -178,11 +195,7 @@ static int font_load_and_wait(const char *vc, const char *font, const char *map,
_exit(EXIT_FAILURE);
}
- r = wait_for_terminate_and_warn(KBD_SETFONT, pid, true);
- if (r < 0)
- return r;
-
- return r == 0;
+ return wait_for_terminate_and_warn(KBD_SETFONT, pid, true);
}
/*
@@ -190,13 +203,21 @@ static int font_load_and_wait(const char *vc, const char *font, const char *map,
* we update all possibly already allocated VTs with the configured
* font. It also allows to restart systemd-vconsole-setup.service,
* to apply a new font to all VTs.
+ *
+ * We also setup per-console utf8 related stuff: kbdmode, term
+ * processing, stty iutf8.
*/
-static void font_copy_to_all_vcs(int fd) {
+static void setup_remaining_vcs(int fd, bool utf8) {
+ struct console_font_op cfo = {
+ .op = KD_FONT_OP_GET,
+ .width = UINT_MAX, .height = UINT_MAX,
+ .charcount = UINT_MAX,
+ };
struct vt_stat vcs = {};
- unsigned char map8[E_TABSZ];
- unsigned short map16[E_TABSZ];
+ struct unimapinit adv = {};
struct unimapdesc unimapd;
_cleanup_free_ struct unipair* unipairs = NULL;
+ _cleanup_free_ void *fontbuf = NULL;
int i, r;
unipairs = new(struct unipair, USHRT_MAX);
@@ -208,52 +229,96 @@ static void font_copy_to_all_vcs(int fd) {
/* get active, and 16 bit mask of used VT numbers */
r = ioctl(fd, VT_GETSTATE, &vcs);
if (r < 0) {
- log_debug_errno(errno, "VT_GETSTATE failed, ignoring: %m");
+ log_warning_errno(errno, "VT_GETSTATE failed, ignoring remaining consoles: %m");
return;
}
- for (i = 1; i <= 15; i++) {
- char vcname[strlen("/dev/vcs") + DECIMAL_STR_MAX(int)];
- _cleanup_close_ int vcfd = -1;
- struct console_font_op cfo = {};
+ /* get metadata of the current font (width, height, count) */
+ r = ioctl(fd, KDFONTOP, &cfo);
+ if (r < 0)
+ log_warning_errno(errno, "KD_FONT_OP_GET failed while trying to get the font metadata: %m");
+ else {
+ /* verify parameter sanity first */
+ if (cfo.width > 32 || cfo.height > 32 || cfo.charcount > 512)
+ log_warning("Invalid font metadata - width: %u (max 32), height: %u (max 32), count: %u (max 512)",
+ cfo.width, cfo.height, cfo.charcount);
+ else {
+ /*
+ * Console fonts supported by the kernel are limited in size to 32 x 32 and maximum 512
+ * characters. Thus with 1 bit per pixel it requires up to 65536 bytes. The height always
+ * requries 32 per glyph, regardless of the actual height - see the comment above #define
+ * max_font_size 65536 in drivers/tty/vt/vt.c for more details.
+ */
+ fontbuf = malloc((cfo.width + 7) / 8 * 32 * cfo.charcount);
+ if (!fontbuf) {
+ log_oom();
+ return;
+ }
+ /* get fonts from source console */
+ cfo.data = fontbuf;
+ r = ioctl(fd, KDFONTOP, &cfo);
+ if (r < 0)
+ log_warning_errno(errno, "KD_FONT_OP_GET failed while trying to read the font data: %m");
+ else {
+ unimapd.entries = unipairs;
+ unimapd.entry_ct = USHRT_MAX;
+ r = ioctl(fd, GIO_UNIMAP, &unimapd);
+ if (r < 0)
+ log_warning_errno(errno, "GIO_UNIMAP failed while trying to read unicode mappings: %m");
+ else
+ cfo.op = KD_FONT_OP_SET;
+ }
+ }
+ }
+
+ if (cfo.op != KD_FONT_OP_SET)
+ log_warning("Fonts will not be copied to remaining consoles");
+
+ for (i = 1; i <= 63; i++) {
+ char ttyname[strlen("/dev/tty") + DECIMAL_STR_MAX(int)];
+ _cleanup_close_ int fd_d = -1;
- if (i == vcs.v_active)
+ if (i == vcs.v_active || !is_allocated(i))
continue;
- /* skip non-allocated ttys */
- xsprintf(vcname, "/dev/vcs%i", i);
- if (access(vcname, F_OK) < 0)
+ /* try to open terminal */
+ xsprintf(ttyname, "/dev/tty%i", i);
+ fd_d = open_terminal(ttyname, O_RDWR|O_CLOEXEC);
+ if (fd_d < 0) {
+ log_warning_errno(fd_d, "Unable to open tty%i, fonts will not be copied: %m", i);
continue;
+ }
- xsprintf(vcname, "/dev/tty%i", i);
- vcfd = open_terminal(vcname, O_RDWR|O_CLOEXEC);
- if (vcfd < 0)
+ if (!is_settable(fd_d))
continue;
- /* copy font from active VT, where the font was uploaded to */
- cfo.op = KD_FONT_OP_COPY;
- cfo.height = vcs.v_active-1; /* tty1 == index 0 */
- (void) ioctl(vcfd, KDFONTOP, &cfo);
+ toggle_utf8(ttyname, fd_d, utf8);
- /* copy map of 8bit chars */
- if (ioctl(fd, GIO_SCRNMAP, map8) >= 0)
- (void) ioctl(vcfd, PIO_SCRNMAP, map8);
+ if (cfo.op != KD_FONT_OP_SET)
+ continue;
- /* copy map of 8bit chars -> 16bit Unicode values */
- if (ioctl(fd, GIO_UNISCRNMAP, map16) >= 0)
- (void) ioctl(vcfd, PIO_UNISCRNMAP, map16);
+ r = ioctl(fd_d, KDFONTOP, &cfo);
+ if (r < 0) {
+ log_warning_errno(errno, "KD_FONT_OP_SET failed, fonts will not be copied to tty%i: %m", i);
+ continue;
+ }
/* copy unicode translation table */
/* unimapd is a ushort count and a pointer to an
array of struct unipair { ushort, ushort } */
- unimapd.entries = unipairs;
- unimapd.entry_ct = USHRT_MAX;
- if (ioctl(fd, GIO_UNIMAP, &unimapd) >= 0) {
- struct unimapinit adv = { 0, 0, 0 };
+ r = ioctl(fd_d, PIO_UNIMAPCLR, &adv);
+ if (r < 0) {
+ log_warning_errno(errno, "PIO_UNIMAPCLR failed, unimaps might be incorrect for tty%i: %m", i);
+ continue;
+ }
- (void) ioctl(vcfd, PIO_UNIMAPCLR, &adv);
- (void) ioctl(vcfd, PIO_UNIMAP, &unimapd);
+ r = ioctl(fd_d, PIO_UNIMAP, &unimapd);
+ if (r < 0) {
+ log_warning_errno(errno, "PIO_UNIMAP failed, unimaps might be incorrect for tty%i: %m", i);
+ continue;
}
+
+ log_debug("Font and unimap successfully copied to %s", ttyname);
}
}
@@ -290,6 +355,16 @@ int main(int argc, char **argv) {
return EXIT_FAILURE;
}
+ if (!is_allocated_byfd(fd)) {
+ log_error("Virtual console %s is not allocated.", vc);
+ return EXIT_FAILURE;
+ }
+
+ if (!is_settable(fd)) {
+ log_error("Virtual console %s is not in K_XLATE or K_UNICODE.", vc);
+ return EXIT_FAILURE;
+ }
+
utf8 = is_locale_utf8();
r = parse_env_file("/etc/vconsole.conf", NEWLINE,
@@ -307,8 +382,12 @@ int main(int argc, char **argv) {
if (detect_container() <= 0) {
r = parse_env_file("/proc/cmdline", WHITESPACE,
"vconsole.keymap", &vc_keymap,
- "vconsole.keymap.toggle", &vc_keymap_toggle,
+ "vconsole.keymap_toggle", &vc_keymap_toggle,
"vconsole.font", &vc_font,
+ "vconsole.font_map", &vc_font_map,
+ "vconsole.font_unimap", &vc_font_unimap,
+ /* compatibility with obsolete multiple-dot scheme */
+ "vconsole.keymap.toggle", &vc_keymap_toggle,
"vconsole.font.map", &vc_font_map,
"vconsole.font.unimap", &vc_font_unimap,
NULL);
@@ -317,17 +396,17 @@ int main(int argc, char **argv) {
log_warning_errno(r, "Failed to read /proc/cmdline: %m");
}
- if (utf8)
- (void) enable_utf8(fd);
- else
- (void) disable_utf8(fd);
+ toggle_utf8_sysfs(utf8);
+ toggle_utf8(vc, fd, utf8);
+ font_ok = font_load_and_wait(vc, vc_font, vc_font_map, vc_font_unimap) == 0;
+ keyboard_ok = keyboard_load_and_wait(vc, vc_keymap, vc_keymap_toggle, utf8) == 0;
- font_ok = font_load_and_wait(vc, vc_font, vc_font_map, vc_font_unimap) > 0;
- keyboard_ok = keyboard_load_and_wait(vc, vc_keymap, vc_keymap_toggle, utf8) > 0;
-
- /* Only copy the font when we executed setfont successfully */
- if (font_copy && font_ok)
- (void) font_copy_to_all_vcs(fd);
+ if (font_copy) {
+ if (font_ok)
+ setup_remaining_vcs(fd, utf8);
+ else
+ log_warning("Setting source virtual console failed, ignoring remaining ones");
+ }
return font_ok && keyboard_ok ? EXIT_SUCCESS : EXIT_FAILURE;
}
diff --git a/src/grp-initprogs/systemd-vconsole-setup/vconsole.conf.xml b/src/grp-initprogs/systemd-vconsole-setup/vconsole.conf.xml
index 27196d44e9..fa30ca6569 100644
--- a/src/grp-initprogs/systemd-vconsole-setup/vconsole.conf.xml
+++ b/src/grp-initprogs/systemd-vconsole-setup/vconsole.conf.xml
@@ -55,8 +55,9 @@
<para>The <filename>/etc/vconsole.conf</filename> file configures
the virtual console, i.e. keyboard mapping and console font. It is
- applied at boot by
- <citerefentry><refentrytitle>systemd-vconsole-setup.service</refentrytitle><manvolnum>8</manvolnum></citerefentry>.</para>
+ applied at boot by udev using <filename>90-vconsole.rules</filename> file.
+ You can safely mask this file if you want to avoid this kind of initialization.
+ </para>
<para>The basic file format of the
<filename>vconsole.conf</filename> is a newline-separated list of
@@ -68,10 +69,10 @@
<para>Note that the kernel command line options
<varname>vconsole.keymap=</varname>,
- <varname>vconsole.keymap.toggle=</varname>,
+ <varname>vconsole.keymap_toggle=</varname>,
<varname>vconsole.font=</varname>,
- <varname>vconsole.font.map=</varname>,
- <varname>vconsole.font.unimap=</varname> may be used
+ <varname>vconsole.font_map=</varname>,
+ <varname>vconsole.font_unimap=</varname> may be used
to override the console settings at boot.</para>
<para>Depending on the operating system other configuration files
@@ -90,12 +91,10 @@
<term><varname>KEYMAP=</varname></term>
<term><varname>KEYMAP_TOGGLE=</varname></term>
- <listitem><para>Configures the key mapping table for the
- keyboard. <varname>KEYMAP=</varname> defaults to
- <literal>us</literal> if not set. The
- <varname>KEYMAP_TOGGLE=</varname> can be used to configure a
- second toggle keymap and is by default
- unset.</para></listitem>
+ <listitem><para>Configures the key mapping table for the keyboard.
+ <varname>KEYMAP=</varname> defaults to <literal>us</literal> if not set. The
+ <varname>KEYMAP_TOGGLE=</varname> can be used to configure a second toggle keymap and is by
+ default unset.</para></listitem>
</varlistentry>
<varlistentry>
@@ -111,6 +110,32 @@
</refsect1>
<refsect1>
+ <title>Kernel Command Line</title>
+
+ <para>A few configuration parameters from <filename>vconsole.conf</filename> may be overridden
+ on the kernel command line:</para>
+
+ <variablelist class='kernel-commandline-options'>
+ <varlistentry>
+ <term><varname>vconsole.keymap=</varname></term>
+ <term><varname>vconsole.keymap_toggle=</varname></term>
+
+ <listitem><para>Overrides <varname>KEYMAP=</varname> and <varname>KEYMAP_TOGGLE=</varname>.
+ </para></listitem>
+ </varlistentry>
+ <varlistentry>
+
+ <term><varname>vconsole.font=</varname></term>
+ <term><varname>vconsole.font_map=</varname></term>
+ <term><varname>vconsole.font_unimap=</varname></term>
+
+ <listitem><para>Overrides <varname>FONT=</varname>, <varname>FONT_MAP=</varname>, and
+ <varname>FONT_UNIMAP=</varname>.</para></listitem>
+ </varlistentry>
+ </variablelist>
+ </refsect1>
+
+ <refsect1>
<title>Example</title>
<example>