Update to latest git
This commit is contained in:
parent
5cdc00d6e6
commit
62fe9450da
@ -1,32 +0,0 @@
|
||||
From 73403e8de2c5bc6d54f89ae2f1c9aa12b92ecb7a Mon Sep 17 00:00:00 2001
|
||||
From: Colin Walters <walters@verbum.org>
|
||||
Date: Mon, 7 Jul 2014 08:27:43 -0400
|
||||
Subject: [PATCH] resolved: Move symlink creation from tmpfiles to daemon
|
||||
runtime
|
||||
|
||||
At least Fedora right now doesn't by default use resolved; the service
|
||||
is disabled by default in the 90-default.preset file.
|
||||
|
||||
The change to unconditionally create the resolv.conf symlink broke
|
||||
Anaconda and related tools (lorax) which expect it to be a regular
|
||||
file. In particular, Anaconda expects to be able to persist
|
||||
networking state from the installation environment to the target
|
||||
system.
|
||||
---
|
||||
tmpfiles.d/etc.conf | 1 -
|
||||
2 files changed, 9 insertions(+), 1 deletion(-)
|
||||
|
||||
diff --git a/tmpfiles.d/etc.conf b/tmpfiles.d/etc.conf
|
||||
index b23272cb27..125d6e0a17 100644
|
||||
--- a/tmpfiles.d/etc.conf
|
||||
+++ b/tmpfiles.d/etc.conf
|
||||
@@ -10,6 +10,5 @@
|
||||
L /etc/os-release - - - - ../usr/lib/os-release
|
||||
L /etc/localtime - - - - ../usr/share/zoneinfo/UTC
|
||||
L+ /etc/mtab - - - - ../proc/self/mounts
|
||||
-L /etc/resolv.conf - - - - ../run/systemd/resolve/resolv.conf
|
||||
C /etc/nsswitch.conf - - - -
|
||||
C /etc/pam.d - - - -
|
||||
--
|
||||
1.9.3
|
||||
|
@ -0,0 +1,52 @@
|
||||
From fdbdf6ec29bda40763d7d3e7bb2a63e2f5d60c4c Mon Sep 17 00:00:00 2001
|
||||
From: Lukas Nykryn <lnykryn@redhat.com>
|
||||
Date: Tue, 19 Aug 2014 20:53:29 +0200
|
||||
Subject: [PATCH] systemctl: fail in the case that no unit files were found
|
||||
|
||||
Previously systemctl died with message
|
||||
|
||||
-bash-4.2# systemctl --root /rawhi list-unit-files
|
||||
(src/systemctl/systemctl.c:868) Out of memory.
|
||||
|
||||
in the case that no unit files were found in the --root
|
||||
or the directory did not exist.
|
||||
|
||||
So lets return ENOENT in the case that --root does not exist
|
||||
and empty list in the case that there are no unit files.
|
||||
---
|
||||
src/shared/install.c | 6 ++++++
|
||||
src/systemctl/systemctl.c | 4 ++++
|
||||
2 files changed, 10 insertions(+)
|
||||
|
||||
diff --git a/src/shared/install.c b/src/shared/install.c
|
||||
index 0fe1371129..03c7a9da2e 100644
|
||||
--- a/src/shared/install.c
|
||||
+++ b/src/shared/install.c
|
||||
@@ -2044,6 +2044,12 @@ int unit_file_get_list(
|
||||
if (root_dir && scope != UNIT_FILE_SYSTEM)
|
||||
return -EINVAL;
|
||||
|
||||
+ if (root_dir) {
|
||||
+ r = access(root_dir, F_OK);
|
||||
+ if (r < 0)
|
||||
+ return -errno;
|
||||
+ }
|
||||
+
|
||||
r = lookup_paths_init_from_scope(&paths, scope, root_dir);
|
||||
if (r < 0)
|
||||
return r;
|
||||
diff --git a/src/systemctl/systemctl.c b/src/systemctl/systemctl.c
|
||||
index 36db652316..072f615ad5 100644
|
||||
--- a/src/systemctl/systemctl.c
|
||||
+++ b/src/systemctl/systemctl.c
|
||||
@@ -1350,6 +1350,10 @@ static int list_unit_files(sd_bus *bus, char **args) {
|
||||
}
|
||||
|
||||
n_units = hashmap_size(h);
|
||||
+
|
||||
+ if (n_units == 0)
|
||||
+ return 0;
|
||||
+
|
||||
units = new(UnitFileList, n_units);
|
||||
if (!units) {
|
||||
unit_file_list_free(h);
|
26
0002-build-remove-repeated-KMOD-section.patch
Normal file
26
0002-build-remove-repeated-KMOD-section.patch
Normal file
@ -0,0 +1,26 @@
|
||||
From 413f6df864083130a380b2f7adbb5aa970139fe7 Mon Sep 17 00:00:00 2001
|
||||
From: Tom Gundersen <teg@jklm.no>
|
||||
Date: Wed, 20 Aug 2014 11:25:23 +0200
|
||||
Subject: [PATCH] build: remove repeated KMOD section
|
||||
|
||||
---
|
||||
src/core/build.h | 6 ------
|
||||
1 file changed, 6 deletions(-)
|
||||
|
||||
diff --git a/src/core/build.h b/src/core/build.h
|
||||
index d380382aba..a7f12a33e4 100644
|
||||
--- a/src/core/build.h
|
||||
+++ b/src/core/build.h
|
||||
@@ -123,12 +123,6 @@
|
||||
#define _KMOD_FEATURE_ "-KMOD"
|
||||
#endif
|
||||
|
||||
-#ifdef HAVE_KMOD
|
||||
-#define _KMOD_FEATURE_ "+KMOD"
|
||||
-#else
|
||||
-#define _KMOD_FEATURE_ "-KMOD"
|
||||
-#endif
|
||||
-
|
||||
#ifdef HAVE_LIBIDN
|
||||
#define _IDN_FEATURE_ "+IDN"
|
||||
#else
|
120
0003-machine-id-setup-don-t-try-to-read-UUID-from-VM-cont.patch
Normal file
120
0003-machine-id-setup-don-t-try-to-read-UUID-from-VM-cont.patch
Normal file
@ -0,0 +1,120 @@
|
||||
From 5dd6d0f8ff1681fff9369e0aa2532979954dbfde Mon Sep 17 00:00:00 2001
|
||||
From: Lennart Poettering <lennart@poettering.net>
|
||||
Date: Wed, 20 Aug 2014 13:49:39 +0200
|
||||
Subject: [PATCH] machine-id-setup: don't try to read UUID from VM/container
|
||||
manager if we operate on a root directory that's not /
|
||||
|
||||
This should make sure no UUID from the host systemd-machine-id-setup is
|
||||
running on leaks onto a disk image that is provisioned with the tool.
|
||||
---
|
||||
src/core/machine-id-setup.c | 79 +++++++++++++++++++++++----------------------
|
||||
1 file changed, 41 insertions(+), 38 deletions(-)
|
||||
|
||||
diff --git a/src/core/machine-id-setup.c b/src/core/machine-id-setup.c
|
||||
index 712f60cb11..efb074fcbd 100644
|
||||
--- a/src/core/machine-id-setup.c
|
||||
+++ b/src/core/machine-id-setup.c
|
||||
@@ -64,15 +64,16 @@ static int generate(char id[34], const char *root) {
|
||||
int fd, r;
|
||||
unsigned char *p;
|
||||
sd_id128_t buf;
|
||||
- char *q;
|
||||
+ char *q;
|
||||
ssize_t k;
|
||||
- const char *vm_id;
|
||||
- _cleanup_free_ char *dbus_machine_id = NULL;
|
||||
+ const char *vm_id, *dbus_machine_id;
|
||||
|
||||
assert(id);
|
||||
|
||||
- if (asprintf(&dbus_machine_id, "%s/var/lib/dbus/machine-id", root) < 0)
|
||||
- return log_oom();
|
||||
+ if (isempty(root))
|
||||
+ dbus_machine_id = "/var/lib/dbus/machine-id";
|
||||
+ else
|
||||
+ dbus_machine_id = strappenda(root, "/var/lib/dbus/machine-id");
|
||||
|
||||
/* First, try reading the D-Bus machine id, unless it is a symlink */
|
||||
fd = open(dbus_machine_id, O_RDONLY|O_CLOEXEC|O_NOCTTY|O_NOFOLLOW);
|
||||
@@ -93,46 +94,48 @@ static int generate(char id[34], const char *root) {
|
||||
}
|
||||
}
|
||||
|
||||
- /* If that didn't work, see if we are running in a container,
|
||||
- * and a machine ID was passed in via $container_uuid the way
|
||||
- * libvirt/LXC does it */
|
||||
- r = detect_container(NULL);
|
||||
- if (r > 0) {
|
||||
- _cleanup_free_ char *e = NULL;
|
||||
-
|
||||
- r = getenv_for_pid(1, "container_uuid", &e);
|
||||
+ if (isempty(root)) {
|
||||
+ /* If that didn't work, see if we are running in a container,
|
||||
+ * and a machine ID was passed in via $container_uuid the way
|
||||
+ * libvirt/LXC does it */
|
||||
+ r = detect_container(NULL);
|
||||
if (r > 0) {
|
||||
- if (strlen(e) >= 36) {
|
||||
- r = shorten_uuid(id, e);
|
||||
- if (r >= 0) {
|
||||
- log_info("Initializing machine ID from container UUID.");
|
||||
- return 0;
|
||||
- }
|
||||
- }
|
||||
- }
|
||||
-
|
||||
- } else {
|
||||
- /* If we are not running in a container, see if we are
|
||||
- * running in qemu/kvm and a machine ID was passed in
|
||||
- * via -uuid on the qemu/kvm command line */
|
||||
+ _cleanup_free_ char *e = NULL;
|
||||
|
||||
- r = detect_vm(&vm_id);
|
||||
- if (r > 0 && streq(vm_id, "kvm")) {
|
||||
- char uuid[37];
|
||||
-
|
||||
- fd = open("/sys/class/dmi/id/product_uuid", O_RDONLY|O_CLOEXEC|O_NOCTTY|O_NOFOLLOW);
|
||||
- if (fd >= 0) {
|
||||
- k = loop_read(fd, uuid, 36, false);
|
||||
- safe_close(fd);
|
||||
-
|
||||
- if (k >= 36) {
|
||||
- r = shorten_uuid(id, uuid);
|
||||
+ r = getenv_for_pid(1, "container_uuid", &e);
|
||||
+ if (r > 0) {
|
||||
+ if (strlen(e) >= 36) {
|
||||
+ r = shorten_uuid(id, e);
|
||||
if (r >= 0) {
|
||||
- log_info("Initializing machine ID from KVM UUID.");
|
||||
+ log_info("Initializing machine ID from container UUID.");
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
+
|
||||
+ } else {
|
||||
+ /* If we are not running in a container, see if we are
|
||||
+ * running in qemu/kvm and a machine ID was passed in
|
||||
+ * via -uuid on the qemu/kvm command line */
|
||||
+
|
||||
+ r = detect_vm(&vm_id);
|
||||
+ if (r > 0 && streq(vm_id, "kvm")) {
|
||||
+ char uuid[37];
|
||||
+
|
||||
+ fd = open("/sys/class/dmi/id/product_uuid", O_RDONLY|O_CLOEXEC|O_NOCTTY|O_NOFOLLOW);
|
||||
+ if (fd >= 0) {
|
||||
+ k = loop_read(fd, uuid, 36, false);
|
||||
+ safe_close(fd);
|
||||
+
|
||||
+ if (k >= 36) {
|
||||
+ r = shorten_uuid(id, uuid);
|
||||
+ if (r >= 0) {
|
||||
+ log_info("Initializing machine ID from KVM UUID.");
|
||||
+ return 0;
|
||||
+ }
|
||||
+ }
|
||||
+ }
|
||||
+ }
|
||||
}
|
||||
}
|
||||
|
36
0004-resolved-dns-rr-fix-typo.patch
Normal file
36
0004-resolved-dns-rr-fix-typo.patch
Normal file
@ -0,0 +1,36 @@
|
||||
From 03664a62914782dbd8f069bbcf8a0c8ca1df7010 Mon Sep 17 00:00:00 2001
|
||||
From: Lukas Nykryn <lnykryn@redhat.com>
|
||||
Date: Wed, 20 Aug 2014 14:34:23 +0200
|
||||
Subject: [PATCH] resolved-dns-rr: fix typo
|
||||
|
||||
a->rrsig.type_covered != a->rrsig.type_covered" is always false
|
||||
regardless of the values of its operands because those operands are identical.
|
||||
---
|
||||
src/resolve/resolved-dns-rr.c | 14 +++++++-------
|
||||
1 file changed, 7 insertions(+), 7 deletions(-)
|
||||
|
||||
diff --git a/src/resolve/resolved-dns-rr.c b/src/resolve/resolved-dns-rr.c
|
||||
index c792deda47..c5f7cb931e 100644
|
||||
--- a/src/resolve/resolved-dns-rr.c
|
||||
+++ b/src/resolve/resolved-dns-rr.c
|
||||
@@ -425,13 +425,13 @@ int dns_resource_record_equal(const DnsResourceRecord *a, const DnsResourceRecor
|
||||
|
||||
case DNS_TYPE_RRSIG:
|
||||
/* do the fast comparisons first */
|
||||
- if (a->rrsig.type_covered != a->rrsig.type_covered ||
|
||||
- a->rrsig.algorithm != a->rrsig.algorithm ||
|
||||
- a->rrsig.labels != a->rrsig.labels ||
|
||||
- a->rrsig.original_ttl != a->rrsig.original_ttl ||
|
||||
- a->rrsig.expiration != a->rrsig.expiration ||
|
||||
- a->rrsig.inception != a->rrsig.inception ||
|
||||
- a->rrsig.key_tag != a->rrsig.key_tag ||
|
||||
+ if (a->rrsig.type_covered != b->rrsig.type_covered ||
|
||||
+ a->rrsig.algorithm != b->rrsig.algorithm ||
|
||||
+ a->rrsig.labels != b->rrsig.labels ||
|
||||
+ a->rrsig.original_ttl != b->rrsig.original_ttl ||
|
||||
+ a->rrsig.expiration != b->rrsig.expiration ||
|
||||
+ a->rrsig.inception != b->rrsig.inception ||
|
||||
+ a->rrsig.key_tag != b->rrsig.key_tag ||
|
||||
a->rrsig.signature_size != b->rrsig.signature_size ||
|
||||
memcmp(a->rrsig.signature, b->rrsig.signature, a->rrsig.signature_size) != 0)
|
||||
return false;
|
25
0005-resolved-fix-which-return-codes-we-check.patch
Normal file
25
0005-resolved-fix-which-return-codes-we-check.patch
Normal file
@ -0,0 +1,25 @@
|
||||
From be754d5443e5fe44ead733ad509b127409cdb0f0 Mon Sep 17 00:00:00 2001
|
||||
From: Lennart Poettering <lennart@poettering.net>
|
||||
Date: Wed, 20 Aug 2014 14:47:35 +0200
|
||||
Subject: [PATCH] resolved: fix which return codes we check
|
||||
|
||||
Discovered by Lukas Nykryn
|
||||
---
|
||||
src/resolve/resolved-dns-domain.c | 4 ++--
|
||||
1 file changed, 2 insertions(+), 2 deletions(-)
|
||||
|
||||
diff --git a/src/resolve/resolved-dns-domain.c b/src/resolve/resolved-dns-domain.c
|
||||
index 6152047ecb..8ed1ecf0a4 100644
|
||||
--- a/src/resolve/resolved-dns-domain.c
|
||||
+++ b/src/resolve/resolved-dns-domain.c
|
||||
@@ -434,8 +434,8 @@ int dns_name_endswith(const char *name, const char *suffix) {
|
||||
saved_n = n;
|
||||
|
||||
q = dns_label_unescape(&s, ls, sizeof(ls));
|
||||
- if (r < 0)
|
||||
- return r;
|
||||
+ if (q < 0)
|
||||
+ return q;
|
||||
w = dns_label_undo_idna(ls, q, ls, sizeof(ls));
|
||||
if (w < 0)
|
||||
return w;
|
21
0006-journal-remote-remove-unreachable-code.patch
Normal file
21
0006-journal-remote-remove-unreachable-code.patch
Normal file
@ -0,0 +1,21 @@
|
||||
From 7a855149eaf6dbd336d9defab5b4a9c70b75d5e6 Mon Sep 17 00:00:00 2001
|
||||
From: Lukas Nykryn <lnykryn@redhat.com>
|
||||
Date: Wed, 20 Aug 2014 14:51:27 +0200
|
||||
Subject: [PATCH] journal-remote: remove unreachable code
|
||||
|
||||
---
|
||||
src/journal-remote/journal-remote.c | 1 -
|
||||
1 file changed, 1 deletion(-)
|
||||
|
||||
diff --git a/src/journal-remote/journal-remote.c b/src/journal-remote/journal-remote.c
|
||||
index aa659d1bd4..7f422bfb37 100644
|
||||
--- a/src/journal-remote/journal-remote.c
|
||||
+++ b/src/journal-remote/journal-remote.c
|
||||
@@ -579,7 +579,6 @@ static int request_handler(
|
||||
log_error("MHD_get_connection_info failed: cannot get remote fd");
|
||||
return mhd_respond(connection, MHD_HTTP_INTERNAL_SERVER_ERROR,
|
||||
"Cannot check remote address");
|
||||
- return code;
|
||||
}
|
||||
|
||||
fd = ci->connect_fd;
|
27
0007-util-return-after-freeing-all-members-of-array.patch
Normal file
27
0007-util-return-after-freeing-all-members-of-array.patch
Normal file
@ -0,0 +1,27 @@
|
||||
From 081e009bef5a09c986bfabdf46e96810afaed1c3 Mon Sep 17 00:00:00 2001
|
||||
From: Lukas Nykryn <lnykryn@redhat.com>
|
||||
Date: Wed, 20 Aug 2014 15:02:09 +0200
|
||||
Subject: [PATCH] util: return after freeing all members of array
|
||||
|
||||
---
|
||||
src/shared/util.c | 6 +++---
|
||||
1 file changed, 3 insertions(+), 3 deletions(-)
|
||||
|
||||
diff --git a/src/shared/util.c b/src/shared/util.c
|
||||
index 85a570a2a4..9d254e0464 100644
|
||||
--- a/src/shared/util.c
|
||||
+++ b/src/shared/util.c
|
||||
@@ -7113,10 +7113,10 @@ int unquote_many_words(const char **p, ...) {
|
||||
if (r < 0) {
|
||||
int j;
|
||||
|
||||
- for (j = 0; j < c; j++) {
|
||||
+ for (j = 0; j < c; j++)
|
||||
free(l[j]);
|
||||
- return r;
|
||||
- }
|
||||
+
|
||||
+ return r;
|
||||
}
|
||||
|
||||
if (r == 0)
|
22
0008-journal-upload-make-sure-that-r-is-initialized.patch
Normal file
22
0008-journal-upload-make-sure-that-r-is-initialized.patch
Normal file
@ -0,0 +1,22 @@
|
||||
From e1ad6e245dcf63faa8f183063eb97678f4f9ac94 Mon Sep 17 00:00:00 2001
|
||||
From: Lukas Nykryn <lnykryn@redhat.com>
|
||||
Date: Wed, 20 Aug 2014 15:13:06 +0200
|
||||
Subject: [PATCH] journal-upload: make sure that 'r' is initialized
|
||||
|
||||
---
|
||||
src/journal-remote/journal-upload.c | 2 +-
|
||||
1 file changed, 1 insertion(+), 1 deletion(-)
|
||||
|
||||
diff --git a/src/journal-remote/journal-upload.c b/src/journal-remote/journal-upload.c
|
||||
index 7a7aee8170..bdeeff6778 100644
|
||||
--- a/src/journal-remote/journal-upload.c
|
||||
+++ b/src/journal-remote/journal-upload.c
|
||||
@@ -324,7 +324,7 @@ static int dispatch_fd_input(sd_event_source *event,
|
||||
}
|
||||
|
||||
static int open_file_for_upload(Uploader *u, const char *filename) {
|
||||
- int fd, r;
|
||||
+ int fd, r = 0;
|
||||
|
||||
if (streq(filename, "-"))
|
||||
fd = STDIN_FILENO;
|
@ -0,0 +1,26 @@
|
||||
From a9feff3d774eaa1cc1b59189e8f344c01e69f888 Mon Sep 17 00:00:00 2001
|
||||
From: Tom Gundersen <teg@jklm.no>
|
||||
Date: Wed, 20 Aug 2014 15:56:14 +0200
|
||||
Subject: [PATCH] resolved: write resolv.conf search - switch arguments
|
||||
MIME-Version: 1.0
|
||||
Content-Type: text/plain; charset=UTF-8
|
||||
Content-Transfer-Encoding: 8bit
|
||||
|
||||
Found by Lukáš Nykrýn.
|
||||
---
|
||||
src/resolve/resolved-manager.c | 2 +-
|
||||
1 file changed, 1 insertion(+), 1 deletion(-)
|
||||
|
||||
diff --git a/src/resolve/resolved-manager.c b/src/resolve/resolved-manager.c
|
||||
index 04ee204074..56baf8730d 100644
|
||||
--- a/src/resolve/resolved-manager.c
|
||||
+++ b/src/resolve/resolved-manager.c
|
||||
@@ -699,7 +699,7 @@ static void write_resolv_conf_server(DnsServer *s, FILE *f, unsigned *count) {
|
||||
}
|
||||
|
||||
static void write_resolv_conf_search(const char *domain, FILE *f,
|
||||
- unsigned *length, unsigned *count) {
|
||||
+ unsigned *count, unsigned *length) {
|
||||
assert(domain);
|
||||
assert(f);
|
||||
assert(length);
|
56
0010-sd-event-add-API-to-access-epoll_fd.patch
Normal file
56
0010-sd-event-add-API-to-access-epoll_fd.patch
Normal file
@ -0,0 +1,56 @@
|
||||
From 9b364545435d2b65fcf73519b3064bb7c28093b7 Mon Sep 17 00:00:00 2001
|
||||
From: Tom Gundersen <teg@jklm.no>
|
||||
Date: Fri, 15 Aug 2014 21:04:07 +0200
|
||||
Subject: [PATCH] sd-event: add API to access epoll_fd
|
||||
|
||||
This is a prerequisite for integrating sd-event into an external
|
||||
event loop.
|
||||
---
|
||||
src/libsystemd/libsystemd.sym.m4 | 1 +
|
||||
src/libsystemd/sd-event/sd-event.c | 8 ++++++++
|
||||
src/systemd/sd-event.h | 1 +
|
||||
3 files changed, 10 insertions(+)
|
||||
|
||||
diff --git a/src/libsystemd/libsystemd.sym.m4 b/src/libsystemd/libsystemd.sym.m4
|
||||
index 415d89afbe..3fc9983f98 100644
|
||||
--- a/src/libsystemd/libsystemd.sym.m4
|
||||
+++ b/src/libsystemd/libsystemd.sym.m4
|
||||
@@ -374,6 +374,7 @@ global:
|
||||
sd_event_loop;
|
||||
sd_event_exit;
|
||||
sd_event_now;
|
||||
+ sd_event_get_fd;
|
||||
sd_event_get_state;
|
||||
sd_event_get_tid;
|
||||
sd_event_get_exit_code;
|
||||
diff --git a/src/libsystemd/sd-event/sd-event.c b/src/libsystemd/sd-event/sd-event.c
|
||||
index 7917ab934a..e062997a80 100644
|
||||
--- a/src/libsystemd/sd-event/sd-event.c
|
||||
+++ b/src/libsystemd/sd-event/sd-event.c
|
||||
@@ -2361,6 +2361,14 @@ finish:
|
||||
return r;
|
||||
}
|
||||
|
||||
+_public_ int sd_event_get_fd(sd_event *e) {
|
||||
+
|
||||
+ assert_return(e, -EINVAL);
|
||||
+ assert_return(!event_pid_changed(e), -ECHILD);
|
||||
+
|
||||
+ return e->epoll_fd;
|
||||
+}
|
||||
+
|
||||
_public_ int sd_event_get_state(sd_event *e) {
|
||||
assert_return(e, -EINVAL);
|
||||
assert_return(!event_pid_changed(e), -ECHILD);
|
||||
diff --git a/src/systemd/sd-event.h b/src/systemd/sd-event.h
|
||||
index 5d9b3be6c7..d96852a763 100644
|
||||
--- a/src/systemd/sd-event.h
|
||||
+++ b/src/systemd/sd-event.h
|
||||
@@ -90,6 +90,7 @@ int sd_event_exit(sd_event *e, int code);
|
||||
|
||||
int sd_event_now(sd_event *e, clockid_t clock, uint64_t *usec);
|
||||
|
||||
+int sd_event_get_fd(sd_event *e);
|
||||
int sd_event_get_state(sd_event *e);
|
||||
int sd_event_get_tid(sd_event *e, pid_t *tid);
|
||||
int sd_event_get_exit_code(sd_event *e, int *code);
|
143
0011-journalctl-add-t-identifier-STRING-option.patch
Normal file
143
0011-journalctl-add-t-identifier-STRING-option.patch
Normal file
@ -0,0 +1,143 @@
|
||||
From 730836403aee5f5bb998e6e3622ea7068fce0699 Mon Sep 17 00:00:00 2001
|
||||
From: Harald Hoyer <harald@redhat.com>
|
||||
Date: Tue, 19 Aug 2014 11:27:34 +0200
|
||||
Subject: [PATCH] journalctl: add "-t --identifier=STRING" option
|
||||
|
||||
This turns journalctl to the counterpart of systemd-cat.
|
||||
Messages sent with
|
||||
|
||||
systemd-cat --identifier foo --prioritiy debug
|
||||
|
||||
can now be shown with
|
||||
|
||||
journalctl --identifier foo --prioritiy debug
|
||||
|
||||
"--identifier" is not merged with "--unit" to make a clear
|
||||
distinction between syslog and systemd units.
|
||||
syslog identifiers can be chosen freely by anyone.
|
||||
---
|
||||
man/journalctl.xml | 14 ++++++++++++++
|
||||
src/journal/journalctl.c | 43 ++++++++++++++++++++++++++++++++++++++++++-
|
||||
2 files changed, 56 insertions(+), 1 deletion(-)
|
||||
|
||||
diff --git a/man/journalctl.xml b/man/journalctl.xml
|
||||
index e10918a9c6..d4e031619a 100644
|
||||
--- a/man/journalctl.xml
|
||||
+++ b/man/journalctl.xml
|
||||
@@ -498,6 +498,20 @@
|
||||
</varlistentry>
|
||||
|
||||
<varlistentry>
|
||||
+ <term><option>-t</option></term>
|
||||
+ <term><option>--identifier=<replaceable>SYSLOG_IDENTIFIER</replaceable>|<replaceable>PATTERN</replaceable></option></term>
|
||||
+
|
||||
+ <listitem><para>Show messages for the
|
||||
+ specified syslog identifier
|
||||
+ <replaceable>SYSLOG_IDENTIFIER</replaceable>, or
|
||||
+ for any of the messages with a <literal>SYSLOG_IDENTIFIER</literal>
|
||||
+ matched by <replaceable>PATTERN</replaceable>.</para>
|
||||
+
|
||||
+ <para>This parameter can be specified
|
||||
+ multiple times.</para></listitem>
|
||||
+ </varlistentry>
|
||||
+
|
||||
+ <varlistentry>
|
||||
<term><option>-u</option></term>
|
||||
<term><option>--unit=<replaceable>UNIT</replaceable>|<replaceable>PATTERN</replaceable></option></term>
|
||||
|
||||
diff --git a/src/journal/journalctl.c b/src/journal/journalctl.c
|
||||
index 5c4a71d618..f3680d1ce2 100644
|
||||
--- a/src/journal/journalctl.c
|
||||
+++ b/src/journal/journalctl.c
|
||||
@@ -89,6 +89,7 @@ static bool arg_force = false;
|
||||
#endif
|
||||
static usec_t arg_since, arg_until;
|
||||
static bool arg_since_set = false, arg_until_set = false;
|
||||
+static char **arg_syslog_identifier = NULL;
|
||||
static char **arg_system_units = NULL;
|
||||
static char **arg_user_units = NULL;
|
||||
static const char *arg_field = NULL;
|
||||
@@ -180,6 +181,7 @@ static void help(void) {
|
||||
" -k --dmesg Show kernel message log from the current boot\n"
|
||||
" -u --unit=UNIT Show data only from the specified unit\n"
|
||||
" --user-unit=UNIT Show data only from the specified user session unit\n"
|
||||
+ " -t --identifier=STRING Show only messages with the specified syslog identifier\n"
|
||||
" -p --priority=RANGE Show only messages within the specified priority range\n"
|
||||
" -e --pager-end Immediately jump to end of the journal in the pager\n"
|
||||
" -f --follow Follow the journal\n"
|
||||
@@ -276,6 +278,7 @@ static int parse_argv(int argc, char *argv[]) {
|
||||
{ "file", required_argument, NULL, ARG_FILE },
|
||||
{ "root", required_argument, NULL, ARG_ROOT },
|
||||
{ "header", no_argument, NULL, ARG_HEADER },
|
||||
+ { "identifier", required_argument, NULL, 't' },
|
||||
{ "priority", required_argument, NULL, 'p' },
|
||||
{ "setup-keys", no_argument, NULL, ARG_SETUP_KEYS },
|
||||
{ "interval", required_argument, NULL, ARG_INTERVAL },
|
||||
@@ -304,7 +307,7 @@ static int parse_argv(int argc, char *argv[]) {
|
||||
assert(argc >= 0);
|
||||
assert(argv);
|
||||
|
||||
- while ((c = getopt_long(argc, argv, "hefo:aln::qmb::kD:p:c:u:F:xrM:", options, NULL)) >= 0)
|
||||
+ while ((c = getopt_long(argc, argv, "hefo:aln::qmb::kD:p:c:t:u:F:xrM:", options, NULL)) >= 0)
|
||||
|
||||
switch (c) {
|
||||
|
||||
@@ -590,6 +593,12 @@ static int parse_argv(int argc, char *argv[]) {
|
||||
arg_until_set = true;
|
||||
break;
|
||||
|
||||
+ case 't':
|
||||
+ r = strv_extend(&arg_syslog_identifier, optarg);
|
||||
+ if (r < 0)
|
||||
+ return log_oom();
|
||||
+ break;
|
||||
+
|
||||
case 'u':
|
||||
r = strv_extend(&arg_system_units, optarg);
|
||||
if (r < 0)
|
||||
@@ -1212,6 +1221,32 @@ static int add_priorities(sd_journal *j) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
+
|
||||
+static int add_syslog_identifier(sd_journal *j) {
|
||||
+ int r;
|
||||
+ char **i;
|
||||
+
|
||||
+ assert(j);
|
||||
+
|
||||
+ STRV_FOREACH(i, arg_syslog_identifier) {
|
||||
+ char *u;
|
||||
+
|
||||
+ u = strappenda("SYSLOG_IDENTIFIER=", *i);
|
||||
+ r = sd_journal_add_match(j, u, 0);
|
||||
+ if (r < 0)
|
||||
+ return r;
|
||||
+ r = sd_journal_add_disjunction(j);
|
||||
+ if (r < 0)
|
||||
+ return r;
|
||||
+ }
|
||||
+
|
||||
+ r = sd_journal_add_conjunction(j);
|
||||
+ if (r < 0)
|
||||
+ return r;
|
||||
+
|
||||
+ return 0;
|
||||
+}
|
||||
+
|
||||
static int setup_keys(void) {
|
||||
#ifdef HAVE_GCRYPT
|
||||
size_t mpk_size, seed_size, state_size, i;
|
||||
@@ -1705,6 +1740,12 @@ int main(int argc, char *argv[]) {
|
||||
return EXIT_FAILURE;
|
||||
}
|
||||
|
||||
+ r = add_syslog_identifier(j);
|
||||
+ if (r < 0) {
|
||||
+ log_error("Failed to add filter for syslog identifiers: %s", strerror(-r));
|
||||
+ return EXIT_FAILURE;
|
||||
+ }
|
||||
+
|
||||
r = add_priorities(j);
|
||||
if (r < 0) {
|
||||
log_error("Failed to add filter for priorities: %s", strerror(-r));
|
@ -0,0 +1,24 @@
|
||||
From 3fdbc8205885f117b7dea289b44217310663e731 Mon Sep 17 00:00:00 2001
|
||||
From: Lennart Poettering <lennart@poettering.net>
|
||||
Date: Thu, 21 Aug 2014 16:10:37 +0200
|
||||
Subject: [PATCH] CODING_STYLE: document that we don't break lines at 80ch
|
||||
|
||||
---
|
||||
CODING_STYLE | 5 ++++-
|
||||
1 file changed, 4 insertions(+), 1 deletion(-)
|
||||
|
||||
diff --git a/CODING_STYLE b/CODING_STYLE
|
||||
index ca3b5183f9..a3fc26c1e1 100644
|
||||
--- a/CODING_STYLE
|
||||
+++ b/CODING_STYLE
|
||||
@@ -1,6 +1,9 @@
|
||||
-
|
||||
- 8ch indent, no tabs
|
||||
|
||||
+- Don't break code lines too eagerly. We do *not* force line breaks at
|
||||
+ 80ch, all of today's screens should be much larger than that. But
|
||||
+ then again, don't overdo it, ~140ch should be enough really.
|
||||
+
|
||||
- Variables and functions *must* be static, unless they have a
|
||||
prototype, and are supposed to be exported.
|
||||
|
@ -0,0 +1,48 @@
|
||||
From 11adc1aef7a1a6e9ba3fda8eb34eb5fadedc0385 Mon Sep 17 00:00:00 2001
|
||||
From: Lennart Poettering <lennart@poettering.net>
|
||||
Date: Thu, 21 Aug 2014 16:10:59 +0200
|
||||
Subject: [PATCH] util: change return value of startswith() to non-const
|
||||
|
||||
This way we can use it on non-const strings, and don't end up with a
|
||||
const'ified result.
|
||||
|
||||
This is similar to libc's strstr() which also takes a const string but
|
||||
returns a non-const one.
|
||||
---
|
||||
src/shared/util.h | 20 ++++++++++++++------
|
||||
1 file changed, 14 insertions(+), 6 deletions(-)
|
||||
|
||||
diff --git a/src/shared/util.h b/src/shared/util.h
|
||||
index 87ad317319..8cd47b8294 100644
|
||||
--- a/src/shared/util.h
|
||||
+++ b/src/shared/util.h
|
||||
@@ -158,15 +158,23 @@ static inline bool isempty(const char *p) {
|
||||
return !p || !p[0];
|
||||
}
|
||||
|
||||
-static inline const char *startswith(const char *s, const char *prefix) {
|
||||
- if (strncmp(s, prefix, strlen(prefix)) == 0)
|
||||
- return s + strlen(prefix);
|
||||
+static inline char *startswith(const char *s, const char *prefix) {
|
||||
+ size_t l;
|
||||
+
|
||||
+ l = strlen(prefix);
|
||||
+ if (strncmp(s, prefix, l) == 0)
|
||||
+ return (char*) s + l;
|
||||
+
|
||||
return NULL;
|
||||
}
|
||||
|
||||
-static inline const char *startswith_no_case(const char *s, const char *prefix) {
|
||||
- if (strncasecmp(s, prefix, strlen(prefix)) == 0)
|
||||
- return s + strlen(prefix);
|
||||
+static inline char *startswith_no_case(const char *s, const char *prefix) {
|
||||
+ size_t l;
|
||||
+
|
||||
+ l = strlen(prefix);
|
||||
+ if (strncasecmp(s, prefix, l) == 0)
|
||||
+ return (char*) s + l;
|
||||
+
|
||||
return NULL;
|
||||
}
|
||||
|
55
0014-util-simplify-close_nointr-a-bit.patch
Normal file
55
0014-util-simplify-close_nointr-a-bit.patch
Normal file
@ -0,0 +1,55 @@
|
||||
From a9f85faf43ae2289e19ba9105c36496aefe66072 Mon Sep 17 00:00:00 2001
|
||||
From: Lennart Poettering <lennart@poettering.net>
|
||||
Date: Thu, 21 Aug 2014 16:13:15 +0200
|
||||
Subject: [PATCH] util: simplify close_nointr() a bit
|
||||
|
||||
---
|
||||
src/shared/util.c | 33 ++++++++++++++++-----------------
|
||||
1 file changed, 16 insertions(+), 17 deletions(-)
|
||||
|
||||
diff --git a/src/shared/util.c b/src/shared/util.c
|
||||
index 9d254e0464..a54e879953 100644
|
||||
--- a/src/shared/util.c
|
||||
+++ b/src/shared/util.c
|
||||
@@ -175,25 +175,24 @@ char* first_word(const char *s, const char *word) {
|
||||
}
|
||||
|
||||
int close_nointr(int fd) {
|
||||
- int r;
|
||||
-
|
||||
assert(fd >= 0);
|
||||
- r = close(fd);
|
||||
- if (r >= 0)
|
||||
- return r;
|
||||
- else if (errno == EINTR)
|
||||
- /*
|
||||
- * Just ignore EINTR; a retry loop is the wrong
|
||||
- * thing to do on Linux.
|
||||
- *
|
||||
- * http://lkml.indiana.edu/hypermail/linux/kernel/0509.1/0877.html
|
||||
- * https://bugzilla.gnome.org/show_bug.cgi?id=682819
|
||||
- * http://utcc.utoronto.ca/~cks/space/blog/unix/CloseEINTR
|
||||
- * https://sites.google.com/site/michaelsafyan/software-engineering/checkforeintrwheninvokingclosethinkagain
|
||||
- */
|
||||
+
|
||||
+ if (close(fd) >= 0)
|
||||
return 0;
|
||||
- else
|
||||
- return -errno;
|
||||
+
|
||||
+ /*
|
||||
+ * Just ignore EINTR; a retry loop is the wrong thing to do on
|
||||
+ * Linux.
|
||||
+ *
|
||||
+ * http://lkml.indiana.edu/hypermail/linux/kernel/0509.1/0877.html
|
||||
+ * https://bugzilla.gnome.org/show_bug.cgi?id=682819
|
||||
+ * http://utcc.utoronto.ca/~cks/space/blog/unix/CloseEINTR
|
||||
+ * https://sites.google.com/site/michaelsafyan/software-engineering/checkforeintrwheninvokingclosethinkagain
|
||||
+ */
|
||||
+ if (errno == EINTR)
|
||||
+ return 0;
|
||||
+
|
||||
+ return -errno;
|
||||
}
|
||||
|
||||
int safe_close(int fd) {
|
@ -0,0 +1,42 @@
|
||||
From 5ed1227238724959f020169f5332086439709b55 Mon Sep 17 00:00:00 2001
|
||||
From: Lennart Poettering <lennart@poettering.net>
|
||||
Date: Thu, 21 Aug 2014 16:13:43 +0200
|
||||
Subject: [PATCH] util: make asynchronous_close() really work like an
|
||||
asynchronous version of safe_close()
|
||||
|
||||
Save/restore errno, like we do in safe_close(). And don't fork a thread
|
||||
if the parameter is already negative.
|
||||
---
|
||||
src/shared/async.c | 12 ++++++++----
|
||||
1 file changed, 8 insertions(+), 4 deletions(-)
|
||||
|
||||
diff --git a/src/shared/async.c b/src/shared/async.c
|
||||
index 3876deda70..115901e637 100644
|
||||
--- a/src/shared/async.c
|
||||
+++ b/src/shared/async.c
|
||||
@@ -73,7 +73,7 @@ int asynchronous_sync(void) {
|
||||
}
|
||||
|
||||
static void *close_thread(void *p) {
|
||||
- safe_close(PTR_TO_INT(p));
|
||||
+ assert_se(close_nointr(PTR_TO_INT(p)) != -EBADF);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
@@ -86,9 +86,13 @@ int asynchronous_close(int fd) {
|
||||
* but it doesn't, so we work around it, and hide this as a
|
||||
* far away as we can. */
|
||||
|
||||
- r = asynchronous_job(close_thread, INT_TO_PTR(fd));
|
||||
- if (r < 0)
|
||||
- safe_close(fd);
|
||||
+ if (fd >= 0) {
|
||||
+ PROTECT_ERRNO;
|
||||
+
|
||||
+ r = asynchronous_job(close_thread, INT_TO_PTR(fd));
|
||||
+ if (r < 0)
|
||||
+ assert_se(close_nointr(fd) != -EBADF);
|
||||
+ }
|
||||
|
||||
return -1;
|
||||
}
|
127
0016-core-unify-how-we-generate-the-prefix-string-when-du.patch
Normal file
127
0016-core-unify-how-we-generate-the-prefix-string-when-du.patch
Normal file
@ -0,0 +1,127 @@
|
||||
From 4c94096027f21d4ed0efe991534a926d39d52369 Mon Sep 17 00:00:00 2001
|
||||
From: Lennart Poettering <lennart@poettering.net>
|
||||
Date: Thu, 21 Aug 2014 16:15:49 +0200
|
||||
Subject: [PATCH] core: unify how we generate the prefix string when dumping
|
||||
unit state
|
||||
|
||||
---
|
||||
src/core/execute.c | 19 ++++++-------------
|
||||
src/core/service.c | 6 ++----
|
||||
src/core/socket.c | 1 +
|
||||
src/core/unit.c | 7 ++-----
|
||||
4 files changed, 11 insertions(+), 22 deletions(-)
|
||||
|
||||
diff --git a/src/core/execute.c b/src/core/execute.c
|
||||
index d8452a666c..2544a2470c 100644
|
||||
--- a/src/core/execute.c
|
||||
+++ b/src/core/execute.c
|
||||
@@ -2398,12 +2398,11 @@ void exec_status_dump(ExecStatus *s, FILE *f, const char *prefix) {
|
||||
assert(s);
|
||||
assert(f);
|
||||
|
||||
- if (!prefix)
|
||||
- prefix = "";
|
||||
-
|
||||
if (s->pid <= 0)
|
||||
return;
|
||||
|
||||
+ prefix = strempty(prefix);
|
||||
+
|
||||
fprintf(f,
|
||||
"%sPID: "PID_FMT"\n",
|
||||
prefix, s->pid);
|
||||
@@ -2463,21 +2462,16 @@ char *exec_command_line(char **argv) {
|
||||
}
|
||||
|
||||
void exec_command_dump(ExecCommand *c, FILE *f, const char *prefix) {
|
||||
- _cleanup_free_ char *p2 = NULL;
|
||||
- const char *prefix2;
|
||||
-
|
||||
_cleanup_free_ char *cmd = NULL;
|
||||
+ const char *prefix2;
|
||||
|
||||
assert(c);
|
||||
assert(f);
|
||||
|
||||
- if (!prefix)
|
||||
- prefix = "";
|
||||
- p2 = strappend(prefix, "\t");
|
||||
- prefix2 = p2 ? p2 : prefix;
|
||||
+ prefix = strempty(prefix);
|
||||
+ prefix2 = strappenda(prefix, "\t");
|
||||
|
||||
cmd = exec_command_line(c->argv);
|
||||
-
|
||||
fprintf(f,
|
||||
"%sCommand Line: %s\n",
|
||||
prefix, cmd ? cmd : strerror(ENOMEM));
|
||||
@@ -2488,8 +2482,7 @@ void exec_command_dump(ExecCommand *c, FILE *f, const char *prefix) {
|
||||
void exec_command_dump_list(ExecCommand *c, FILE *f, const char *prefix) {
|
||||
assert(f);
|
||||
|
||||
- if (!prefix)
|
||||
- prefix = "";
|
||||
+ prefix = strempty(prefix);
|
||||
|
||||
LIST_FOREACH(command, c, c)
|
||||
exec_command_dump(c, f, prefix);
|
||||
diff --git a/src/core/service.c b/src/core/service.c
|
||||
index 6a4665a1ae..887b1c8514 100644
|
||||
--- a/src/core/service.c
|
||||
+++ b/src/core/service.c
|
||||
@@ -463,16 +463,14 @@ static int service_load(Unit *u) {
|
||||
}
|
||||
|
||||
static void service_dump(Unit *u, FILE *f, const char *prefix) {
|
||||
-
|
||||
ServiceExecCommand c;
|
||||
Service *s = SERVICE(u);
|
||||
const char *prefix2;
|
||||
- _cleanup_free_ char *p2 = NULL;
|
||||
|
||||
assert(s);
|
||||
|
||||
- p2 = strappend(prefix, "\t");
|
||||
- prefix2 = p2 ? p2 : prefix;
|
||||
+ prefix = strempty(prefix);
|
||||
+ prefix2 = strappenda(prefix, "\t");
|
||||
|
||||
fprintf(f,
|
||||
"%sService State: %s\n"
|
||||
diff --git a/src/core/socket.c b/src/core/socket.c
|
||||
index 1189f451d2..7ca8edbda8 100644
|
||||
--- a/src/core/socket.c
|
||||
+++ b/src/core/socket.c
|
||||
@@ -471,6 +471,7 @@ static void socket_dump(Unit *u, FILE *f, const char *prefix) {
|
||||
assert(s);
|
||||
assert(f);
|
||||
|
||||
+ prefix = strempty(prefix);
|
||||
prefix2 = strappenda(prefix, "\t");
|
||||
|
||||
fprintf(f,
|
||||
diff --git a/src/core/unit.c b/src/core/unit.c
|
||||
index 08e74b4160..56102b360d 100644
|
||||
--- a/src/core/unit.c
|
||||
+++ b/src/core/unit.c
|
||||
@@ -791,7 +791,6 @@ void unit_dump(Unit *u, FILE *f, const char *prefix) {
|
||||
char *t, **j;
|
||||
UnitDependency d;
|
||||
Iterator i;
|
||||
- _cleanup_free_ char *p2 = NULL;
|
||||
const char *prefix2;
|
||||
char
|
||||
timestamp1[FORMAT_TIMESTAMP_MAX],
|
||||
@@ -806,10 +805,8 @@ void unit_dump(Unit *u, FILE *f, const char *prefix) {
|
||||
assert(u);
|
||||
assert(u->type >= 0);
|
||||
|
||||
- if (!prefix)
|
||||
- prefix = "";
|
||||
- p2 = strappend(prefix, "\t");
|
||||
- prefix2 = p2 ? p2 : prefix;
|
||||
+ prefix = strempty(prefix);
|
||||
+ prefix2 = strappenda(prefix, "\t");
|
||||
|
||||
fprintf(f,
|
||||
"%s-> Unit %s:\n"
|
@ -0,0 +1,24 @@
|
||||
From abb4c1cc0161cc6b371ee7ea2550df17a3bfc21e Mon Sep 17 00:00:00 2001
|
||||
From: Lennart Poettering <lennart@poettering.net>
|
||||
Date: Thu, 21 Aug 2014 16:17:02 +0200
|
||||
Subject: [PATCH] service: asynchronous_close() already checks for negative
|
||||
parameters, no need to duplicate that
|
||||
|
||||
---
|
||||
src/core/service.c | 3 ---
|
||||
1 file changed, 3 deletions(-)
|
||||
|
||||
diff --git a/src/core/service.c b/src/core/service.c
|
||||
index 887b1c8514..008e81437d 100644
|
||||
--- a/src/core/service.c
|
||||
+++ b/src/core/service.c
|
||||
@@ -180,9 +180,6 @@ static int service_set_main_pid(Service *s, pid_t pid) {
|
||||
static void service_close_socket_fd(Service *s) {
|
||||
assert(s);
|
||||
|
||||
- if (s->socket_fd < 0)
|
||||
- return;
|
||||
-
|
||||
s->socket_fd = asynchronous_close(s->socket_fd);
|
||||
}
|
||||
|
526
0018-service-remove-some-pointless-linebreaks-to-make-thi.patch
Normal file
526
0018-service-remove-some-pointless-linebreaks-to-make-thi.patch
Normal file
@ -0,0 +1,526 @@
|
||||
From 8bb2d17d2b89e87b2e9d8f6c147a757f4670b0fc Mon Sep 17 00:00:00 2001
|
||||
From: Lennart Poettering <lennart@poettering.net>
|
||||
Date: Thu, 21 Aug 2014 16:19:25 +0200
|
||||
Subject: [PATCH] service: remove some pointless linebreaks, to make things
|
||||
more readable
|
||||
|
||||
---
|
||||
src/core/service.c | 200 +++++++++++++++++------------------------------------
|
||||
1 file changed, 65 insertions(+), 135 deletions(-)
|
||||
|
||||
diff --git a/src/core/service.c b/src/core/service.c
|
||||
index 008e81437d..f10582d89e 100644
|
||||
--- a/src/core/service.c
|
||||
+++ b/src/core/service.c
|
||||
@@ -135,8 +135,7 @@ static void service_unwatch_pid_file(Service *s) {
|
||||
if (!s->pid_file_pathspec)
|
||||
return;
|
||||
|
||||
- log_debug_unit(UNIT(s)->id, "Stopping watch for %s's PID file %s",
|
||||
- UNIT(s)->id, s->pid_file_pathspec->path);
|
||||
+ log_debug_unit(UNIT(s)->id, "Stopping watch for %s's PID file %s", UNIT(s)->id, s->pid_file_pathspec->path);
|
||||
path_spec_unwatch(s->pid_file_pathspec);
|
||||
path_spec_done(s->pid_file_pathspec);
|
||||
free(s->pid_file_pathspec);
|
||||
@@ -166,10 +165,7 @@ static int service_set_main_pid(Service *s, pid_t pid) {
|
||||
s->main_pid_known = true;
|
||||
|
||||
if (get_parent_of_pid(pid, &ppid) >= 0 && ppid != getpid()) {
|
||||
- log_warning_unit(UNIT(s)->id,
|
||||
- "%s: Supervising process "PID_FMT" which is not our child. We'll most likely not notice when it exits.",
|
||||
- UNIT(s)->id, pid);
|
||||
-
|
||||
+ log_warning_unit(UNIT(s)->id, "%s: Supervising process "PID_FMT" which is not our child. We'll most likely not notice when it exits.", UNIT(s)->id, pid);
|
||||
s->main_pid_alien = true;
|
||||
} else
|
||||
s->main_pid_alien = false;
|
||||
@@ -362,14 +358,12 @@ static int service_add_default_dependencies(Service *s) {
|
||||
* majority of services. */
|
||||
|
||||
/* First, pull in base system */
|
||||
- r = unit_add_two_dependencies_by_name(UNIT(s), UNIT_AFTER, UNIT_REQUIRES,
|
||||
- SPECIAL_BASIC_TARGET, NULL, true);
|
||||
+ r = unit_add_two_dependencies_by_name(UNIT(s), UNIT_AFTER, UNIT_REQUIRES, SPECIAL_BASIC_TARGET, NULL, true);
|
||||
if (r < 0)
|
||||
return r;
|
||||
|
||||
/* Second, activate normal shutdown */
|
||||
- r = unit_add_two_dependencies_by_name(UNIT(s), UNIT_BEFORE, UNIT_CONFLICTS,
|
||||
- SPECIAL_SHUTDOWN_TARGET, NULL, true);
|
||||
+ r = unit_add_two_dependencies_by_name(UNIT(s), UNIT_BEFORE, UNIT_CONFLICTS, SPECIAL_SHUTDOWN_TARGET, NULL, true);
|
||||
return r;
|
||||
}
|
||||
|
||||
@@ -392,8 +386,8 @@ static void service_fix_output(Service *s) {
|
||||
}
|
||||
|
||||
static int service_load(Unit *u) {
|
||||
- int r;
|
||||
Service *s = SERVICE(u);
|
||||
+ int r;
|
||||
|
||||
assert(s);
|
||||
|
||||
@@ -556,25 +550,20 @@ static int service_load_pid_file(Service *s, bool may_warn) {
|
||||
r = read_one_line_file(s->pid_file, &k);
|
||||
if (r < 0) {
|
||||
if (may_warn)
|
||||
- log_info_unit(UNIT(s)->id,
|
||||
- "PID file %s not readable (yet?) after %s.",
|
||||
- s->pid_file, service_state_to_string(s->state));
|
||||
+ log_info_unit(UNIT(s)->id, "PID file %s not readable (yet?) after %s.", s->pid_file, service_state_to_string(s->state));
|
||||
return r;
|
||||
}
|
||||
|
||||
r = parse_pid(k, &pid);
|
||||
if (r < 0) {
|
||||
if (may_warn)
|
||||
- log_info_unit(UNIT(s)->id,
|
||||
- "Failed to read PID from file %s: %s",
|
||||
- s->pid_file, strerror(-r));
|
||||
+ log_info_unit(UNIT(s)->id, "Failed to read PID from file %s: %s", s->pid_file, strerror(-r));
|
||||
return r;
|
||||
}
|
||||
|
||||
if (!pid_is_alive(pid)) {
|
||||
if (may_warn)
|
||||
log_info_unit(UNIT(s)->id, "PID "PID_FMT" read from file %s does not exist or is a zombie.", pid, s->pid_file);
|
||||
-
|
||||
return -ESRCH;
|
||||
}
|
||||
|
||||
@@ -582,14 +571,12 @@ static int service_load_pid_file(Service *s, bool may_warn) {
|
||||
if (pid == s->main_pid)
|
||||
return 0;
|
||||
|
||||
- log_debug_unit(UNIT(s)->id,
|
||||
- "Main PID changing: "PID_FMT" -> "PID_FMT,
|
||||
- s->main_pid, pid);
|
||||
+ log_debug_unit(UNIT(s)->id, "Main PID changing: "PID_FMT" -> "PID_FMT, s->main_pid, pid);
|
||||
+
|
||||
service_unwatch_main_pid(s);
|
||||
s->main_pid_known = false;
|
||||
} else
|
||||
- log_debug_unit(UNIT(s)->id,
|
||||
- "Main PID loaded: "PID_FMT, pid);
|
||||
+ log_debug_unit(UNIT(s)->id, "Main PID loaded: "PID_FMT, pid);
|
||||
|
||||
r = service_set_main_pid(s, pid);
|
||||
if (r < 0)
|
||||
@@ -598,9 +585,7 @@ static int service_load_pid_file(Service *s, bool may_warn) {
|
||||
r = unit_watch_pid(UNIT(s), pid);
|
||||
if (r < 0) {
|
||||
/* FIXME: we need to do something here */
|
||||
- log_warning_unit(UNIT(s)->id,
|
||||
- "Failed to watch PID "PID_FMT" from service %s",
|
||||
- pid, UNIT(s)->id);
|
||||
+ log_warning_unit(UNIT(s)->id, "Failed to watch PID "PID_FMT" from service %s", pid, UNIT(s)->id);
|
||||
return r;
|
||||
}
|
||||
|
||||
@@ -627,19 +612,19 @@ static int service_search_main_pid(Service *s) {
|
||||
if (pid <= 0)
|
||||
return -ENOENT;
|
||||
|
||||
- log_debug_unit(UNIT(s)->id,
|
||||
- "Main PID guessed: "PID_FMT, pid);
|
||||
+ log_debug_unit(UNIT(s)->id, "Main PID guessed: "PID_FMT, pid);
|
||||
r = service_set_main_pid(s, pid);
|
||||
if (r < 0)
|
||||
return r;
|
||||
|
||||
r = unit_watch_pid(UNIT(s), pid);
|
||||
- if (r < 0)
|
||||
+ if (r < 0) {
|
||||
/* FIXME: we need to do something here */
|
||||
- log_warning_unit(UNIT(s)->id,
|
||||
- "Failed to watch PID "PID_FMT" from service %s",
|
||||
- pid, UNIT(s)->id);
|
||||
- return r;
|
||||
+ log_warning_unit(UNIT(s)->id, "Failed to watch PID "PID_FMT" from service %s", pid, UNIT(s)->id);
|
||||
+ return r;
|
||||
+ }
|
||||
+
|
||||
+ return 0;
|
||||
}
|
||||
|
||||
static void service_set_state(Service *s, ServiceState state) {
|
||||
@@ -1096,9 +1081,7 @@ static void service_enter_dead(Service *s, ServiceResult f, bool allow_restart)
|
||||
return;
|
||||
|
||||
fail:
|
||||
- log_warning_unit(UNIT(s)->id,
|
||||
- "%s failed to run install restart timer: %s",
|
||||
- UNIT(s)->id, strerror(-r));
|
||||
+ log_warning_unit(UNIT(s)->id, "%s failed to run install restart timer: %s", UNIT(s)->id, strerror(-r));
|
||||
service_enter_dead(s, SERVICE_FAILURE_RESOURCES, false);
|
||||
}
|
||||
|
||||
@@ -1136,9 +1119,7 @@ static void service_enter_stop_post(Service *s, ServiceResult f) {
|
||||
return;
|
||||
|
||||
fail:
|
||||
- log_warning_unit(UNIT(s)->id,
|
||||
- "%s failed to run 'stop-post' task: %s",
|
||||
- UNIT(s)->id, strerror(-r));
|
||||
+ log_warning_unit(UNIT(s)->id, "%s failed to run 'stop-post' task: %s", UNIT(s)->id, strerror(-r));
|
||||
service_enter_signal(s, SERVICE_FINAL_SIGTERM, SERVICE_FAILURE_RESOURCES);
|
||||
}
|
||||
|
||||
@@ -1183,8 +1164,7 @@ static void service_enter_signal(Service *s, ServiceState state, ServiceResult f
|
||||
return;
|
||||
|
||||
fail:
|
||||
- log_warning_unit(UNIT(s)->id,
|
||||
- "%s failed to kill processes: %s", UNIT(s)->id, strerror(-r));
|
||||
+ log_warning_unit(UNIT(s)->id, "%s failed to kill processes: %s", UNIT(s)->id, strerror(-r));
|
||||
|
||||
if (state == SERVICE_STOP_SIGTERM || state == SERVICE_STOP_SIGKILL)
|
||||
service_enter_stop_post(s, SERVICE_FAILURE_RESOURCES);
|
||||
@@ -1227,8 +1207,7 @@ static void service_enter_stop(Service *s, ServiceResult f) {
|
||||
return;
|
||||
|
||||
fail:
|
||||
- log_warning_unit(UNIT(s)->id,
|
||||
- "%s failed to run 'stop' task: %s", UNIT(s)->id, strerror(-r));
|
||||
+ log_warning_unit(UNIT(s)->id, "%s failed to run 'stop' task: %s", UNIT(s)->id, strerror(-r));
|
||||
service_enter_signal(s, SERVICE_STOP_SIGTERM, SERVICE_FAILURE_RESOURCES);
|
||||
}
|
||||
|
||||
@@ -1282,8 +1261,7 @@ static void service_enter_start_post(Service *s) {
|
||||
return;
|
||||
|
||||
fail:
|
||||
- log_warning_unit(UNIT(s)->id,
|
||||
- "%s failed to run 'start-post' task: %s", UNIT(s)->id, strerror(-r));
|
||||
+ log_warning_unit(UNIT(s)->id, "%s failed to run 'start-post' task: %s", UNIT(s)->id, strerror(-r));
|
||||
service_enter_stop(s, SERVICE_FAILURE_RESOURCES);
|
||||
}
|
||||
|
||||
@@ -1375,8 +1353,7 @@ static void service_enter_start(Service *s) {
|
||||
return;
|
||||
|
||||
fail:
|
||||
- log_warning_unit(UNIT(s)->id,
|
||||
- "%s failed to run 'start' task: %s", UNIT(s)->id, strerror(-r));
|
||||
+ log_warning_unit(UNIT(s)->id, "%s failed to run 'start' task: %s", UNIT(s)->id, strerror(-r));
|
||||
service_enter_signal(s, SERVICE_FINAL_SIGTERM, SERVICE_FAILURE_RESOURCES);
|
||||
}
|
||||
|
||||
@@ -1489,9 +1466,7 @@ static void service_enter_reload(Service *s) {
|
||||
return;
|
||||
|
||||
fail:
|
||||
- log_warning_unit(UNIT(s)->id,
|
||||
- "%s failed to run 'reload' task: %s",
|
||||
- UNIT(s)->id, strerror(-r));
|
||||
+ log_warning_unit(UNIT(s)->id, "%s failed to run 'reload' task: %s", UNIT(s)->id, strerror(-r));
|
||||
s->reload_result = SERVICE_FAILURE_RESOURCES;
|
||||
service_enter_running(s, SERVICE_SUCCESS);
|
||||
}
|
||||
@@ -1525,9 +1500,7 @@ static void service_run_next_control(Service *s) {
|
||||
return;
|
||||
|
||||
fail:
|
||||
- log_warning_unit(UNIT(s)->id,
|
||||
- "%s failed to run next control task: %s",
|
||||
- UNIT(s)->id, strerror(-r));
|
||||
+ log_warning_unit(UNIT(s)->id, "%s failed to run next control task: %s", UNIT(s)->id, strerror(-r));
|
||||
|
||||
if (s->state == SERVICE_START_PRE)
|
||||
service_enter_signal(s, SERVICE_FINAL_SIGTERM, SERVICE_FAILURE_RESOURCES);
|
||||
@@ -1572,8 +1545,7 @@ static void service_run_next_main(Service *s) {
|
||||
return;
|
||||
|
||||
fail:
|
||||
- log_warning_unit(UNIT(s)->id,
|
||||
- "%s failed to run next main task: %s", UNIT(s)->id, strerror(-r));
|
||||
+ log_warning_unit(UNIT(s)->id, "%s failed to run next main task: %s", UNIT(s)->id, strerror(-r));
|
||||
service_enter_stop(s, SERVICE_FAILURE_RESOURCES);
|
||||
}
|
||||
|
||||
@@ -1588,41 +1560,35 @@ static int service_execute_action(Service *s, FailureAction action, const char *
|
||||
|
||||
case SERVICE_FAILURE_ACTION_NONE:
|
||||
if (log_action_none)
|
||||
- log_warning_unit(UNIT(s)->id,
|
||||
- "%s %s, refusing to start.", UNIT(s)->id, reason);
|
||||
+ log_warning_unit(UNIT(s)->id, "%s %s, refusing to start.", UNIT(s)->id, reason);
|
||||
break;
|
||||
|
||||
case SERVICE_FAILURE_ACTION_REBOOT: {
|
||||
_cleanup_bus_error_free_ sd_bus_error error = SD_BUS_ERROR_NULL;
|
||||
int r;
|
||||
|
||||
- log_warning_unit(UNIT(s)->id,
|
||||
- "%s %s, rebooting.", UNIT(s)->id, reason);
|
||||
+ log_warning_unit(UNIT(s)->id, "%s %s, rebooting.", UNIT(s)->id, reason);
|
||||
|
||||
- r = manager_add_job_by_name(UNIT(s)->manager, JOB_START,
|
||||
- SPECIAL_REBOOT_TARGET, JOB_REPLACE,
|
||||
- true, &error, NULL);
|
||||
+ r = manager_add_job_by_name(UNIT(s)->manager, JOB_START, SPECIAL_REBOOT_TARGET, JOB_REPLACE, true, &error, NULL);
|
||||
if (r < 0)
|
||||
- log_error_unit(UNIT(s)->id,
|
||||
- "Failed to reboot: %s.", bus_error_message(&error, r));
|
||||
+ log_error_unit(UNIT(s)->id, "Failed to reboot: %s.", bus_error_message(&error, r));
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
case SERVICE_FAILURE_ACTION_REBOOT_FORCE:
|
||||
- log_warning_unit(UNIT(s)->id,
|
||||
- "%s %s, forcibly rebooting.", UNIT(s)->id, reason);
|
||||
+ log_warning_unit(UNIT(s)->id, "%s %s, forcibly rebooting.", UNIT(s)->id, reason);
|
||||
UNIT(s)->manager->exit_code = MANAGER_REBOOT;
|
||||
break;
|
||||
|
||||
case SERVICE_FAILURE_ACTION_REBOOT_IMMEDIATE:
|
||||
- log_warning_unit(UNIT(s)->id,
|
||||
- "%s %s, rebooting immediately.", UNIT(s)->id, reason);
|
||||
+ log_warning_unit(UNIT(s)->id, "%s %s, rebooting immediately.", UNIT(s)->id, reason);
|
||||
+
|
||||
sync();
|
||||
+
|
||||
if (s->reboot_arg) {
|
||||
log_info("Rebooting with argument '%s'.", s->reboot_arg);
|
||||
- syscall(SYS_reboot, LINUX_REBOOT_MAGIC1, LINUX_REBOOT_MAGIC2,
|
||||
- LINUX_REBOOT_CMD_RESTART2, s->reboot_arg);
|
||||
+ syscall(SYS_reboot, LINUX_REBOOT_MAGIC1, LINUX_REBOOT_MAGIC2, LINUX_REBOOT_CMD_RESTART2, s->reboot_arg);
|
||||
}
|
||||
|
||||
log_info("Rebooting.");
|
||||
@@ -1630,8 +1596,7 @@ static int service_execute_action(Service *s, FailureAction action, const char *
|
||||
break;
|
||||
|
||||
default:
|
||||
- log_error_unit(UNIT(s)->id,
|
||||
- "failure action=%i", action);
|
||||
+ log_error_unit(UNIT(s)->id, "failure action=%i", action);
|
||||
assert_not_reached("Unknown FailureAction.");
|
||||
}
|
||||
|
||||
@@ -1990,7 +1955,7 @@ _pure_ static bool service_check_snapshot(Unit *u) {
|
||||
|
||||
assert(s);
|
||||
|
||||
- return (s->socket_fd < 0);
|
||||
+ return s->socket_fd < 0;
|
||||
}
|
||||
|
||||
static int service_retry_pid_file(Service *s) {
|
||||
@@ -2012,24 +1977,19 @@ static int service_retry_pid_file(Service *s) {
|
||||
static int service_watch_pid_file(Service *s) {
|
||||
int r;
|
||||
|
||||
- log_debug_unit(UNIT(s)->id,
|
||||
- "Setting watch for %s's PID file %s",
|
||||
- UNIT(s)->id, s->pid_file_pathspec->path);
|
||||
+ log_debug_unit(UNIT(s)->id, "Setting watch for %s's PID file %s", UNIT(s)->id, s->pid_file_pathspec->path);
|
||||
+
|
||||
r = path_spec_watch(s->pid_file_pathspec, service_dispatch_io);
|
||||
if (r < 0)
|
||||
goto fail;
|
||||
|
||||
/* the pidfile might have appeared just before we set the watch */
|
||||
- log_debug_unit(UNIT(s)->id,
|
||||
- "Trying to read %s's PID file %s in case it changed",
|
||||
- UNIT(s)->id, s->pid_file_pathspec->path);
|
||||
+ log_debug_unit(UNIT(s)->id, "Trying to read %s's PID file %s in case it changed", UNIT(s)->id, s->pid_file_pathspec->path);
|
||||
service_retry_pid_file(s);
|
||||
|
||||
return 0;
|
||||
fail:
|
||||
- log_error_unit(UNIT(s)->id,
|
||||
- "Failed to set a watch for %s's PID file %s: %s",
|
||||
- UNIT(s)->id, s->pid_file_pathspec->path, strerror(-r));
|
||||
+ log_error_unit(UNIT(s)->id, "Failed to set a watch for %s's PID file %s: %s", UNIT(s)->id, s->pid_file_pathspec->path, strerror(-r));
|
||||
service_unwatch_pid_file(s);
|
||||
return r;
|
||||
}
|
||||
@@ -2116,8 +2076,8 @@ static void service_notify_cgroup_empty_event(Unit *u) {
|
||||
/* If we were hoping for the daemon to write its PID file,
|
||||
* we can give up now. */
|
||||
if (s->pid_file_pathspec) {
|
||||
- log_warning_unit(u->id,
|
||||
- "%s never wrote its PID file. Failing.", UNIT(s)->id);
|
||||
+ log_warning_unit(u->id, "%s never wrote its PID file. Failing.", UNIT(s)->id);
|
||||
+
|
||||
service_unwatch_pid_file(s);
|
||||
if (s->state == SERVICE_START)
|
||||
service_enter_signal(s, SERVICE_FINAL_SIGTERM, SERVICE_FAILURE_RESOURCES);
|
||||
@@ -2223,9 +2183,7 @@ static void service_sigchld_event(Unit *u, pid_t pid, int code, int status) {
|
||||
/* There is another command to *
|
||||
* execute, so let's do that. */
|
||||
|
||||
- log_debug_unit(u->id,
|
||||
- "%s running next main command for state %s",
|
||||
- u->id, service_state_to_string(s->state));
|
||||
+ log_debug_unit(u->id, "%s running next main command for state %s", u->id, service_state_to_string(s->state));
|
||||
service_run_next_main(s);
|
||||
|
||||
} else {
|
||||
@@ -2285,8 +2243,7 @@ static void service_sigchld_event(Unit *u, pid_t pid, int code, int status) {
|
||||
s->control_pid = 0;
|
||||
|
||||
if (s->control_command) {
|
||||
- exec_status_exit(&s->control_command->exec_status,
|
||||
- &s->exec_context, pid, code, status);
|
||||
+ exec_status_exit(&s->control_command->exec_status, &s->exec_context, pid, code, status);
|
||||
|
||||
if (s->control_command->ignore)
|
||||
f = SERVICE_SUCCESS;
|
||||
@@ -2311,9 +2268,7 @@ static void service_sigchld_event(Unit *u, pid_t pid, int code, int status) {
|
||||
/* There is another command to *
|
||||
* execute, so let's do that. */
|
||||
|
||||
- log_debug_unit(u->id,
|
||||
- "%s running next control command for state %s",
|
||||
- u->id, service_state_to_string(s->state));
|
||||
+ log_debug_unit(u->id, "%s running next control command for state %s", u->id, service_state_to_string(s->state));
|
||||
service_run_next_control(s);
|
||||
|
||||
} else {
|
||||
@@ -2323,9 +2278,7 @@ static void service_sigchld_event(Unit *u, pid_t pid, int code, int status) {
|
||||
s->control_command = NULL;
|
||||
s->control_command_id = _SERVICE_EXEC_COMMAND_INVALID;
|
||||
|
||||
- log_debug_unit(u->id,
|
||||
- "%s got final SIGCHLD for state %s",
|
||||
- u->id, service_state_to_string(s->state));
|
||||
+ log_debug_unit(u->id, "%s got final SIGCHLD for state %s", u->id, service_state_to_string(s->state));
|
||||
|
||||
switch (s->state) {
|
||||
|
||||
@@ -2453,40 +2406,32 @@ static int service_dispatch_timer(sd_event_source *source, usec_t usec, void *us
|
||||
|
||||
case SERVICE_START_PRE:
|
||||
case SERVICE_START:
|
||||
- log_warning_unit(UNIT(s)->id,
|
||||
- "%s %s operation timed out. Terminating.",
|
||||
- UNIT(s)->id,
|
||||
- s->state == SERVICE_START ? "start" : "start-pre");
|
||||
+ log_warning_unit(UNIT(s)->id, "%s %s operation timed out. Terminating.", UNIT(s)->id, s->state == SERVICE_START ? "start" : "start-pre");
|
||||
service_enter_signal(s, SERVICE_FINAL_SIGTERM, SERVICE_FAILURE_TIMEOUT);
|
||||
break;
|
||||
|
||||
case SERVICE_START_POST:
|
||||
- log_warning_unit(UNIT(s)->id,
|
||||
- "%s start-post operation timed out. Stopping.", UNIT(s)->id);
|
||||
+ log_warning_unit(UNIT(s)->id, "%s start-post operation timed out. Stopping.", UNIT(s)->id);
|
||||
service_enter_stop(s, SERVICE_FAILURE_TIMEOUT);
|
||||
break;
|
||||
|
||||
case SERVICE_RELOAD:
|
||||
- log_warning_unit(UNIT(s)->id,
|
||||
- "%s reload operation timed out. Stopping.", UNIT(s)->id);
|
||||
+ log_warning_unit(UNIT(s)->id, "%s reload operation timed out. Stopping.", UNIT(s)->id);
|
||||
s->reload_result = SERVICE_FAILURE_TIMEOUT;
|
||||
service_enter_running(s, SERVICE_SUCCESS);
|
||||
break;
|
||||
|
||||
case SERVICE_STOP:
|
||||
- log_warning_unit(UNIT(s)->id,
|
||||
- "%s stopping timed out. Terminating.", UNIT(s)->id);
|
||||
+ log_warning_unit(UNIT(s)->id, "%s stopping timed out. Terminating.", UNIT(s)->id);
|
||||
service_enter_signal(s, SERVICE_STOP_SIGTERM, SERVICE_FAILURE_TIMEOUT);
|
||||
break;
|
||||
|
||||
case SERVICE_STOP_SIGTERM:
|
||||
if (s->kill_context.send_sigkill) {
|
||||
- log_warning_unit(UNIT(s)->id,
|
||||
- "%s stop-sigterm timed out. Killing.", UNIT(s)->id);
|
||||
+ log_warning_unit(UNIT(s)->id, "%s stop-sigterm timed out. Killing.", UNIT(s)->id);
|
||||
service_enter_signal(s, SERVICE_STOP_SIGKILL, SERVICE_FAILURE_TIMEOUT);
|
||||
} else {
|
||||
- log_warning_unit(UNIT(s)->id,
|
||||
- "%s stop-sigterm timed out. Skipping SIGKILL.", UNIT(s)->id);
|
||||
+ log_warning_unit(UNIT(s)->id, "%s stop-sigterm timed out. Skipping SIGKILL.", UNIT(s)->id);
|
||||
service_enter_stop_post(s, SERVICE_FAILURE_TIMEOUT);
|
||||
}
|
||||
|
||||
@@ -2497,34 +2442,28 @@ static int service_dispatch_timer(sd_event_source *source, usec_t usec, void *us
|
||||
* Must be something we cannot kill, so let's just be
|
||||
* weirded out and continue */
|
||||
|
||||
- log_warning_unit(UNIT(s)->id,
|
||||
- "%s still around after SIGKILL. Ignoring.", UNIT(s)->id);
|
||||
+ log_warning_unit(UNIT(s)->id, "%s still around after SIGKILL. Ignoring.", UNIT(s)->id);
|
||||
service_enter_stop_post(s, SERVICE_FAILURE_TIMEOUT);
|
||||
break;
|
||||
|
||||
case SERVICE_STOP_POST:
|
||||
- log_warning_unit(UNIT(s)->id,
|
||||
- "%s stop-post timed out. Terminating.", UNIT(s)->id);
|
||||
+ log_warning_unit(UNIT(s)->id, "%s stop-post timed out. Terminating.", UNIT(s)->id);
|
||||
service_enter_signal(s, SERVICE_FINAL_SIGTERM, SERVICE_FAILURE_TIMEOUT);
|
||||
break;
|
||||
|
||||
case SERVICE_FINAL_SIGTERM:
|
||||
if (s->kill_context.send_sigkill) {
|
||||
- log_warning_unit(UNIT(s)->id,
|
||||
- "%s stop-final-sigterm timed out. Killing.", UNIT(s)->id);
|
||||
+ log_warning_unit(UNIT(s)->id, "%s stop-final-sigterm timed out. Killing.", UNIT(s)->id);
|
||||
service_enter_signal(s, SERVICE_FINAL_SIGKILL, SERVICE_FAILURE_TIMEOUT);
|
||||
} else {
|
||||
- log_warning_unit(UNIT(s)->id,
|
||||
- "%s stop-final-sigterm timed out. Skipping SIGKILL. Entering failed mode.",
|
||||
- UNIT(s)->id);
|
||||
+ log_warning_unit(UNIT(s)->id, "%s stop-final-sigterm timed out. Skipping SIGKILL. Entering failed mode.", UNIT(s)->id);
|
||||
service_enter_dead(s, SERVICE_FAILURE_TIMEOUT, false);
|
||||
}
|
||||
|
||||
break;
|
||||
|
||||
case SERVICE_FINAL_SIGKILL:
|
||||
- log_warning_unit(UNIT(s)->id,
|
||||
- "%s still around after final SIGKILL. Entering failed mode.", UNIT(s)->id);
|
||||
+ log_warning_unit(UNIT(s)->id, "%s still around after final SIGKILL. Entering failed mode.", UNIT(s)->id);
|
||||
service_enter_dead(s, SERVICE_FAILURE_TIMEOUT, true);
|
||||
break;
|
||||
|
||||
@@ -2551,10 +2490,9 @@ static int service_dispatch_watchdog(sd_event_source *source, usec_t usec, void
|
||||
assert(s);
|
||||
assert(source == s->watchdog_event_source);
|
||||
|
||||
- log_error_unit(UNIT(s)->id,
|
||||
- "%s watchdog timeout (limit %s)!",
|
||||
- UNIT(s)->id,
|
||||
+ log_error_unit(UNIT(s)->id, "%s watchdog timeout (limit %s)!", UNIT(s)->id,
|
||||
format_timespan(t, sizeof(t), s->watchdog_usec, 1));
|
||||
+
|
||||
service_enter_signal(s, SERVICE_STOP_SIGTERM, SERVICE_FAILURE_WATCHDOG);
|
||||
|
||||
return 0;
|
||||
@@ -2571,9 +2509,7 @@ static void service_notify_message(Unit *u, pid_t pid, char **tags) {
|
||||
u->id, pid, tags && *tags ? tags[0] : "(empty)");
|
||||
|
||||
if (s->notify_access == NOTIFY_NONE) {
|
||||
- log_warning_unit(u->id,
|
||||
- "%s: Got notification message from PID "PID_FMT", but reception is disabled.",
|
||||
- u->id, pid);
|
||||
+ log_warning_unit(u->id, "%s: Got notification message from PID "PID_FMT", but reception is disabled.", u->id, pid);
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -2693,17 +2629,11 @@ static void service_bus_name_owner_change(
|
||||
assert(old_owner || new_owner);
|
||||
|
||||
if (old_owner && new_owner)
|
||||
- log_debug_unit(u->id,
|
||||
- "%s's D-Bus name %s changed owner from %s to %s",
|
||||
- u->id, name, old_owner, new_owner);
|
||||
+ log_debug_unit(u->id, "%s's D-Bus name %s changed owner from %s to %s", u->id, name, old_owner, new_owner);
|
||||
else if (old_owner)
|
||||
- log_debug_unit(u->id,
|
||||
- "%s's D-Bus name %s no longer registered by %s",
|
||||
- u->id, name, old_owner);
|
||||
+ log_debug_unit(u->id, "%s's D-Bus name %s no longer registered by %s", u->id, name, old_owner);
|
||||
else
|
||||
- log_debug_unit(u->id,
|
||||
- "%s's D-Bus name %s now registered by %s",
|
||||
- u->id, name, new_owner);
|
||||
+ log_debug_unit(u->id, "%s's D-Bus name %s now registered by %s", u->id, name, new_owner);
|
||||
|
||||
s->bus_name_good = !!new_owner;
|
||||
|
@ -0,0 +1,30 @@
|
||||
From f49650cee2c5256dc0491432e1f12a4ae19be6c5 Mon Sep 17 00:00:00 2001
|
||||
From: Lennart Poettering <lennart@poettering.net>
|
||||
Date: Thu, 21 Aug 2014 16:20:17 +0200
|
||||
Subject: [PATCH] service: don't invoke functions at the same time as declaring
|
||||
variables
|
||||
|
||||
---
|
||||
src/core/service.c | 8 ++++++--
|
||||
1 file changed, 6 insertions(+), 2 deletions(-)
|
||||
|
||||
diff --git a/src/core/service.c b/src/core/service.c
|
||||
index f10582d89e..fc952e848f 100644
|
||||
--- a/src/core/service.c
|
||||
+++ b/src/core/service.c
|
||||
@@ -694,9 +694,13 @@ static void service_set_state(Service *s, ServiceState state) {
|
||||
/* For remain_after_exit services, let's see if we can "release" the
|
||||
* hold on the console, since unit_notify() only does that in case of
|
||||
* change of state */
|
||||
- if (state == SERVICE_EXITED && s->remain_after_exit &&
|
||||
+ if (state == SERVICE_EXITED &&
|
||||
+ s->remain_after_exit &&
|
||||
UNIT(s)->manager->n_on_console > 0) {
|
||||
- ExecContext *ec = unit_get_exec_context(UNIT(s));
|
||||
+
|
||||
+ ExecContext *ec;
|
||||
+
|
||||
+ ec = unit_get_exec_context(UNIT(s));
|
||||
if (ec && exec_context_may_touch_console(ec)) {
|
||||
Manager *m = UNIT(s)->manager;
|
||||
|
139
0020-service-strv-introduce-strv_find_startswith-and-make.patch
Normal file
139
0020-service-strv-introduce-strv_find_startswith-and-make.patch
Normal file
@ -0,0 +1,139 @@
|
||||
From 28849dbadb7cd127f7f89e8892ec94c6a05070da Mon Sep 17 00:00:00 2001
|
||||
From: Lennart Poettering <lennart@poettering.net>
|
||||
Date: Thu, 21 Aug 2014 16:22:34 +0200
|
||||
Subject: [PATCH] service,strv: introduce strv_find_startswith() and make use
|
||||
of it
|
||||
|
||||
Unlike strv_find_prefix() the new call will return a pointer to the
|
||||
suffix of the item we found, instead of the whole item. This is more
|
||||
closer inline with what startswith() does, and allows us to simplify a
|
||||
couple of invocations.
|
||||
---
|
||||
src/core/service.c | 44 +++++++++++++++++++++-----------------------
|
||||
src/shared/strv.c | 17 +++++++++++++++++
|
||||
src/shared/strv.h | 1 +
|
||||
3 files changed, 39 insertions(+), 23 deletions(-)
|
||||
|
||||
diff --git a/src/core/service.c b/src/core/service.c
|
||||
index fc952e848f..262a40cc8b 100644
|
||||
--- a/src/core/service.c
|
||||
+++ b/src/core/service.c
|
||||
@@ -2526,12 +2526,13 @@ static void service_notify_message(Unit *u, pid_t pid, char **tags) {
|
||||
}
|
||||
|
||||
/* Interpret MAINPID= */
|
||||
- e = strv_find_prefix(tags, "MAINPID=");
|
||||
+ e = strv_find_startswith(tags, "MAINPID=");
|
||||
if (e && IN_SET(s->state, SERVICE_START, SERVICE_START_POST, SERVICE_RUNNING, SERVICE_RELOAD)) {
|
||||
- if (parse_pid(e + 8, &pid) < 0)
|
||||
+ if (parse_pid(e, &pid) < 0)
|
||||
log_warning_unit(u->id, "Failed to parse MAINPID= field in notification message: %s", e);
|
||||
else {
|
||||
- log_debug_unit(u->id, "%s: got %s", u->id, e);
|
||||
+ log_debug_unit(u->id, "%s: got MAINPID=%s", u->id, e);
|
||||
+
|
||||
service_set_main_pid(s, pid);
|
||||
unit_watch_pid(UNIT(s), pid);
|
||||
notify_dbus = true;
|
||||
@@ -2546,44 +2547,41 @@ static void service_notify_message(Unit *u, pid_t pid, char **tags) {
|
||||
}
|
||||
|
||||
/* Interpret STATUS= */
|
||||
- e = strv_find_prefix(tags, "STATUS=");
|
||||
+ e = strv_find_startswith(tags, "STATUS=");
|
||||
if (e) {
|
||||
- char *t;
|
||||
+ _cleanup_free_ char *t = NULL;
|
||||
|
||||
- if (e[7]) {
|
||||
- if (!utf8_is_valid(e+7)) {
|
||||
+ if (!isempty(e)) {
|
||||
+ if (!utf8_is_valid(e))
|
||||
log_warning_unit(u->id, "Status message in notification is not UTF-8 clean.");
|
||||
- return;
|
||||
- }
|
||||
+ else {
|
||||
+ log_debug_unit(u->id, "%s: got STATUS=%s", u->id, e);
|
||||
|
||||
- log_debug_unit(u->id, "%s: got %s", u->id, e);
|
||||
-
|
||||
- t = strdup(e+7);
|
||||
- if (!t) {
|
||||
- log_oom();
|
||||
- return;
|
||||
+ t = strdup(e);
|
||||
+ if (!t)
|
||||
+ log_oom();
|
||||
}
|
||||
-
|
||||
- } else
|
||||
- t = NULL;
|
||||
+ }
|
||||
|
||||
if (!streq_ptr(s->status_text, t)) {
|
||||
+
|
||||
free(s->status_text);
|
||||
s->status_text = t;
|
||||
+ t = NULL;
|
||||
+
|
||||
notify_dbus = true;
|
||||
- } else
|
||||
- free(t);
|
||||
+ }
|
||||
}
|
||||
|
||||
/* Interpret ERRNO= */
|
||||
- e = strv_find_prefix(tags, "ERRNO=");
|
||||
+ e = strv_find_startswith(tags, "ERRNO=");
|
||||
if (e) {
|
||||
int status_errno;
|
||||
|
||||
- if (safe_atoi(e + 6, &status_errno) < 0 || status_errno < 0)
|
||||
+ if (safe_atoi(e, &status_errno) < 0 || status_errno < 0)
|
||||
log_warning_unit(u->id, "Failed to parse ERRNO= field in notification message: %s", e);
|
||||
else {
|
||||
- log_debug_unit(u->id, "%s: got %s", u->id, e);
|
||||
+ log_debug_unit(u->id, "%s: got ERRNO=%s", u->id, e);
|
||||
|
||||
if (s->status_errno != status_errno) {
|
||||
s->status_errno = status_errno;
|
||||
diff --git a/src/shared/strv.c b/src/shared/strv.c
|
||||
index 6448f3170f..0df978d23b 100644
|
||||
--- a/src/shared/strv.c
|
||||
+++ b/src/shared/strv.c
|
||||
@@ -52,6 +52,23 @@ char *strv_find_prefix(char **l, const char *name) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
+char *strv_find_startswith(char **l, const char *name) {
|
||||
+ char **i, *e;
|
||||
+
|
||||
+ assert(name);
|
||||
+
|
||||
+ /* Like strv_find_prefix, but actually returns only the
|
||||
+ * suffix, not the whole item */
|
||||
+
|
||||
+ STRV_FOREACH(i, l) {
|
||||
+ e = startswith(*i, name);
|
||||
+ if (e)
|
||||
+ return e;
|
||||
+ }
|
||||
+
|
||||
+ return NULL;
|
||||
+}
|
||||
+
|
||||
void strv_free(char **l) {
|
||||
char **k;
|
||||
|
||||
diff --git a/src/shared/strv.h b/src/shared/strv.h
|
||||
index ee55c148aa..9c9633c515 100644
|
||||
--- a/src/shared/strv.h
|
||||
+++ b/src/shared/strv.h
|
||||
@@ -28,6 +28,7 @@
|
||||
|
||||
char *strv_find(char **l, const char *name) _pure_;
|
||||
char *strv_find_prefix(char **l, const char *name) _pure_;
|
||||
+char *strv_find_startswith(char **l, const char *name) _pure_;
|
||||
|
||||
void strv_free(char **l);
|
||||
DEFINE_TRIVIAL_CLEANUP_FUNC(char**, strv_free);
|
@ -0,0 +1,30 @@
|
||||
From 55836941ff642d42403921fa9d5fd2f8376ae722 Mon Sep 17 00:00:00 2001
|
||||
From: Lennart Poettering <lennart@poettering.net>
|
||||
Date: Thu, 21 Aug 2014 16:51:44 +0200
|
||||
Subject: [PATCH] manager: reuse sockaddr_union instead of redefining our own
|
||||
version of it
|
||||
|
||||
---
|
||||
src/core/manager.c | 7 ++-----
|
||||
1 file changed, 2 insertions(+), 5 deletions(-)
|
||||
|
||||
diff --git a/src/core/manager.c b/src/core/manager.c
|
||||
index 445461b6b9..e488aba5f8 100644
|
||||
--- a/src/core/manager.c
|
||||
+++ b/src/core/manager.c
|
||||
@@ -527,13 +527,10 @@ static int manager_setup_notify(Manager *m) {
|
||||
|
||||
if (m->notify_fd < 0) {
|
||||
_cleanup_close_ int fd = -1;
|
||||
- union {
|
||||
- struct sockaddr sa;
|
||||
- struct sockaddr_un un;
|
||||
- } sa = {
|
||||
+ union sockaddr_union sa = {
|
||||
.sa.sa_family = AF_UNIX,
|
||||
};
|
||||
- int one = 1;
|
||||
+ static const int one = 1;
|
||||
|
||||
/* First free all secondary fields */
|
||||
free(m->notify_socket);
|
@ -0,0 +1,99 @@
|
||||
From 70af4d17dafe81acc96f71f4ec06fbea7386bc38 Mon Sep 17 00:00:00 2001
|
||||
From: Lennart Poettering <lennart@poettering.net>
|
||||
Date: Thu, 21 Aug 2014 16:52:41 +0200
|
||||
Subject: [PATCH] manager: don#t dispatch sd_notify() messages and SIGCHLD
|
||||
multiple times to the same units
|
||||
|
||||
---
|
||||
src/core/manager.c | 44 +++++++++++++++++++++++---------------------
|
||||
1 file changed, 23 insertions(+), 21 deletions(-)
|
||||
|
||||
diff --git a/src/core/manager.c b/src/core/manager.c
|
||||
index e488aba5f8..c91ece116f 100644
|
||||
--- a/src/core/manager.c
|
||||
+++ b/src/core/manager.c
|
||||
@@ -562,7 +562,7 @@ static int manager_setup_notify(Manager *m) {
|
||||
strncpy(sa.un.sun_path, m->notify_socket, sizeof(sa.un.sun_path)-1);
|
||||
r = bind(fd, &sa.sa, offsetof(struct sockaddr_un, sun_path) + strlen(sa.un.sun_path));
|
||||
if (r < 0) {
|
||||
- log_error("bind(@%s) failed: %m", sa.un.sun_path+1);
|
||||
+ log_error("bind(%s) failed: %m", sa.un.sun_path);
|
||||
return -errno;
|
||||
}
|
||||
|
||||
@@ -1398,7 +1398,7 @@ static int manager_dispatch_notify_fd(sd_event_source *source, int fd, uint32_t
|
||||
.msg_controllen = sizeof(control),
|
||||
};
|
||||
struct ucred *ucred;
|
||||
- Unit *u;
|
||||
+ Unit *u1, *u2, *u3;
|
||||
|
||||
n = recvmsg(m->notify_fd, &msghdr, MSG_DONTWAIT);
|
||||
if (n <= 0) {
|
||||
@@ -1424,21 +1424,23 @@ static int manager_dispatch_notify_fd(sd_event_source *source, int fd, uint32_t
|
||||
assert((size_t) n < sizeof(buf));
|
||||
buf[n] = 0;
|
||||
|
||||
- u = manager_get_unit_by_pid(m, ucred->pid);
|
||||
- if (u) {
|
||||
- manager_invoke_notify_message(m, u, ucred->pid, buf, n);
|
||||
+ /* Notify every unit that might be interested, but try
|
||||
+ * to avoid notifying the same one multiple times. */
|
||||
+ u1 = manager_get_unit_by_pid(m, ucred->pid);
|
||||
+ if (u1) {
|
||||
+ manager_invoke_notify_message(m, u1, ucred->pid, buf, n);
|
||||
found = true;
|
||||
}
|
||||
|
||||
- u = hashmap_get(m->watch_pids1, LONG_TO_PTR(ucred->pid));
|
||||
- if (u) {
|
||||
- manager_invoke_notify_message(m, u, ucred->pid, buf, n);
|
||||
+ u2 = hashmap_get(m->watch_pids1, LONG_TO_PTR(ucred->pid));
|
||||
+ if (u2 && u2 != u1) {
|
||||
+ manager_invoke_notify_message(m, u2, ucred->pid, buf, n);
|
||||
found = true;
|
||||
}
|
||||
|
||||
- u = hashmap_get(m->watch_pids2, LONG_TO_PTR(ucred->pid));
|
||||
- if (u) {
|
||||
- manager_invoke_notify_message(m, u, ucred->pid, buf, n);
|
||||
+ u3 = hashmap_get(m->watch_pids2, LONG_TO_PTR(ucred->pid));
|
||||
+ if (u3 && u3 != u2 && u3 != u1) {
|
||||
+ manager_invoke_notify_message(m, u3, ucred->pid, buf, n);
|
||||
found = true;
|
||||
}
|
||||
|
||||
@@ -1485,7 +1487,7 @@ static int manager_dispatch_sigchld(Manager *m) {
|
||||
|
||||
if (si.si_code == CLD_EXITED || si.si_code == CLD_KILLED || si.si_code == CLD_DUMPED) {
|
||||
_cleanup_free_ char *name = NULL;
|
||||
- Unit *u;
|
||||
+ Unit *u1, *u2, *u3;
|
||||
|
||||
get_process_comm(si.si_pid, &name);
|
||||
|
||||
@@ -1499,15 +1501,15 @@ static int manager_dispatch_sigchld(Manager *m) {
|
||||
|
||||
/* And now figure out the unit this belongs
|
||||
* to, it might be multiple... */
|
||||
- u = manager_get_unit_by_pid(m, si.si_pid);
|
||||
- if (u)
|
||||
- invoke_sigchld_event(m, u, &si);
|
||||
- u = hashmap_get(m->watch_pids1, LONG_TO_PTR(si.si_pid));
|
||||
- if (u)
|
||||
- invoke_sigchld_event(m, u, &si);
|
||||
- u = hashmap_get(m->watch_pids2, LONG_TO_PTR(si.si_pid));
|
||||
- if (u)
|
||||
- invoke_sigchld_event(m, u, &si);
|
||||
+ u1 = manager_get_unit_by_pid(m, si.si_pid);
|
||||
+ if (u1)
|
||||
+ invoke_sigchld_event(m, u1, &si);
|
||||
+ u2 = hashmap_get(m->watch_pids1, LONG_TO_PTR(si.si_pid));
|
||||
+ if (u2 && u2 != u1)
|
||||
+ invoke_sigchld_event(m, u2, &si);
|
||||
+ u3 = hashmap_get(m->watch_pids2, LONG_TO_PTR(si.si_pid));
|
||||
+ if (u3 && u3 != u2 && u3 != u1)
|
||||
+ invoke_sigchld_event(m, u3, &si);
|
||||
}
|
||||
|
||||
/* And now, we actually reap the zombie. */
|
471
0023-core-allow-informing-systemd-about-service-status-ch.patch
Normal file
471
0023-core-allow-informing-systemd-about-service-status-ch.patch
Normal file
@ -0,0 +1,471 @@
|
||||
From 308d72dc1e2106f94ae637e2ea510e8d466d2af1 Mon Sep 17 00:00:00 2001
|
||||
From: Lennart Poettering <lennart@poettering.net>
|
||||
Date: Thu, 21 Aug 2014 17:03:15 +0200
|
||||
Subject: [PATCH] core: allow informing systemd about service status changes
|
||||
with RELOADING=1 and STOPPING=1 sd_notify() messages
|
||||
|
||||
---
|
||||
man/sd_notify.xml | 93 ++++++++++++++++++++++++++++---------------
|
||||
src/core/service.c | 105 +++++++++++++++++++++++++++++++++++++++++++------
|
||||
src/core/service.h | 13 ++++++
|
||||
src/test/test-daemon.c | 22 +++++++++--
|
||||
4 files changed, 185 insertions(+), 48 deletions(-)
|
||||
|
||||
diff --git a/man/sd_notify.xml b/man/sd_notify.xml
|
||||
index 6bf8230763..fbb882dfd2 100644
|
||||
--- a/man/sd_notify.xml
|
||||
+++ b/man/sd_notify.xml
|
||||
@@ -46,7 +46,7 @@
|
||||
<refnamediv>
|
||||
<refname>sd_notify</refname>
|
||||
<refname>sd_notifyf</refname>
|
||||
- <refpurpose>Notify service manager about start-up completion and other daemon status changes</refpurpose>
|
||||
+ <refpurpose>Notify service manager about start-up completion and other service status changes</refpurpose>
|
||||
</refnamediv>
|
||||
|
||||
<refsynopsisdiv>
|
||||
@@ -70,12 +70,12 @@
|
||||
|
||||
<refsect1>
|
||||
<title>Description</title>
|
||||
- <para><function>sd_notify()</function> shall be called
|
||||
- by a daemon to notify the init system about status
|
||||
- changes. It can be used to send arbitrary information,
|
||||
- encoded in an environment-block-like string. Most
|
||||
- importantly it can be used for start-up completion
|
||||
- notification.</para>
|
||||
+ <para><function>sd_notify()</function> may be called
|
||||
+ by a service to notify the service manager about
|
||||
+ state changes. It can be used to send arbitrary
|
||||
+ information, encoded in an environment-block-like
|
||||
+ string. Most importantly it can be used for start-up
|
||||
+ completion notification.</para>
|
||||
|
||||
<para>If the <parameter>unset_environment</parameter>
|
||||
parameter is non-zero, <function>sd_notify()</function>
|
||||
@@ -99,58 +99,87 @@
|
||||
<varlistentry>
|
||||
<term>READY=1</term>
|
||||
|
||||
- <listitem><para>Tells the init system
|
||||
- that daemon startup is finished. This
|
||||
- is only used by systemd if the service
|
||||
- definition file has Type=notify
|
||||
- set. The passed argument is a boolean
|
||||
- "1" or "0". Since there is little
|
||||
+ <listitem><para>Tells the service
|
||||
+ manager that service startup is
|
||||
+ finished. This is only used by systemd
|
||||
+ if the service definition file has
|
||||
+ Type=notify set. Since there is little
|
||||
value in signaling non-readiness, the
|
||||
- only value daemons should send is
|
||||
- "READY=1".</para></listitem>
|
||||
+ only value services should send is
|
||||
+ <literal>READY=1</literal>
|
||||
+ (i.e. <literal>READY=0</literal> is
|
||||
+ not defined).</para></listitem>
|
||||
+ </varlistentry>
|
||||
+
|
||||
+ <varlistentry>
|
||||
+ <term>RELOADING=1</term>
|
||||
+
|
||||
+ <listitem><para>Tells the service manager
|
||||
+ that the service is reloading its
|
||||
+ configuration. This is useful to allow
|
||||
+ the service manager to track the service's
|
||||
+ internal state, and present it to the
|
||||
+ user. Note that a service that sends
|
||||
+ this notification must also send a
|
||||
+ <literal>READY=1</literal>
|
||||
+ notification when it completed
|
||||
+ reloading its
|
||||
+ configuration.</para></listitem>
|
||||
+ </varlistentry>
|
||||
+
|
||||
+ <varlistentry>
|
||||
+ <term>STOPPING=1</term>
|
||||
+
|
||||
+ <listitem><para>Tells the service manager
|
||||
+ that the service is beginning its
|
||||
+ shutdown. This is useful to allow the
|
||||
+ service manager to track the service's
|
||||
+ internal state, and present it to the
|
||||
+ user.</para></listitem>
|
||||
</varlistentry>
|
||||
|
||||
<varlistentry>
|
||||
<term>STATUS=...</term>
|
||||
|
||||
<listitem><para>Passes a single-line
|
||||
- status string back to the init system
|
||||
- that describes the daemon state. This
|
||||
+ UTF-8 status string back to the service manager
|
||||
+ that describes the service state. This
|
||||
is free-form and can be used for
|
||||
various purposes: general state
|
||||
feedback, fsck-like programs could
|
||||
pass completion percentages and
|
||||
failing programs could pass a human
|
||||
readable error message. Example:
|
||||
- "STATUS=Completed 66% of file system
|
||||
- check..."</para></listitem>
|
||||
+ <literal>STATUS=Completed 66% of file
|
||||
+ system
|
||||
+ check...</literal></para></listitem>
|
||||
</varlistentry>
|
||||
|
||||
<varlistentry>
|
||||
<term>ERRNO=...</term>
|
||||
|
||||
- <listitem><para>If a daemon fails, the
|
||||
+ <listitem><para>If a service fails, the
|
||||
errno-style error code, formatted as
|
||||
- string. Example: "ERRNO=2" for
|
||||
+ string. Example: <literal>ERRNO=2</literal> for
|
||||
ENOENT.</para></listitem>
|
||||
</varlistentry>
|
||||
|
||||
<varlistentry>
|
||||
<term>BUSERROR=...</term>
|
||||
|
||||
- <listitem><para>If a daemon fails, the
|
||||
+ <listitem><para>If a service fails, the
|
||||
D-Bus error-style error code. Example:
|
||||
- "BUSERROR=org.freedesktop.DBus.Error.TimedOut"</para></listitem>
|
||||
+ <literal>BUSERROR=org.freedesktop.DBus.Error.TimedOut</literal></para></listitem>
|
||||
</varlistentry>
|
||||
|
||||
<varlistentry>
|
||||
<term>MAINPID=...</term>
|
||||
|
||||
<listitem><para>The main pid of the
|
||||
- daemon, in case the init system did
|
||||
+ service, in case the service manager did
|
||||
not fork off the process
|
||||
itself. Example:
|
||||
- "MAINPID=4711"</para></listitem>
|
||||
+ <literal>MAINPID=4711</literal></para></listitem>
|
||||
</varlistentry>
|
||||
|
||||
<varlistentry>
|
||||
@@ -183,7 +212,7 @@
|
||||
clashes.</para>
|
||||
|
||||
<para>Note that systemd will accept status data sent
|
||||
- from a daemon only if the
|
||||
+ from a service only if the
|
||||
<varname>NotifyAccess=</varname> option is correctly
|
||||
set in the service definition file. See
|
||||
<citerefentry><refentrytitle>systemd.service</refentrytitle><manvolnum>5</manvolnum></citerefentry>
|
||||
@@ -222,7 +251,7 @@
|
||||
<varname>$NOTIFY_SOCKET</varname> is <literal>@</literal>, the string is
|
||||
understood as Linux abstract namespace socket. The
|
||||
datagram is accompanied by the process credentials of
|
||||
- the sending daemon, using SCM_CREDENTIALS.</para>
|
||||
+ the sending service, using SCM_CREDENTIALS.</para>
|
||||
</refsect1>
|
||||
|
||||
<refsect1>
|
||||
@@ -232,7 +261,7 @@
|
||||
<varlistentry>
|
||||
<term><varname>$NOTIFY_SOCKET</varname></term>
|
||||
|
||||
- <listitem><para>Set by the init system
|
||||
+ <listitem><para>Set by the service manager
|
||||
for supervised processes for status
|
||||
and start-up completion
|
||||
notification. This environment variable
|
||||
@@ -249,9 +278,9 @@
|
||||
<example>
|
||||
<title>Start-up Notification</title>
|
||||
|
||||
- <para>When a daemon finished starting up, it
|
||||
+ <para>When a service finished starting up, it
|
||||
might issue the following call to notify
|
||||
- the init system:</para>
|
||||
+ the service manager:</para>
|
||||
|
||||
<programlisting>sd_notify(0, "READY=1");</programlisting>
|
||||
</example>
|
||||
@@ -259,7 +288,7 @@
|
||||
<example>
|
||||
<title>Extended Start-up Notification</title>
|
||||
|
||||
- <para>A daemon could send the following after
|
||||
+ <para>A service could send the following after
|
||||
completing initialization:</para>
|
||||
|
||||
<programlisting>sd_notifyf(0, "READY=1\n"
|
||||
@@ -271,7 +300,7 @@
|
||||
<example>
|
||||
<title>Error Cause Notification</title>
|
||||
|
||||
- <para>A daemon could send the following shortly before exiting, on failure</para>
|
||||
+ <para>A service could send the following shortly before exiting, on failure</para>
|
||||
|
||||
<programlisting>sd_notifyf(0, "STATUS=Failed to start up: %s\n"
|
||||
"ERRNO=%i",
|
||||
diff --git a/src/core/service.c b/src/core/service.c
|
||||
index 262a40cc8b..3221938793 100644
|
||||
--- a/src/core/service.c
|
||||
+++ b/src/core/service.c
|
||||
@@ -92,6 +92,7 @@ static int service_dispatch_timer(sd_event_source *source, usec_t usec, void *us
|
||||
static int service_dispatch_watchdog(sd_event_source *source, usec_t usec, void *userdata);
|
||||
|
||||
static void service_enter_signal(Service *s, ServiceState state, ServiceResult f);
|
||||
+static void service_enter_reload_by_notify(Service *s);
|
||||
|
||||
static void service_init(Unit *u) {
|
||||
Service *s = SERVICE(u);
|
||||
@@ -473,7 +474,8 @@ static void service_dump(Unit *u, FILE *f, const char *prefix) {
|
||||
"%sGuessMainPID: %s\n"
|
||||
"%sType: %s\n"
|
||||
"%sRestart: %s\n"
|
||||
- "%sNotifyAccess: %s\n",
|
||||
+ "%sNotifyAccess: %s\n"
|
||||
+ "%sNotifyState: %s\n",
|
||||
prefix, service_state_to_string(s->state),
|
||||
prefix, service_result_to_string(s->result),
|
||||
prefix, service_result_to_string(s->reload_result),
|
||||
@@ -483,7 +485,8 @@ static void service_dump(Unit *u, FILE *f, const char *prefix) {
|
||||
prefix, yes_no(s->guess_main_pid),
|
||||
prefix, service_type_to_string(s->type),
|
||||
prefix, service_restart_to_string(s->restart),
|
||||
- prefix, notify_access_to_string(s->notify_access));
|
||||
+ prefix, notify_access_to_string(s->notify_access),
|
||||
+ prefix, notify_state_to_string(s->notify_state));
|
||||
|
||||
if (s->control_pid > 0)
|
||||
fprintf(f,
|
||||
@@ -1176,6 +1179,17 @@ fail:
|
||||
service_enter_dead(s, SERVICE_FAILURE_RESOURCES, true);
|
||||
}
|
||||
|
||||
+static void service_enter_stop_by_notify(Service *s) {
|
||||
+ assert(s);
|
||||
+
|
||||
+ unit_watch_all_pids(UNIT(s));
|
||||
+
|
||||
+ if (s->timeout_stop_usec > 0)
|
||||
+ service_arm_timer(s, s->timeout_stop_usec);
|
||||
+
|
||||
+ service_set_state(s, SERVICE_STOP);
|
||||
+}
|
||||
+
|
||||
static void service_enter_stop(Service *s, ServiceResult f) {
|
||||
int r;
|
||||
|
||||
@@ -1226,9 +1240,18 @@ static void service_enter_running(Service *s, ServiceResult f) {
|
||||
cgroup_ok = cgroup_good(s);
|
||||
|
||||
if ((main_pid_ok > 0 || (main_pid_ok < 0 && cgroup_ok != 0)) &&
|
||||
- (s->bus_name_good || s->type != SERVICE_DBUS))
|
||||
- service_set_state(s, SERVICE_RUNNING);
|
||||
- else if (s->remain_after_exit)
|
||||
+ (s->bus_name_good || s->type != SERVICE_DBUS)) {
|
||||
+
|
||||
+ /* If there are any queued up sd_notify()
|
||||
+ * notifications, process them now */
|
||||
+ if (s->notify_state == NOTIFY_RELOADING)
|
||||
+ service_enter_reload_by_notify(s);
|
||||
+ else if (s->notify_state == NOTIFY_STOPPING)
|
||||
+ service_enter_stop_by_notify(s);
|
||||
+ else
|
||||
+ service_set_state(s, SERVICE_RUNNING);
|
||||
+
|
||||
+ } else if (s->remain_after_exit)
|
||||
service_set_state(s, SERVICE_EXITED);
|
||||
else
|
||||
service_enter_stop(s, SERVICE_SUCCESS);
|
||||
@@ -1433,12 +1456,19 @@ static void service_enter_restart(Service *s) {
|
||||
return;
|
||||
|
||||
fail:
|
||||
- log_warning_unit(UNIT(s)->id,
|
||||
- "%s failed to schedule restart job: %s",
|
||||
- UNIT(s)->id, bus_error_message(&error, -r));
|
||||
+ log_warning_unit(UNIT(s)->id, "%s failed to schedule restart job: %s", UNIT(s)->id, bus_error_message(&error, -r));
|
||||
service_enter_dead(s, SERVICE_FAILURE_RESOURCES, false);
|
||||
}
|
||||
|
||||
+static void service_enter_reload_by_notify(Service *s) {
|
||||
+ assert(s);
|
||||
+
|
||||
+ if (s->timeout_start_usec > 0)
|
||||
+ service_arm_timer(s, s->timeout_start_usec);
|
||||
+
|
||||
+ service_set_state(s, SERVICE_RELOAD);
|
||||
+}
|
||||
+
|
||||
static void service_enter_reload(Service *s) {
|
||||
int r;
|
||||
|
||||
@@ -1667,6 +1697,8 @@ static int service_start(Unit *u) {
|
||||
s->status_text = NULL;
|
||||
s->status_errno = 0;
|
||||
|
||||
+ s->notify_state = NOTIFY_UNKNOWN;
|
||||
+
|
||||
service_enter_start_pre(s);
|
||||
return 0;
|
||||
}
|
||||
@@ -2504,13 +2536,15 @@ static int service_dispatch_watchdog(sd_event_source *source, usec_t usec, void
|
||||
|
||||
static void service_notify_message(Unit *u, pid_t pid, char **tags) {
|
||||
Service *s = SERVICE(u);
|
||||
- const char *e;
|
||||
+ _cleanup_free_ char *cc = NULL;
|
||||
bool notify_dbus = false;
|
||||
+ const char *e;
|
||||
|
||||
assert(u);
|
||||
|
||||
- log_debug_unit(u->id, "%s: Got notification message from PID "PID_FMT" (%s...)",
|
||||
- u->id, pid, tags && *tags ? tags[0] : "(empty)");
|
||||
+ cc = strv_join(tags, ", ");
|
||||
+ log_debug_unit(u->id, "%s: Got notification message from PID "PID_FMT" (%s)",
|
||||
+ u->id, pid, isempty(cc) ? "n/a" : cc);
|
||||
|
||||
if (s->notify_access == NOTIFY_NONE) {
|
||||
log_warning_unit(u->id, "%s: Got notification message from PID "PID_FMT", but reception is disabled.", u->id, pid);
|
||||
@@ -2539,10 +2573,46 @@ static void service_notify_message(Unit *u, pid_t pid, char **tags) {
|
||||
}
|
||||
}
|
||||
|
||||
+ /* Interpret RELOADING= */
|
||||
+ if (strv_find(tags, "RELOADING=1")) {
|
||||
+
|
||||
+ log_debug_unit(u->id, "%s: got RELOADING=1", u->id);
|
||||
+ s->notify_state = NOTIFY_RELOADING;
|
||||
+
|
||||
+ if (s->state == SERVICE_RUNNING)
|
||||
+ service_enter_reload_by_notify(s);
|
||||
+
|
||||
+ notify_dbus = true;
|
||||
+ }
|
||||
+
|
||||
/* Interpret READY= */
|
||||
- if (s->type == SERVICE_NOTIFY && s->state == SERVICE_START && strv_find(tags, "READY=1")) {
|
||||
+ if (strv_find(tags, "READY=1")) {
|
||||
+
|
||||
log_debug_unit(u->id, "%s: got READY=1", u->id);
|
||||
- service_enter_start_post(s);
|
||||
+ s->notify_state = NOTIFY_READY;
|
||||
+
|
||||
+ /* Type=notify services inform us about completed
|
||||
+ * initialization with READY=1 */
|
||||
+ if (s->type == SERVICE_NOTIFY && s->state == SERVICE_START)
|
||||
+ service_enter_start_post(s);
|
||||
+
|
||||
+ /* Sending READY=1 while we are reloading informs us
|
||||
+ * that the reloading is complete */
|
||||
+ if (s->state == SERVICE_RELOAD && s->control_pid == 0)
|
||||
+ service_enter_running(s, SERVICE_SUCCESS);
|
||||
+
|
||||
+ notify_dbus = true;
|
||||
+ }
|
||||
+
|
||||
+ /* Interpret STOPPING= */
|
||||
+ if (strv_find(tags, "STOPPING=1")) {
|
||||
+
|
||||
+ log_debug_unit(u->id, "%s: got STOPPING=1", u->id);
|
||||
+ s->notify_state = NOTIFY_STOPPING;
|
||||
+
|
||||
+ if (s->state == SERVICE_RUNNING)
|
||||
+ service_enter_stop_by_notify(s);
|
||||
+
|
||||
notify_dbus = true;
|
||||
}
|
||||
|
||||
@@ -2798,6 +2868,15 @@ static const char* const notify_access_table[_NOTIFY_ACCESS_MAX] = {
|
||||
|
||||
DEFINE_STRING_TABLE_LOOKUP(notify_access, NotifyAccess);
|
||||
|
||||
+static const char* const notify_state_table[_NOTIFY_STATE_MAX] = {
|
||||
+ [NOTIFY_UNKNOWN] = "unknown",
|
||||
+ [NOTIFY_READY] = "ready",
|
||||
+ [NOTIFY_RELOADING] = "reloading",
|
||||
+ [NOTIFY_STOPPING] = "stopping",
|
||||
+};
|
||||
+
|
||||
+DEFINE_STRING_TABLE_LOOKUP(notify_state, NotifyState);
|
||||
+
|
||||
static const char* const service_result_table[_SERVICE_RESULT_MAX] = {
|
||||
[SERVICE_SUCCESS] = "success",
|
||||
[SERVICE_FAILURE_RESOURCES] = "resources",
|
||||
diff --git a/src/core/service.h b/src/core/service.h
|
||||
index 686cf4b0bd..0227321d99 100644
|
||||
--- a/src/core/service.h
|
||||
+++ b/src/core/service.h
|
||||
@@ -91,6 +91,15 @@ typedef enum NotifyAccess {
|
||||
_NOTIFY_ACCESS_INVALID = -1
|
||||
} NotifyAccess;
|
||||
|
||||
+typedef enum NotifyState {
|
||||
+ NOTIFY_UNKNOWN,
|
||||
+ NOTIFY_READY,
|
||||
+ NOTIFY_RELOADING,
|
||||
+ NOTIFY_STOPPING,
|
||||
+ _NOTIFY_STATE_MAX,
|
||||
+ _NOTIFY_STATE_INVALID = -1
|
||||
+} NotifyState;
|
||||
+
|
||||
typedef enum ServiceResult {
|
||||
SERVICE_SUCCESS,
|
||||
SERVICE_FAILURE_RESOURCES,
|
||||
@@ -196,6 +205,7 @@ struct Service {
|
||||
PathSpec *pid_file_pathspec;
|
||||
|
||||
NotifyAccess notify_access;
|
||||
+ NotifyState notify_state;
|
||||
};
|
||||
|
||||
extern const UnitVTable service_vtable;
|
||||
@@ -219,6 +229,9 @@ ServiceExecCommand service_exec_command_from_string(const char *s) _pure_;
|
||||
const char* notify_access_to_string(NotifyAccess i) _const_;
|
||||
NotifyAccess notify_access_from_string(const char *s) _pure_;
|
||||
|
||||
+const char* notify_state_to_string(NotifyState i) _const_;
|
||||
+NotifyState notify_state_from_string(const char *s) _pure_;
|
||||
+
|
||||
const char* service_result_to_string(ServiceResult i) _const_;
|
||||
ServiceResult service_result_from_string(const char *s) _pure_;
|
||||
|
||||
diff --git a/src/test/test-daemon.c b/src/test/test-daemon.c
|
||||
index bcc049b325..7e0ac754d1 100644
|
||||
--- a/src/test/test-daemon.c
|
||||
+++ b/src/test/test-daemon.c
|
||||
@@ -25,13 +25,29 @@
|
||||
|
||||
int main(int argc, char*argv[]) {
|
||||
|
||||
- sd_notify(0, "STATUS=Starting up");
|
||||
+ sd_notify(0,
|
||||
+ "STATUS=Starting up");
|
||||
+ sleep(5);
|
||||
+
|
||||
+ sd_notify(0,
|
||||
+ "STATUS=Running\n"
|
||||
+ "READY=1");
|
||||
+ sleep(5);
|
||||
+
|
||||
+ sd_notify(0,
|
||||
+ "STATUS=Reloading\n"
|
||||
+ "RELOADING=1");
|
||||
sleep(5);
|
||||
+
|
||||
sd_notify(0,
|
||||
"STATUS=Running\n"
|
||||
"READY=1");
|
||||
- sleep(10);
|
||||
- sd_notify(0, "STATUS=Quitting");
|
||||
+ sleep(5);
|
||||
+
|
||||
+ sd_notify(0,
|
||||
+ "STATUS=Quitting\n"
|
||||
+ "STOPPING=1");
|
||||
+ sleep(5);
|
||||
|
||||
return 0;
|
||||
}
|
236
0024-notify-send-STOPPING-1-from-our-daemons.patch
Normal file
236
0024-notify-send-STOPPING-1-from-our-daemons.patch
Normal file
@ -0,0 +1,236 @@
|
||||
From af4ec4309e8f82aad87a8d574785c12f8763d5f8 Mon Sep 17 00:00:00 2001
|
||||
From: Lennart Poettering <lennart@poettering.net>
|
||||
Date: Thu, 21 Aug 2014 17:19:28 +0200
|
||||
Subject: [PATCH] notify: send STOPPING=1 from our daemons
|
||||
|
||||
---
|
||||
src/bus-proxyd/bus-proxyd.c | 6 +++++-
|
||||
src/core/manager.c | 3 ++-
|
||||
src/initctl/initctl.c | 1 +
|
||||
src/journal-remote/journal-remote.c | 6 ++++--
|
||||
src/journal-remote/journal-upload.c | 5 ++++-
|
||||
src/journal/journald.c | 4 +++-
|
||||
src/login/logind.c | 1 +
|
||||
src/machine/machined.c | 1 +
|
||||
src/network/networkd.c | 1 +
|
||||
src/nspawn/nspawn.c | 8 +++++++-
|
||||
src/resolve/resolved.c | 4 +++-
|
||||
src/shutdownd/shutdownd.c | 1 +
|
||||
src/timesync/timesyncd.c | 8 ++++++--
|
||||
13 files changed, 39 insertions(+), 10 deletions(-)
|
||||
|
||||
diff --git a/src/bus-proxyd/bus-proxyd.c b/src/bus-proxyd/bus-proxyd.c
|
||||
index d8d989b9b0..d35d7f63b2 100644
|
||||
--- a/src/bus-proxyd/bus-proxyd.c
|
||||
+++ b/src/bus-proxyd/bus-proxyd.c
|
||||
@@ -239,7 +239,7 @@ static int rename_service(sd_bus *a, sd_bus *b) {
|
||||
pid, p,
|
||||
uid, name,
|
||||
a->unique_name);
|
||||
- ;
|
||||
+
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -1474,6 +1474,10 @@ int main(int argc, char *argv[]) {
|
||||
}
|
||||
|
||||
finish:
|
||||
+ sd_notify(false,
|
||||
+ "STOPPING=1\n"
|
||||
+ "STATUS=Shutting down.");
|
||||
+
|
||||
policy_free(&policy);
|
||||
strv_free(arg_configuration);
|
||||
free(arg_address);
|
||||
diff --git a/src/core/manager.c b/src/core/manager.c
|
||||
index c91ece116f..7401817844 100644
|
||||
--- a/src/core/manager.c
|
||||
+++ b/src/core/manager.c
|
||||
@@ -2551,7 +2551,8 @@ void manager_check_finished(Manager *m) {
|
||||
bus_manager_send_finished(m, firmware_usec, loader_usec, kernel_usec, initrd_usec, userspace_usec, total_usec);
|
||||
|
||||
sd_notifyf(false,
|
||||
- "READY=1\nSTATUS=Startup finished in %s.",
|
||||
+ "READY=1\n"
|
||||
+ "STATUS=Startup finished in %s.",
|
||||
format_timespan(sum, sizeof(sum), total_usec, USEC_PER_MSEC));
|
||||
}
|
||||
|
||||
diff --git a/src/initctl/initctl.c b/src/initctl/initctl.c
|
||||
index 0954e58afd..f1c2b8dfb4 100644
|
||||
--- a/src/initctl/initctl.c
|
||||
+++ b/src/initctl/initctl.c
|
||||
@@ -431,6 +431,7 @@ int main(int argc, char *argv[]) {
|
||||
|
||||
fail:
|
||||
sd_notify(false,
|
||||
+ "STOPPING=1\n"
|
||||
"STATUS=Shutting down...");
|
||||
|
||||
server_done(&server);
|
||||
diff --git a/src/journal-remote/journal-remote.c b/src/journal-remote/journal-remote.c
|
||||
index 7f422bfb37..1cc86aeaf3 100644
|
||||
--- a/src/journal-remote/journal-remote.c
|
||||
+++ b/src/journal-remote/journal-remote.c
|
||||
@@ -1530,10 +1530,12 @@ int main(int argc, char **argv) {
|
||||
}
|
||||
}
|
||||
|
||||
- server_destroy(&s);
|
||||
+ sd_notifyf(false,
|
||||
+ "STOPPING=1\n"
|
||||
+ "STATUS=Shutting down after writing %" PRIu64 " entries...", s.event_count);
|
||||
log_info("Finishing after writing %" PRIu64 " entries", s.event_count);
|
||||
|
||||
- sd_notify(false, "STATUS=Shutting down...");
|
||||
+ server_destroy(&s);
|
||||
|
||||
free(arg_key);
|
||||
free(arg_cert);
|
||||
diff --git a/src/journal-remote/journal-upload.c b/src/journal-remote/journal-upload.c
|
||||
index bdeeff6778..40c380aa9e 100644
|
||||
--- a/src/journal-remote/journal-upload.c
|
||||
+++ b/src/journal-remote/journal-upload.c
|
||||
@@ -818,7 +818,10 @@ int main(int argc, char **argv) {
|
||||
}
|
||||
|
||||
cleanup:
|
||||
- sd_notify(false, "STATUS=Shutting down...");
|
||||
+ sd_notify(false,
|
||||
+ "STOPPING=1\n"
|
||||
+ "STATUS=Shutting down...");
|
||||
+
|
||||
destroy_uploader(&u);
|
||||
|
||||
finish:
|
||||
diff --git a/src/journal/journald.c b/src/journal/journald.c
|
||||
index b1a0e25d0c..de40827d6a 100644
|
||||
--- a/src/journal/journald.c
|
||||
+++ b/src/journal/journald.c
|
||||
@@ -116,7 +116,9 @@ int main(int argc, char *argv[]) {
|
||||
server_driver_message(&server, SD_MESSAGE_JOURNAL_STOP, "Journal stopped");
|
||||
|
||||
finish:
|
||||
- sd_notify(false, "STATUS=Shutting down...");
|
||||
+ sd_notify(false,
|
||||
+ "STOPPING=1\n"
|
||||
+ "STATUS=Shutting down...");
|
||||
|
||||
server_done(&server);
|
||||
|
||||
diff --git a/src/login/logind.c b/src/login/logind.c
|
||||
index 006c56ae51..52e1c43a47 100644
|
||||
--- a/src/login/logind.c
|
||||
+++ b/src/login/logind.c
|
||||
@@ -1226,6 +1226,7 @@ int main(int argc, char *argv[]) {
|
||||
|
||||
finish:
|
||||
sd_notify(false,
|
||||
+ "STOPPING=1\n"
|
||||
"STATUS=Shutting down...");
|
||||
|
||||
if (m)
|
||||
diff --git a/src/machine/machined.c b/src/machine/machined.c
|
||||
index 6160320127..f9d180d24a 100644
|
||||
--- a/src/machine/machined.c
|
||||
+++ b/src/machine/machined.c
|
||||
@@ -350,6 +350,7 @@ int main(int argc, char *argv[]) {
|
||||
|
||||
finish:
|
||||
sd_notify(false,
|
||||
+ "STOPPING=1\n"
|
||||
"STATUS=Shutting down...");
|
||||
|
||||
if (m)
|
||||
diff --git a/src/network/networkd.c b/src/network/networkd.c
|
||||
index 665f4c4709..fdb80368d4 100644
|
||||
--- a/src/network/networkd.c
|
||||
+++ b/src/network/networkd.c
|
||||
@@ -125,6 +125,7 @@ int main(int argc, char *argv[]) {
|
||||
|
||||
out:
|
||||
sd_notify(false,
|
||||
+ "STOPPING=1\n"
|
||||
"STATUS=Shutting down...");
|
||||
|
||||
return r < 0 ? EXIT_FAILURE : EXIT_SUCCESS;
|
||||
diff --git a/src/nspawn/nspawn.c b/src/nspawn/nspawn.c
|
||||
index d01da45930..2c718557ee 100644
|
||||
--- a/src/nspawn/nspawn.c
|
||||
+++ b/src/nspawn/nspawn.c
|
||||
@@ -3071,7 +3071,9 @@ int main(int argc, char *argv[]) {
|
||||
goto finish;
|
||||
}
|
||||
|
||||
- sd_notify(0, "READY=1");
|
||||
+ sd_notify(false,
|
||||
+ "READY=1\n"
|
||||
+ "STATUS=Container running.");
|
||||
|
||||
assert_se(sigemptyset(&mask) == 0);
|
||||
assert_se(sigemptyset(&mask_chld) == 0);
|
||||
@@ -3504,6 +3506,10 @@ int main(int argc, char *argv[]) {
|
||||
}
|
||||
|
||||
finish:
|
||||
+ sd_notify(false,
|
||||
+ "STOPPING=1\n"
|
||||
+ "STATUS=Terminating...");
|
||||
+
|
||||
loop_remove(loop_nr, &image_fd);
|
||||
|
||||
if (pid > 0)
|
||||
diff --git a/src/resolve/resolved.c b/src/resolve/resolved.c
|
||||
index 8235558585..88c3bcc591 100644
|
||||
--- a/src/resolve/resolved.c
|
||||
+++ b/src/resolve/resolved.c
|
||||
@@ -100,7 +100,9 @@ int main(int argc, char *argv[]) {
|
||||
sd_event_get_exit_code(m->event, &r);
|
||||
|
||||
finish:
|
||||
- sd_notify(false, "STATUS=Shutting down...");
|
||||
+ sd_notify(false,
|
||||
+ "STOPPIN=1\n"
|
||||
+ "STATUS=Shutting down...");
|
||||
|
||||
return r < 0 ? EXIT_FAILURE : EXIT_SUCCESS;
|
||||
}
|
||||
diff --git a/src/shutdownd/shutdownd.c b/src/shutdownd/shutdownd.c
|
||||
index 92907497ed..99aa4b32b3 100644
|
||||
--- a/src/shutdownd/shutdownd.c
|
||||
+++ b/src/shutdownd/shutdownd.c
|
||||
@@ -456,6 +456,7 @@ finish:
|
||||
}
|
||||
|
||||
sd_notify(false,
|
||||
+ "STOPPING=\n"
|
||||
"STATUS=Exiting...");
|
||||
|
||||
return r;
|
||||
diff --git a/src/timesync/timesyncd.c b/src/timesync/timesyncd.c
|
||||
index 351bfd0236..ee3bc99ae0 100644
|
||||
--- a/src/timesync/timesyncd.c
|
||||
+++ b/src/timesync/timesyncd.c
|
||||
@@ -132,7 +132,9 @@ int main(int argc, char *argv[]) {
|
||||
log_warning("Failed to parse configuration file: %s", strerror(-r));
|
||||
|
||||
log_debug("systemd-timesyncd running as pid %lu", (unsigned long) getpid());
|
||||
- sd_notify(false, "READY=1");
|
||||
+ sd_notify(false,
|
||||
+ "READY=1\n"
|
||||
+ "STATUS=Daemon is running");
|
||||
|
||||
if (network_is_online()) {
|
||||
r = manager_connect(m);
|
||||
@@ -153,7 +155,9 @@ int main(int argc, char *argv[]) {
|
||||
sd_event_get_exit_code(m->event, &r);
|
||||
|
||||
finish:
|
||||
- sd_notify(false, "STATUS=Shutting down...");
|
||||
+ sd_notify(false,
|
||||
+ "STOPPING=1\n"
|
||||
+ "STATUS=Shutting down...");
|
||||
|
||||
return r < 0 ? EXIT_FAILURE : EXIT_SUCCESS;
|
||||
}
|
34
0025-update-TODO.patch
Normal file
34
0025-update-TODO.patch
Normal file
@ -0,0 +1,34 @@
|
||||
From 55cdcbacf70f05a40a155af24f6d2da6b478cba6 Mon Sep 17 00:00:00 2001
|
||||
From: Lennart Poettering <lennart@poettering.net>
|
||||
Date: Thu, 21 Aug 2014 17:20:00 +0200
|
||||
Subject: [PATCH] update TODO
|
||||
|
||||
---
|
||||
TODO | 7 +------
|
||||
1 file changed, 1 insertion(+), 6 deletions(-)
|
||||
|
||||
diff --git a/TODO b/TODO
|
||||
index cbd8384b4a..868518ab75 100644
|
||||
--- a/TODO
|
||||
+++ b/TODO
|
||||
@@ -38,9 +38,6 @@ Features:
|
||||
for "systemctl suspend" to finish to know when the suspending is
|
||||
complete.
|
||||
|
||||
-* sd_notify("SHUTDOWN=1") to fix a dbus activation race.
|
||||
- http://lists.freedesktop.org/archives/systemd-devel/2014-July/020983.html
|
||||
-
|
||||
* merge ~/.local/share and ~/.local/lib into one similar /usr/lib and /usr/share....
|
||||
|
||||
* make "systemctl suspend" block until we are back from suspend
|
||||
@@ -603,9 +600,7 @@ Features:
|
||||
|
||||
* make sure systemd-ask-password-wall does not shutdown systemd-ask-password-console too early
|
||||
|
||||
-* support sd_notify() style notification when reload begins (RELOADING=1), reload is finished (READY=1), and add ReloadSignal= then to use in combination
|
||||
-
|
||||
-* support sd_notify() style notification when shutting down, to make auto-exit bus services work (STOPPING=1)
|
||||
+* add ReloadSignal= for configuring a reload signal to use
|
||||
|
||||
* verify that the AF_UNIX sockets of a service in the fs still exist
|
||||
when we start a service in order to avoid confusion when a user
|
@ -0,0 +1,49 @@
|
||||
From 430e21c2f7e77d600257ead56419f511e48e854a Mon Sep 17 00:00:00 2001
|
||||
From: Lennart Poettering <lennart@poettering.net>
|
||||
Date: Thu, 21 Aug 2014 17:20:19 +0200
|
||||
Subject: [PATCH] bus: when terminating our bus-actviated services that
|
||||
exit-on-idle send STOPPING=1 via sd_notify()
|
||||
|
||||
This should fix a race where a service thatis idle drops its name, and
|
||||
is immediately requested by another client, which causes dbus-daemon to
|
||||
ask systemd to activate it again, but since systemd still assumes it is
|
||||
running it won't do anything.
|
||||
---
|
||||
src/libsystemd/sd-bus/bus-util.c | 16 ++++++++++++----
|
||||
1 file changed, 12 insertions(+), 4 deletions(-)
|
||||
|
||||
diff --git a/src/libsystemd/sd-bus/bus-util.c b/src/libsystemd/sd-bus/bus-util.c
|
||||
index 475ed34a53..c97bf7d99d 100644
|
||||
--- a/src/libsystemd/sd-bus/bus-util.c
|
||||
+++ b/src/libsystemd/sd-bus/bus-util.c
|
||||
@@ -22,6 +22,8 @@
|
||||
#include <sys/socket.h>
|
||||
#include <sys/capability.h>
|
||||
|
||||
+#include "systemd/sd-daemon.h"
|
||||
+
|
||||
#include "util.h"
|
||||
#include "strv.h"
|
||||
#include "macro.h"
|
||||
@@ -128,11 +130,17 @@ int bus_event_loop_with_idle(
|
||||
if (r == -EBUSY)
|
||||
continue;
|
||||
|
||||
+ /* Fallback for dbus1 connections: we
|
||||
+ * unregister the name and wait for the
|
||||
+ * response to come through for it */
|
||||
if (r == -ENOTSUP) {
|
||||
- /* Fallback for dbus1 connections: we
|
||||
- * unregister the name and wait for
|
||||
- * the response to come through for
|
||||
- * it */
|
||||
+
|
||||
+ /* Inform the service manager that we
|
||||
+ * are going down, so that it will
|
||||
+ * queue all further start requests,
|
||||
+ * instead of assuming we are already
|
||||
+ * running. */
|
||||
+ sd_notify(false, "STOPPING=1");
|
||||
|
||||
r = bus_async_unregister_and_exit(e, bus, name);
|
||||
if (r < 0)
|
@ -0,0 +1,25 @@
|
||||
From f461c8073dee9cd10bfae5ae3586e785ec8a5d07 Mon Sep 17 00:00:00 2001
|
||||
From: Lennart Poettering <lennart@poettering.net>
|
||||
Date: Thu, 21 Aug 2014 17:35:19 +0200
|
||||
Subject: [PATCH] execute: explain in a comment, why close_all_fds() is invoked
|
||||
the second time differently
|
||||
|
||||
---
|
||||
src/core/execute.c | 4 +++-
|
||||
1 file changed, 3 insertions(+), 1 deletion(-)
|
||||
|
||||
diff --git a/src/core/execute.c b/src/core/execute.c
|
||||
index 2544a2470c..b5b22472d5 100644
|
||||
--- a/src/core/execute.c
|
||||
+++ b/src/core/execute.c
|
||||
@@ -1635,7 +1635,9 @@ int exec_spawn(ExecCommand *command,
|
||||
}
|
||||
|
||||
/* We repeat the fd closing here, to make sure that
|
||||
- * nothing is leaked from the PAM modules */
|
||||
+ * nothing is leaked from the PAM modules. Note that
|
||||
+ * we are more aggressive this time since socket_fd
|
||||
+ * and the netns fds we don#t need anymore. */
|
||||
err = close_all_fds(fds, n_fds);
|
||||
if (err >= 0)
|
||||
err = shift_fds(fds, n_fds);
|
106
0028-service-use-the-right-timeout-for-stop-processes-we-.patch
Normal file
106
0028-service-use-the-right-timeout-for-stop-processes-we-.patch
Normal file
@ -0,0 +1,106 @@
|
||||
From 21b2ce39d4038cd6176394836fdcfb7fba63f424 Mon Sep 17 00:00:00 2001
|
||||
From: Lennart Poettering <lennart@poettering.net>
|
||||
Date: Thu, 21 Aug 2014 18:01:22 +0200
|
||||
Subject: [PATCH] service: use the right timeout for stop processes we fork
|
||||
|
||||
---
|
||||
src/core/service.c | 23 +++++++++++------------
|
||||
1 file changed, 11 insertions(+), 12 deletions(-)
|
||||
|
||||
diff --git a/src/core/service.c b/src/core/service.c
|
||||
index 3221938793..7d6ea73e05 100644
|
||||
--- a/src/core/service.c
|
||||
+++ b/src/core/service.c
|
||||
@@ -862,7 +862,7 @@ fail:
|
||||
static int service_spawn(
|
||||
Service *s,
|
||||
ExecCommand *c,
|
||||
- bool timeout,
|
||||
+ usec_t timeout,
|
||||
bool pass_fds,
|
||||
bool apply_permissions,
|
||||
bool apply_chroot,
|
||||
@@ -907,8 +907,8 @@ static int service_spawn(
|
||||
}
|
||||
}
|
||||
|
||||
- if (timeout && s->timeout_start_usec > 0) {
|
||||
- r = service_arm_timer(s, s->timeout_start_usec);
|
||||
+ if (timeout > 0) {
|
||||
+ r = service_arm_timer(s, timeout);
|
||||
if (r < 0)
|
||||
goto fail;
|
||||
} else
|
||||
@@ -1108,7 +1108,7 @@ static void service_enter_stop_post(Service *s, ServiceResult f) {
|
||||
|
||||
r = service_spawn(s,
|
||||
s->control_command,
|
||||
- true,
|
||||
+ s->timeout_stop_usec,
|
||||
false,
|
||||
!s->permissions_start_only,
|
||||
!s->root_directory_start_only,
|
||||
@@ -1207,7 +1207,7 @@ static void service_enter_stop(Service *s, ServiceResult f) {
|
||||
|
||||
r = service_spawn(s,
|
||||
s->control_command,
|
||||
- true,
|
||||
+ s->timeout_stop_usec,
|
||||
false,
|
||||
!s->permissions_start_only,
|
||||
!s->root_directory_start_only,
|
||||
@@ -1270,7 +1270,7 @@ static void service_enter_start_post(Service *s) {
|
||||
|
||||
r = service_spawn(s,
|
||||
s->control_command,
|
||||
- true,
|
||||
+ s->timeout_start_usec,
|
||||
false,
|
||||
!s->permissions_start_only,
|
||||
!s->root_directory_start_only,
|
||||
@@ -1334,8 +1334,7 @@ static void service_enter_start(Service *s) {
|
||||
|
||||
r = service_spawn(s,
|
||||
c,
|
||||
- s->type == SERVICE_FORKING || s->type == SERVICE_DBUS ||
|
||||
- s->type == SERVICE_NOTIFY || s->type == SERVICE_ONESHOT,
|
||||
+ IN_SET(s->type, SERVICE_FORKING, SERVICE_DBUS, SERVICE_NOTIFY, SERVICE_ONESHOT) ? s->timeout_start_usec : 0,
|
||||
true,
|
||||
true,
|
||||
true,
|
||||
@@ -1401,7 +1400,7 @@ static void service_enter_start_pre(Service *s) {
|
||||
|
||||
r = service_spawn(s,
|
||||
s->control_command,
|
||||
- true,
|
||||
+ s->timeout_start_usec,
|
||||
false,
|
||||
!s->permissions_start_only,
|
||||
!s->root_directory_start_only,
|
||||
@@ -1482,7 +1481,7 @@ static void service_enter_reload(Service *s) {
|
||||
|
||||
r = service_spawn(s,
|
||||
s->control_command,
|
||||
- true,
|
||||
+ s->timeout_start_usec,
|
||||
false,
|
||||
!s->permissions_start_only,
|
||||
!s->root_directory_start_only,
|
||||
@@ -1519,7 +1518,7 @@ static void service_run_next_control(Service *s) {
|
||||
|
||||
r = service_spawn(s,
|
||||
s->control_command,
|
||||
- true,
|
||||
+ IN_SET(s->state, SERVICE_START_PRE, SERVICE_START, SERVICE_START_POST, SERVICE_RUNNING, SERVICE_RELOAD) ? s->timeout_start_usec : s->timeout_stop_usec,
|
||||
false,
|
||||
!s->permissions_start_only,
|
||||
!s->root_directory_start_only,
|
||||
@@ -1563,7 +1562,7 @@ static void service_run_next_main(Service *s) {
|
||||
|
||||
r = service_spawn(s,
|
||||
s->main_command,
|
||||
- true,
|
||||
+ s->timeout_start_usec,
|
||||
true,
|
||||
true,
|
||||
true,
|
22
0029-update-TODO.patch
Normal file
22
0029-update-TODO.patch
Normal file
@ -0,0 +1,22 @@
|
||||
From 1954ea346dc28226c0fffde848d49a297165b0a9 Mon Sep 17 00:00:00 2001
|
||||
From: Lennart Poettering <lennart@poettering.net>
|
||||
Date: Thu, 21 Aug 2014 18:01:47 +0200
|
||||
Subject: [PATCH] update TODO
|
||||
|
||||
---
|
||||
TODO | 2 --
|
||||
1 file changed, 2 deletions(-)
|
||||
|
||||
diff --git a/TODO b/TODO
|
||||
index 868518ab75..16b61d045c 100644
|
||||
--- a/TODO
|
||||
+++ b/TODO
|
||||
@@ -40,8 +40,6 @@ Features:
|
||||
|
||||
* merge ~/.local/share and ~/.local/lib into one similar /usr/lib and /usr/share....
|
||||
|
||||
-* make "systemctl suspend" block until we are back from suspend
|
||||
-
|
||||
* remove readahead in 217
|
||||
|
||||
* journald: allows specification of UID range for splitting up journal files
|
166
0030-service-allow-services-of-Type-oneshot-that-specify-.patch
Normal file
166
0030-service-allow-services-of-Type-oneshot-that-specify-.patch
Normal file
@ -0,0 +1,166 @@
|
||||
From 96fb8242cc1ef6b0e28f6c86a4f57950095dd7f1 Mon Sep 17 00:00:00 2001
|
||||
From: Lennart Poettering <lennart@poettering.net>
|
||||
Date: Thu, 21 Aug 2014 18:50:42 +0200
|
||||
Subject: [PATCH] service: allow services of Type=oneshot that specify no
|
||||
ExecStart= commands
|
||||
|
||||
This is useful for services that simply want to run something on
|
||||
shutdown, but not at bootup. They should only set ExecStop= but leave
|
||||
ExecStart= unset.
|
||||
---
|
||||
man/systemd.service.xml | 44 +++++++++++++++++++++++++++-----------------
|
||||
src/core/service.c | 39 +++++++++++++++++++++++++++++----------
|
||||
2 files changed, 56 insertions(+), 27 deletions(-)
|
||||
|
||||
diff --git a/man/systemd.service.xml b/man/systemd.service.xml
|
||||
index 5c4bd6569f..e584a1f006 100644
|
||||
--- a/man/systemd.service.xml
|
||||
+++ b/man/systemd.service.xml
|
||||
@@ -139,9 +139,10 @@
|
||||
|
||||
<para>If set to
|
||||
<option>simple</option> (the default
|
||||
- value if neither
|
||||
+ if neither
|
||||
<varname>Type=</varname> nor
|
||||
- <varname>BusName=</varname> are
|
||||
+ <varname>BusName=</varname>, but
|
||||
+ <varname>ExecStart=</varname> are
|
||||
specified), it is expected that the
|
||||
process configured with
|
||||
<varname>ExecStart=</varname> is the
|
||||
@@ -177,13 +178,17 @@
|
||||
exits.</para>
|
||||
|
||||
<para>Behavior of
|
||||
- <option>oneshot</option> is similar
|
||||
- to <option>simple</option>; however,
|
||||
- it is expected that the process has to
|
||||
+ <option>oneshot</option> is similar to
|
||||
+ <option>simple</option>; however, it
|
||||
+ is expected that the process has to
|
||||
exit before systemd starts follow-up
|
||||
units. <varname>RemainAfterExit=</varname>
|
||||
is particularly useful for this type
|
||||
- of service.</para>
|
||||
+ of service. This is the implied
|
||||
+ default if neither
|
||||
+ <varname>Type=</varname> or
|
||||
+ <varname>ExecStart=</varname> are
|
||||
+ specified.</para>
|
||||
|
||||
<para>Behavior of
|
||||
<option>dbus</option> is similar to
|
||||
@@ -313,22 +318,27 @@
|
||||
|
||||
<para>When <varname>Type</varname> is
|
||||
not <option>oneshot</option>, only one
|
||||
- command may be given. When
|
||||
+ command may and must be given. When
|
||||
<varname>Type=oneshot</varname> is
|
||||
- used, more than one command may be
|
||||
- specified. Multiple command lines may
|
||||
- be concatenated in a single directive
|
||||
- by separating them with semicolons
|
||||
- (these semicolons must be passed as
|
||||
- separate words). Alternatively, this
|
||||
- directive may be specified more than
|
||||
- once with the same effect.
|
||||
- Lone semicolons may be escaped as
|
||||
+ used, none or more than one command
|
||||
+ may be specified. Multiple command
|
||||
+ lines may be concatenated in a single
|
||||
+ directive by separating them with
|
||||
+ semicolons (these semicolons must be
|
||||
+ passed as separate
|
||||
+ words). Alternatively, this directive
|
||||
+ may be specified more than once with
|
||||
+ the same effect. Lone semicolons may
|
||||
+ be escaped as
|
||||
<literal>\;</literal>. If the empty
|
||||
string is assigned to this option, the
|
||||
list of commands to start is reset,
|
||||
prior assignments of this option will
|
||||
- have no effect.</para>
|
||||
+ have no effect. If no
|
||||
+ <varname>ExecStart=</varname> is
|
||||
+ specified, then the service must have
|
||||
+ <varname>RemainAfterExit=yes</varname>
|
||||
+ set.</para>
|
||||
|
||||
<para>Each command line is split on
|
||||
whitespace, with the first item being
|
||||
diff --git a/src/core/service.c b/src/core/service.c
|
||||
index 7d6ea73e05..1b864c4c8c 100644
|
||||
--- a/src/core/service.c
|
||||
+++ b/src/core/service.c
|
||||
@@ -313,14 +313,23 @@ static int service_verify(Service *s) {
|
||||
if (UNIT(s)->load_state != UNIT_LOADED)
|
||||
return 0;
|
||||
|
||||
- if (!s->exec_command[SERVICE_EXEC_START]) {
|
||||
- log_error_unit(UNIT(s)->id, "%s lacks ExecStart setting. Refusing.", UNIT(s)->id);
|
||||
+ if (!s->exec_command[SERVICE_EXEC_START] && !s->exec_command[SERVICE_EXEC_STOP]) {
|
||||
+ log_error_unit(UNIT(s)->id, "%s lacks both ExecStart= and ExecStop= setting. Refusing.", UNIT(s)->id);
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
- if (s->type != SERVICE_ONESHOT &&
|
||||
- s->exec_command[SERVICE_EXEC_START]->command_next) {
|
||||
- log_error_unit(UNIT(s)->id, "%s has more than one ExecStart setting, which is only allowed for Type=oneshot services. Refusing.", UNIT(s)->id);
|
||||
+ if (s->type != SERVICE_ONESHOT && !s->exec_command[SERVICE_EXEC_START]) {
|
||||
+ log_error_unit(UNIT(s)->id, "%s has no ExecStart= setting, which is only allowed for Type=oneshot services. Refusing.", UNIT(s)->id);
|
||||
+ return -EINVAL;
|
||||
+ }
|
||||
+
|
||||
+ if (!s->remain_after_exit && !s->exec_command[SERVICE_EXEC_START]) {
|
||||
+ log_error_unit(UNIT(s)->id, "%s has no ExecStart= setting, which is only allowed for RemainAfterExit=yes services. Refusing.", UNIT(s)->id);
|
||||
+ return -EINVAL;
|
||||
+ }
|
||||
+
|
||||
+ if (s->type != SERVICE_ONESHOT && s->exec_command[SERVICE_EXEC_START]->command_next) {
|
||||
+ log_error_unit(UNIT(s)->id, "%s has more than one ExecStart= setting, which is only allowed for Type=oneshot services. Refusing.", UNIT(s)->id);
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
@@ -410,8 +419,15 @@ static int service_load(Unit *u) {
|
||||
if (r < 0)
|
||||
return r;
|
||||
|
||||
- if (s->type == _SERVICE_TYPE_INVALID)
|
||||
- s->type = s->bus_name ? SERVICE_DBUS : SERVICE_SIMPLE;
|
||||
+ if (s->type == _SERVICE_TYPE_INVALID) {
|
||||
+ /* Figure out a type automatically */
|
||||
+ if (s->bus_name)
|
||||
+ s->type = SERVICE_DBUS;
|
||||
+ else if (s->exec_command[SERVICE_EXEC_START])
|
||||
+ s->type = SERVICE_SIMPLE;
|
||||
+ else
|
||||
+ s->type = SERVICE_ONESHOT;
|
||||
+ }
|
||||
|
||||
/* Oneshot services have disabled start timeout by default */
|
||||
if (s->type == SERVICE_ONESHOT && !s->start_timeout_defined)
|
||||
@@ -1309,9 +1325,6 @@ static void service_enter_start(Service *s) {
|
||||
|
||||
assert(s);
|
||||
|
||||
- assert(s->exec_command[SERVICE_EXEC_START]);
|
||||
- assert(!s->exec_command[SERVICE_EXEC_START]->command_next || s->type == SERVICE_ONESHOT);
|
||||
-
|
||||
service_unwatch_control_pid(s);
|
||||
service_unwatch_main_pid(s);
|
||||
|
||||
@@ -1332,6 +1345,12 @@ static void service_enter_start(Service *s) {
|
||||
c = s->main_command = s->exec_command[SERVICE_EXEC_START];
|
||||
}
|
||||
|
||||
+ if (!c) {
|
||||
+ assert(s->type == SERVICE_ONESHOT);
|
||||
+ service_enter_start_post(s);
|
||||
+ return;
|
||||
+ }
|
||||
+
|
||||
r = service_spawn(s,
|
||||
c,
|
||||
IN_SET(s->type, SERVICE_FORKING, SERVICE_DBUS, SERVICE_NOTIFY, SERVICE_ONESHOT) ? s->timeout_start_usec : 0,
|
126
0031-install-simplify-usage-of-_cleanup_-macros.patch
Normal file
126
0031-install-simplify-usage-of-_cleanup_-macros.patch
Normal file
@ -0,0 +1,126 @@
|
||||
From 59ccf93d97f0a37522e5f4fbf5cc0288dbedf495 Mon Sep 17 00:00:00 2001
|
||||
From: Lennart Poettering <lennart@poettering.net>
|
||||
Date: Thu, 21 Aug 2014 19:08:30 +0200
|
||||
Subject: [PATCH] install: simplify usage of _cleanup_ macros
|
||||
|
||||
---
|
||||
src/shared/install.c | 27 +++++++++++++--------------
|
||||
src/shared/path-lookup.h | 4 ++--
|
||||
2 files changed, 15 insertions(+), 16 deletions(-)
|
||||
|
||||
diff --git a/src/shared/install.c b/src/shared/install.c
|
||||
index 03c7a9da2e..4b09a69456 100644
|
||||
--- a/src/shared/install.c
|
||||
+++ b/src/shared/install.c
|
||||
@@ -45,8 +45,6 @@ typedef struct {
|
||||
Hashmap *have_installed;
|
||||
} InstallContext;
|
||||
|
||||
-#define _cleanup_install_context_done_ _cleanup_(install_context_done)
|
||||
-
|
||||
static int in_search_path(const char *path, char **search) {
|
||||
_cleanup_free_ char *parent = NULL;
|
||||
int r;
|
||||
@@ -1161,7 +1159,7 @@ static int unit_file_can_install(
|
||||
const char *name,
|
||||
bool allow_symlink) {
|
||||
|
||||
- _cleanup_install_context_done_ InstallContext c = {};
|
||||
+ _cleanup_(install_context_done) InstallContext c = {};
|
||||
InstallInfo *i;
|
||||
int r;
|
||||
|
||||
@@ -1498,7 +1496,7 @@ int unit_file_enable(
|
||||
unsigned *n_changes) {
|
||||
|
||||
_cleanup_lookup_paths_free_ LookupPaths paths = {};
|
||||
- _cleanup_install_context_done_ InstallContext c = {};
|
||||
+ _cleanup_(install_context_done) InstallContext c = {};
|
||||
char **i;
|
||||
_cleanup_free_ char *config_path = NULL;
|
||||
int r;
|
||||
@@ -1537,7 +1535,7 @@ int unit_file_disable(
|
||||
unsigned *n_changes) {
|
||||
|
||||
_cleanup_lookup_paths_free_ LookupPaths paths = {};
|
||||
- _cleanup_install_context_done_ InstallContext c = {};
|
||||
+ _cleanup_(install_context_done) InstallContext c = {};
|
||||
char **i;
|
||||
_cleanup_free_ char *config_path = NULL;
|
||||
_cleanup_set_free_free_ Set *remove_symlinks_to = NULL;
|
||||
@@ -1597,7 +1595,7 @@ int unit_file_set_default(
|
||||
unsigned *n_changes) {
|
||||
|
||||
_cleanup_lookup_paths_free_ LookupPaths paths = {};
|
||||
- _cleanup_install_context_done_ InstallContext c = {};
|
||||
+ _cleanup_(install_context_done) InstallContext c = {};
|
||||
_cleanup_free_ char *config_path = NULL;
|
||||
char *path;
|
||||
int r;
|
||||
@@ -1859,7 +1857,7 @@ int unit_file_preset(
|
||||
UnitFileChange **changes,
|
||||
unsigned *n_changes) {
|
||||
|
||||
- _cleanup_install_context_done_ InstallContext plus = {}, minus = {};
|
||||
+ _cleanup_(install_context_done) InstallContext plus = {}, minus = {};
|
||||
_cleanup_lookup_paths_free_ LookupPaths paths = {};
|
||||
_cleanup_free_ char *config_path = NULL;
|
||||
char **i;
|
||||
@@ -1927,7 +1925,7 @@ int unit_file_preset_all(
|
||||
UnitFileChange **changes,
|
||||
unsigned *n_changes) {
|
||||
|
||||
- _cleanup_install_context_done_ InstallContext plus = {}, minus = {};
|
||||
+ _cleanup_(install_context_done) InstallContext plus = {}, minus = {};
|
||||
_cleanup_lookup_paths_free_ LookupPaths paths = {};
|
||||
_cleanup_free_ char *config_path = NULL;
|
||||
char **i;
|
||||
@@ -2019,14 +2017,15 @@ int unit_file_preset_all(
|
||||
return r;
|
||||
}
|
||||
|
||||
-static void unitfilelist_free(UnitFileList **f) {
|
||||
- if (!*f)
|
||||
+static void unit_file_list_free_one(UnitFileList *f) {
|
||||
+ if (!f)
|
||||
return;
|
||||
|
||||
- free((*f)->path);
|
||||
- free(*f);
|
||||
+ free(f->path);
|
||||
+ free(f);
|
||||
}
|
||||
-#define _cleanup_unitfilelist_free_ _cleanup_(unitfilelist_free)
|
||||
+
|
||||
+DEFINE_TRIVIAL_CLEANUP_FUNC(UnitFileList*, unit_file_list_free_one);
|
||||
|
||||
int unit_file_get_list(
|
||||
UnitFileScope scope,
|
||||
@@ -2071,7 +2070,7 @@ int unit_file_get_list(
|
||||
}
|
||||
|
||||
for (;;) {
|
||||
- _cleanup_unitfilelist_free_ UnitFileList *f = NULL;
|
||||
+ _cleanup_(unit_file_list_free_onep) UnitFileList *f = NULL;
|
||||
struct dirent *de;
|
||||
|
||||
errno = 0;
|
||||
diff --git a/src/shared/path-lookup.h b/src/shared/path-lookup.h
|
||||
index 2fe8173f44..4bbd47ec39 100644
|
||||
--- a/src/shared/path-lookup.h
|
||||
+++ b/src/shared/path-lookup.h
|
||||
@@ -38,8 +38,6 @@ typedef enum SystemdRunningAs {
|
||||
_SYSTEMD_RUNNING_AS_INVALID = -1
|
||||
} SystemdRunningAs;
|
||||
|
||||
-#define _cleanup_lookup_paths_free_ _cleanup_(lookup_paths_free)
|
||||
-
|
||||
int user_config_home(char **config_home);
|
||||
|
||||
int lookup_paths_init(LookupPaths *p,
|
||||
@@ -50,3 +48,5 @@ int lookup_paths_init(LookupPaths *p,
|
||||
const char *generator_early,
|
||||
const char *generator_late);
|
||||
void lookup_paths_free(LookupPaths *p);
|
||||
+
|
||||
+#define _cleanup_lookup_paths_free_ _cleanup_(lookup_paths_free)
|
@ -0,0 +1,46 @@
|
||||
From 4fe1be9ce2e0cca6354a4167f0a1a7e1f943c91c Mon Sep 17 00:00:00 2001
|
||||
From: Lennart Poettering <lennart@poettering.net>
|
||||
Date: Thu, 21 Aug 2014 19:10:26 +0200
|
||||
Subject: [PATCH] systemctl: in list-unit-files, always show legend, even if we
|
||||
know about no unit files
|
||||
|
||||
---
|
||||
src/systemctl/systemctl.c | 14 +++++---------
|
||||
1 file changed, 5 insertions(+), 9 deletions(-)
|
||||
|
||||
diff --git a/src/systemctl/systemctl.c b/src/systemctl/systemctl.c
|
||||
index 072f615ad5..d9b8bee28d 100644
|
||||
--- a/src/systemctl/systemctl.c
|
||||
+++ b/src/systemctl/systemctl.c
|
||||
@@ -1351,11 +1351,8 @@ static int list_unit_files(sd_bus *bus, char **args) {
|
||||
|
||||
n_units = hashmap_size(h);
|
||||
|
||||
- if (n_units == 0)
|
||||
- return 0;
|
||||
-
|
||||
units = new(UnitFileList, n_units);
|
||||
- if (!units) {
|
||||
+ if (!units && n_units > 0) {
|
||||
unit_file_list_free(h);
|
||||
return log_oom();
|
||||
}
|
||||
@@ -1411,14 +1408,13 @@ static int list_unit_files(sd_bus *bus, char **args) {
|
||||
return bus_log_parse_error(r);
|
||||
}
|
||||
|
||||
- if (c > 0) {
|
||||
- qsort(units, c, sizeof(UnitFileList), compare_unit_file_list);
|
||||
- output_unit_file_list(units, c);
|
||||
- }
|
||||
+ qsort_safe(units, c, sizeof(UnitFileList), compare_unit_file_list);
|
||||
+ output_unit_file_list(units, c);
|
||||
|
||||
- if (avoid_bus())
|
||||
+ if (avoid_bus()) {
|
||||
for (unit = units; unit < units + c; unit++)
|
||||
free(unit->path);
|
||||
+ }
|
||||
|
||||
return 0;
|
||||
}
|
24
0033-update-TODO.patch
Normal file
24
0033-update-TODO.patch
Normal file
@ -0,0 +1,24 @@
|
||||
From 337ce7442a0602116c6253ebf202bd34f675f627 Mon Sep 17 00:00:00 2001
|
||||
From: Lennart Poettering <lennart@poettering.net>
|
||||
Date: Thu, 21 Aug 2014 19:12:43 +0200
|
||||
Subject: [PATCH] update TODO
|
||||
|
||||
---
|
||||
TODO | 4 ----
|
||||
1 file changed, 4 deletions(-)
|
||||
|
||||
diff --git a/TODO b/TODO
|
||||
index 16b61d045c..3073f3a5a2 100644
|
||||
--- a/TODO
|
||||
+++ b/TODO
|
||||
@@ -521,10 +521,6 @@ Features:
|
||||
|
||||
* properly handle loop back mounts via fstab, especially regards to fsck/passno
|
||||
|
||||
-* allow services with no ExecStart= but with an ExecStop=
|
||||
-
|
||||
-* dracut-shutdown needs to be ordered before unmounting /boot
|
||||
-
|
||||
* initialize the hostname from the fs label of /, if /etc/hostname does not exist?
|
||||
|
||||
* rename "userspace" to "core-os"
|
59
0034-dbus1-generator-properly-free-the-FILE.patch
Normal file
59
0034-dbus1-generator-properly-free-the-FILE.patch
Normal file
@ -0,0 +1,59 @@
|
||||
From 0975b63fb31263e535a2d26ed41e66e23f468bc5 Mon Sep 17 00:00:00 2001
|
||||
From: Lennart Poettering <lennart@poettering.net>
|
||||
Date: Fri, 22 Aug 2014 12:44:17 +0200
|
||||
Subject: [PATCH] dbus1-generator: properly free the FILE*
|
||||
|
||||
Also, rework the code to make use of fflush_and_check().
|
||||
|
||||
Issue discovered by Simon Danner.
|
||||
---
|
||||
src/dbus1-generator/dbus1-generator.c | 20 ++++++++++++--------
|
||||
1 file changed, 12 insertions(+), 8 deletions(-)
|
||||
|
||||
diff --git a/src/dbus1-generator/dbus1-generator.c b/src/dbus1-generator/dbus1-generator.c
|
||||
index e1ffc5515f..3c4522b589 100644
|
||||
--- a/src/dbus1-generator/dbus1-generator.c
|
||||
+++ b/src/dbus1-generator/dbus1-generator.c
|
||||
@@ -40,6 +40,7 @@ static int create_dbus_files(
|
||||
|
||||
_cleanup_free_ char *b = NULL, *s = NULL, *lnk = NULL;
|
||||
_cleanup_fclose_ FILE *f = NULL;
|
||||
+ int r;
|
||||
|
||||
assert(path);
|
||||
assert(name);
|
||||
@@ -100,12 +101,15 @@ static int create_dbus_files(
|
||||
}
|
||||
}
|
||||
|
||||
- fflush(f);
|
||||
- if (ferror(f)) {
|
||||
- log_error("Failed to write %s: %m", a);
|
||||
- return -errno;
|
||||
+ r = fflush_and_check(f);
|
||||
+ if (r < 0) {
|
||||
+ log_error("Failed to write %s: %s", a, strerror(-r));
|
||||
+ return r;
|
||||
}
|
||||
|
||||
+ fclose(f);
|
||||
+ f = NULL;
|
||||
+
|
||||
service = s;
|
||||
}
|
||||
|
||||
@@ -134,10 +138,10 @@ static int create_dbus_files(
|
||||
name,
|
||||
service);
|
||||
|
||||
- fflush(f);
|
||||
- if (ferror(f)) {
|
||||
- log_error("Failed to write %s: %m", b);
|
||||
- return -errno;
|
||||
+ r = fflush_and_check(f);
|
||||
+ if (r < 0) {
|
||||
+ log_error("Failed to write %s: %s", b, strerror(-r));
|
||||
+ return r;
|
||||
}
|
||||
|
||||
lnk = strjoin(arg_dest_late, "/" SPECIAL_BUSNAMES_TARGET ".wants/", name, ".busname", NULL);
|
75
0035-shared-add-MAXSIZE-and-use-it-in-resolved.patch
Normal file
75
0035-shared-add-MAXSIZE-and-use-it-in-resolved.patch
Normal file
@ -0,0 +1,75 @@
|
||||
From 40a1eebde6be7ac3f1885147fc24e06ad1da260c Mon Sep 17 00:00:00 2001
|
||||
From: David Herrmann <dh.herrmann@gmail.com>
|
||||
Date: Fri, 22 Aug 2014 13:55:57 +0200
|
||||
Subject: [PATCH] shared: add MAXSIZE() and use it in resolved
|
||||
|
||||
The MAXSIZE() macro takes two types and returns the size of the larger
|
||||
one. It is much simpler to use than MAX(sizeof(A), sizeof(B)) and also
|
||||
avoids any compiler-extensions, unlike CONST_MAX() and MAX() (which are
|
||||
needed to avoid evaluating arguments more than once). This was suggested
|
||||
by Daniele Nicolodi <daniele@grinta.net>.
|
||||
|
||||
Also make resolved use this macro instead of CONST_MAX(). This enhances
|
||||
readability quite a bit.
|
||||
---
|
||||
src/resolve/resolved-dns-stream.c | 2 +-
|
||||
src/resolve/resolved-manager.c | 2 +-
|
||||
src/shared/macro.h | 3 +++
|
||||
src/test/test-util.c | 4 ++++
|
||||
4 files changed, 9 insertions(+), 2 deletions(-)
|
||||
|
||||
diff --git a/src/resolve/resolved-dns-stream.c b/src/resolve/resolved-dns-stream.c
|
||||
index 8b3a3ced4b..8aad5e4df1 100644
|
||||
--- a/src/resolve/resolved-dns-stream.c
|
||||
+++ b/src/resolve/resolved-dns-stream.c
|
||||
@@ -64,7 +64,7 @@ static int dns_stream_complete(DnsStream *s, int error) {
|
||||
static int dns_stream_identify(DnsStream *s) {
|
||||
union {
|
||||
struct cmsghdr header; /* For alignment */
|
||||
- uint8_t buffer[CMSG_SPACE(CONST_MAX(sizeof(struct in_pktinfo), sizeof(struct in6_pktinfo)))
|
||||
+ uint8_t buffer[CMSG_SPACE(MAXSIZE(struct in_pktinfo, struct in6_pktinfo))
|
||||
+ EXTRA_CMSG_SPACE /* kernel appears to require extra space */];
|
||||
} control;
|
||||
struct msghdr mh = {};
|
||||
diff --git a/src/resolve/resolved-manager.c b/src/resolve/resolved-manager.c
|
||||
index 56baf8730d..659b1dacc8 100644
|
||||
--- a/src/resolve/resolved-manager.c
|
||||
+++ b/src/resolve/resolved-manager.c
|
||||
@@ -841,7 +841,7 @@ int manager_recv(Manager *m, int fd, DnsProtocol protocol, DnsPacket **ret) {
|
||||
_cleanup_(dns_packet_unrefp) DnsPacket *p = NULL;
|
||||
union {
|
||||
struct cmsghdr header; /* For alignment */
|
||||
- uint8_t buffer[CMSG_SPACE(CONST_MAX(sizeof(struct in_pktinfo), sizeof(struct in6_pktinfo)))
|
||||
+ uint8_t buffer[CMSG_SPACE(MAXSIZE(struct in_pktinfo, struct in6_pktinfo))
|
||||
+ CMSG_SPACE(int) /* ttl/hoplimit */
|
||||
+ EXTRA_CMSG_SPACE /* kernel appears to require extra buffer space */];
|
||||
} control;
|
||||
diff --git a/src/shared/macro.h b/src/shared/macro.h
|
||||
index 179b24c983..43fa3e556f 100644
|
||||
--- a/src/shared/macro.h
|
||||
+++ b/src/shared/macro.h
|
||||
@@ -149,6 +149,9 @@ static inline unsigned long ALIGN_POWER2(unsigned long u) {
|
||||
((_A) > (_B)) ? (_A) : (_B), \
|
||||
(void)0))
|
||||
|
||||
+/* takes two types and returns the size of the larger one */
|
||||
+#define MAXSIZE(A, B) (sizeof(union _packed_ { typeof(A) a; typeof(B) b; }))
|
||||
+
|
||||
#define MAX3(x,y,z) \
|
||||
__extension__ ({ \
|
||||
const typeof(x) _c = MAX(x,y); \
|
||||
diff --git a/src/test/test-util.c b/src/test/test-util.c
|
||||
index ac1afce86b..34d5f2ed7d 100644
|
||||
--- a/src/test/test-util.c
|
||||
+++ b/src/test/test-util.c
|
||||
@@ -90,6 +90,10 @@ static void test_max(void) {
|
||||
assert_se(val1.a == 100);
|
||||
assert_se(MAX(++d, 0) == 1);
|
||||
assert_se(d == 1);
|
||||
+
|
||||
+ assert_cc(MAXSIZE(char[3], uint16_t) == 3);
|
||||
+ assert_cc(MAXSIZE(char[3], uint32_t) == 4);
|
||||
+ assert_cc(MAXSIZE(char, long) == sizeof(long));
|
||||
}
|
||||
|
||||
static void test_first_word(void) {
|
25
0036-missing.h-add-fake-__NR_memfd_create-for-MIPS.patch
Normal file
25
0036-missing.h-add-fake-__NR_memfd_create-for-MIPS.patch
Normal file
@ -0,0 +1,25 @@
|
||||
From a7d611f280b3eadafd6b411b659a321b4d6e63f4 Mon Sep 17 00:00:00 2001
|
||||
From: Daniel Mack <zonque@gmail.com>
|
||||
Date: Fri, 22 Aug 2014 15:39:36 +0200
|
||||
Subject: [PATCH] missing.h: add fake __NR_memfd_create for MIPS
|
||||
|
||||
We don't have the correct __NR_memfd_create syscall number yet, so set it to
|
||||
0xffffffff for now to prevent compile time errors.
|
||||
---
|
||||
src/shared/missing.h | 3 +++
|
||||
1 file changed, 3 insertions(+)
|
||||
|
||||
diff --git a/src/shared/missing.h b/src/shared/missing.h
|
||||
index 3ff1a21720..3051cb5640 100644
|
||||
--- a/src/shared/missing.h
|
||||
+++ b/src/shared/missing.h
|
||||
@@ -167,6 +167,9 @@ static inline int pivot_root(const char *new_root, const char *put_old) {
|
||||
# define __NR_fanotify_mark 5296
|
||||
# endif
|
||||
# endif
|
||||
+# ifndef __NR_memfd_create
|
||||
+# define __NR_memfd_create 0xffffffff /* FIXME */
|
||||
+# endif
|
||||
#else
|
||||
# ifndef __NR_fanotify_init
|
||||
# define __NR_fanotify_init 338
|
@ -0,0 +1,23 @@
|
||||
From 2de1851fe3611c59abf77127c6b5bc1b91eb7cba Mon Sep 17 00:00:00 2001
|
||||
From: Daniel Mack <zonque@gmail.com>
|
||||
Date: Fri, 22 Aug 2014 16:10:02 +0200
|
||||
Subject: [PATCH] missing.h: add a cpp warning for __NR_memfd_create on MIPS
|
||||
|
||||
---
|
||||
src/shared/missing.h | 3 ++-
|
||||
1 file changed, 2 insertions(+), 1 deletion(-)
|
||||
|
||||
diff --git a/src/shared/missing.h b/src/shared/missing.h
|
||||
index 3051cb5640..a9dd274274 100644
|
||||
--- a/src/shared/missing.h
|
||||
+++ b/src/shared/missing.h
|
||||
@@ -168,7 +168,8 @@ static inline int pivot_root(const char *new_root, const char *put_old) {
|
||||
# endif
|
||||
# endif
|
||||
# ifndef __NR_memfd_create
|
||||
-# define __NR_memfd_create 0xffffffff /* FIXME */
|
||||
+# warning "__NR_memfd_create not yet defined for MIPS"
|
||||
+# define __NR_memfd_create 0xffffffff
|
||||
# endif
|
||||
#else
|
||||
# ifndef __NR_fanotify_init
|
704
0038-core-add-support-for-a-configurable-system-wide-star.patch
Normal file
704
0038-core-add-support-for-a-configurable-system-wide-star.patch
Normal file
@ -0,0 +1,704 @@
|
||||
From 2928b0a863091f8f291fddb168988711afd389ef Mon Sep 17 00:00:00 2001
|
||||
From: Lennart Poettering <lennart@poettering.net>
|
||||
Date: Fri, 22 Aug 2014 16:36:38 +0200
|
||||
Subject: [PATCH] core: add support for a configurable system-wide start-up
|
||||
timeout
|
||||
|
||||
When this system-wide start-up timeout is hit we execute one of the
|
||||
failure actions already implemented for services that fail.
|
||||
|
||||
This should not only be useful on embedded devices, but also on laptops
|
||||
which have the power-button reachable when the lid is closed. This
|
||||
devices, when in a backpack might get powered on by accident due to the
|
||||
easily reachable power button. We want to make sure that the system
|
||||
turns itself off if it starts up due this after a while.
|
||||
|
||||
When the system manages to fully start-up logind will suspend the
|
||||
machine by default if the lid is closed. However, in some cases we don't
|
||||
even get as far as logind, and the boot hangs much earlier, for example
|
||||
because we ask for a LUKS password that nobody ever enters.
|
||||
|
||||
Yeah, this is a real-life problem on my Yoga 13, which has one of those
|
||||
easily accessible power buttons, even if the device is closed.
|
||||
---
|
||||
Makefile.am | 4 +-
|
||||
man/systemd-system.conf.xml | 27 ++++++++++++-
|
||||
man/systemd.service.xml | 23 +++++------
|
||||
src/core/failure-action.c | 94 +++++++++++++++++++++++++++++++++++++++++++++
|
||||
src/core/failure-action.h | 40 +++++++++++++++++++
|
||||
src/core/main.c | 13 +++++++
|
||||
src/core/manager.c | 43 +++++++++++++++++++--
|
||||
src/core/manager.h | 10 +++++
|
||||
src/core/service.c | 77 ++++---------------------------------
|
||||
src/core/service.h | 16 +-------
|
||||
src/core/system.conf | 3 ++
|
||||
src/shared/util.c | 21 ++++++++++
|
||||
src/shared/util.h | 2 +
|
||||
src/test/test-tables.c | 2 +-
|
||||
14 files changed, 273 insertions(+), 102 deletions(-)
|
||||
create mode 100644 src/core/failure-action.c
|
||||
create mode 100644 src/core/failure-action.h
|
||||
|
||||
diff --git a/Makefile.am b/Makefile.am
|
||||
index 4028112a62..cbf98bdac3 100644
|
||||
--- a/Makefile.am
|
||||
+++ b/Makefile.am
|
||||
@@ -1112,7 +1112,9 @@ libsystemd_core_la_SOURCES = \
|
||||
src/core/audit-fd.c \
|
||||
src/core/audit-fd.h \
|
||||
src/core/show-status.c \
|
||||
- src/core/show-status.h
|
||||
+ src/core/show-status.h \
|
||||
+ src/core/failure-action.c \
|
||||
+ src/core/failure-action.h
|
||||
|
||||
if HAVE_KMOD
|
||||
libsystemd_core_la_SOURCES += \
|
||||
diff --git a/man/systemd-system.conf.xml b/man/systemd-system.conf.xml
|
||||
index 6105c5131c..48690024f4 100644
|
||||
--- a/man/systemd-system.conf.xml
|
||||
+++ b/man/systemd-system.conf.xml
|
||||
@@ -254,7 +254,6 @@
|
||||
signal.</para></listitem>
|
||||
</varlistentry>
|
||||
|
||||
-
|
||||
<varlistentry>
|
||||
<term><varname>TimerSlackNSec=</varname></term>
|
||||
|
||||
@@ -281,6 +280,32 @@
|
||||
</varlistentry>
|
||||
|
||||
<varlistentry>
|
||||
+ <term><varname>StartTimeoutSec=</varname></term>
|
||||
+ <term><varname>StartTimeoutAction=</varname></term>
|
||||
+ <term><varname>StartTimeoutRebootArgument=</varname></term>
|
||||
+
|
||||
+ <listitem><para>Configures an over-all
|
||||
+ system start-up timeout and controls
|
||||
+ what to do when the timeout is
|
||||
+ reached. <varname>StartTimeoutSec=</varname>
|
||||
+ specifies the timeout, and defaults to
|
||||
+ <literal>15min</literal>. <varname>StartTimeoutAction=</varname>
|
||||
+ configures the action to take when the
|
||||
+ system did not finish boot-up within
|
||||
+ the specified time. It takes the same
|
||||
+ values as the per-service
|
||||
+ <varname>StartLimitAction=</varname>
|
||||
+ setting, see
|
||||
+ <citerefentry><refentrytitle>systemd.service</refentrytitle><manvolnum>5</manvolnum></citerefentry>
|
||||
+ for details. Defaults to
|
||||
+ <option>reboot-force</option>. <varname>StartTimeoutRebootArgument=</varname>
|
||||
+ configures an optional reboot string
|
||||
+ to pass to the
|
||||
+ <citerefentry><refentrytitle>reboot</refentrytitle><manvolnum>2</manvolnum></citerefentry>
|
||||
+ system call.</para></listitem>
|
||||
+ </varlistentry>
|
||||
+
|
||||
+ <varlistentry>
|
||||
<term><varname>DefaultTimerAccuracySec=</varname></term>
|
||||
|
||||
<listitem><para>Sets the default
|
||||
diff --git a/man/systemd.service.xml b/man/systemd.service.xml
|
||||
index e584a1f006..20d2a0d755 100644
|
||||
--- a/man/systemd.service.xml
|
||||
+++ b/man/systemd.service.xml
|
||||
@@ -1155,29 +1155,30 @@ ExecStart=/bin/echo $ONE $TWO ${TWO}</programlisting>
|
||||
</varlistentry>
|
||||
|
||||
<varlistentry>
|
||||
+ <term><varname>FailureAction=</varname></term>
|
||||
+ <listitem><para>Configure the action
|
||||
+ to take when the service enters a failed
|
||||
+ state. Takes the same values as
|
||||
+ <varname>StartLimitAction=</varname>
|
||||
+ and executes the same actions.
|
||||
+ Defaults to <option>none</option>.
|
||||
+ </para></listitem>
|
||||
+ </varlistentry>
|
||||
+
|
||||
+ <varlistentry>
|
||||
<term><varname>RebootArgument=</varname></term>
|
||||
<listitem><para>Configure the optional
|
||||
argument for the
|
||||
<citerefentry><refentrytitle>reboot</refentrytitle><manvolnum>2</manvolnum></citerefentry>
|
||||
system call if
|
||||
<varname>StartLimitAction=</varname>
|
||||
+ or <varname>FailureAction=</varname>
|
||||
is a reboot action. This works just
|
||||
like the optional argument to
|
||||
<command>systemctl reboot</command>
|
||||
command.</para></listitem>
|
||||
</varlistentry>
|
||||
|
||||
- <varlistentry>
|
||||
- <term><varname>FailureAction=</varname></term>
|
||||
- <listitem><para>Configure the action
|
||||
- to take when the service enters a failed
|
||||
- state. Takes the same values as
|
||||
- <varname>StartLimitAction=</varname>
|
||||
- and executes the same actions.
|
||||
- Defaults to <option>none</option>.
|
||||
- </para></listitem>
|
||||
- </varlistentry>
|
||||
-
|
||||
</variablelist>
|
||||
|
||||
<para>Check
|
||||
diff --git a/src/core/failure-action.c b/src/core/failure-action.c
|
||||
new file mode 100644
|
||||
index 0000000000..ca807b68da
|
||||
--- /dev/null
|
||||
+++ b/src/core/failure-action.c
|
||||
@@ -0,0 +1,94 @@
|
||||
+/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
|
||||
+
|
||||
+/***
|
||||
+ This file is part of systemd.
|
||||
+
|
||||
+ Copyright 2014 Lennart Poettering
|
||||
+ Copyright 2012 Michael Olbrich
|
||||
+
|
||||
+ 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
|
||||
+ the Free Software Foundation; either version 2.1 of the License, or
|
||||
+ (at your option) any later version.
|
||||
+
|
||||
+ systemd is distributed in the hope that it will be useful, but
|
||||
+ WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
+ Lesser General Public License for more details.
|
||||
+
|
||||
+ You should have received a copy of the GNU Lesser General Public License
|
||||
+ along with systemd; If not, see <http://www.gnu.org/licenses/>.
|
||||
+***/
|
||||
+
|
||||
+#include <sys/reboot.h>
|
||||
+#include <linux/reboot.h>
|
||||
+#include <sys/syscall.h>
|
||||
+
|
||||
+#include "bus-util.h"
|
||||
+#include "bus-error.h"
|
||||
+#include "special.h"
|
||||
+#include "failure-action.h"
|
||||
+
|
||||
+int failure_action(
|
||||
+ Manager *m,
|
||||
+ FailureAction action,
|
||||
+ const char *reboot_arg) {
|
||||
+
|
||||
+ int r;
|
||||
+
|
||||
+ assert(m);
|
||||
+ assert(action >= 0);
|
||||
+ assert(action < _FAILURE_ACTION_MAX);
|
||||
+
|
||||
+ switch (action) {
|
||||
+
|
||||
+ case FAILURE_ACTION_NONE:
|
||||
+ break;
|
||||
+
|
||||
+ case FAILURE_ACTION_REBOOT: {
|
||||
+ _cleanup_bus_error_free_ sd_bus_error error = SD_BUS_ERROR_NULL;
|
||||
+
|
||||
+ log_warning("Rebooting as result of failure.");
|
||||
+
|
||||
+ update_reboot_param_file(reboot_arg);
|
||||
+ r = manager_add_job_by_name(m, JOB_START, SPECIAL_REBOOT_TARGET, JOB_REPLACE, true, &error, NULL);
|
||||
+ if (r < 0)
|
||||
+ log_error("Failed to reboot: %s.", bus_error_message(&error, r));
|
||||
+
|
||||
+ break;
|
||||
+ }
|
||||
+
|
||||
+ case FAILURE_ACTION_REBOOT_FORCE:
|
||||
+ log_warning("Forcibly rebooting as result of failure.");
|
||||
+ update_reboot_param_file(reboot_arg);
|
||||
+ m->exit_code = MANAGER_REBOOT;
|
||||
+ break;
|
||||
+
|
||||
+ case FAILURE_ACTION_REBOOT_IMMEDIATE:
|
||||
+ log_warning("Rebooting immediately as result of failure.");
|
||||
+
|
||||
+ sync();
|
||||
+
|
||||
+ if (reboot_arg) {
|
||||
+ log_info("Rebooting with argument '%s'.", reboot_arg);
|
||||
+ syscall(SYS_reboot, LINUX_REBOOT_MAGIC1, LINUX_REBOOT_MAGIC2, LINUX_REBOOT_CMD_RESTART2, reboot_arg);
|
||||
+ }
|
||||
+
|
||||
+ log_info("Rebooting.");
|
||||
+ reboot(RB_AUTOBOOT);
|
||||
+ break;
|
||||
+
|
||||
+ default:
|
||||
+ assert_not_reached("Unknown failure action");
|
||||
+ }
|
||||
+
|
||||
+ return -ECANCELED;
|
||||
+}
|
||||
+
|
||||
+static const char* const failure_action_table[_FAILURE_ACTION_MAX] = {
|
||||
+ [FAILURE_ACTION_NONE] = "none",
|
||||
+ [FAILURE_ACTION_REBOOT] = "reboot",
|
||||
+ [FAILURE_ACTION_REBOOT_FORCE] = "reboot-force",
|
||||
+ [FAILURE_ACTION_REBOOT_IMMEDIATE] = "reboot-immediate"
|
||||
+};
|
||||
+DEFINE_STRING_TABLE_LOOKUP(failure_action, FailureAction);
|
||||
diff --git a/src/core/failure-action.h b/src/core/failure-action.h
|
||||
new file mode 100644
|
||||
index 0000000000..5353192f31
|
||||
--- /dev/null
|
||||
+++ b/src/core/failure-action.h
|
||||
@@ -0,0 +1,40 @@
|
||||
+/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
|
||||
+
|
||||
+#pragma once
|
||||
+
|
||||
+/***
|
||||
+ This file is part of systemd.
|
||||
+
|
||||
+ Copyright 2014 Lennart Poettering
|
||||
+ Copyright 2012 Michael Olbrich
|
||||
+
|
||||
+ 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
|
||||
+ the Free Software Foundation; either version 2.1 of the License, or
|
||||
+ (at your option) any later version.
|
||||
+
|
||||
+ systemd is distributed in the hope that it will be useful, but
|
||||
+ WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
+ Lesser General Public License for more details.
|
||||
+
|
||||
+ You should have received a copy of the GNU Lesser General Public License
|
||||
+ along with systemd; If not, see <http://www.gnu.org/licenses/>.
|
||||
+***/
|
||||
+
|
||||
+typedef enum FailureAction {
|
||||
+ FAILURE_ACTION_NONE,
|
||||
+ FAILURE_ACTION_REBOOT,
|
||||
+ FAILURE_ACTION_REBOOT_FORCE,
|
||||
+ FAILURE_ACTION_REBOOT_IMMEDIATE,
|
||||
+ _FAILURE_ACTION_MAX,
|
||||
+ _FAILURE_ACTION_INVALID = -1
|
||||
+} FailureAction;
|
||||
+
|
||||
+#include "macro.h"
|
||||
+#include "manager.h"
|
||||
+
|
||||
+int failure_action(Manager *m, FailureAction action, const char *reboot_arg);
|
||||
+
|
||||
+const char* failure_action_to_string(FailureAction i) _const_;
|
||||
+FailureAction failure_action_from_string(const char *s) _pure_;
|
||||
diff --git a/src/core/main.c b/src/core/main.c
|
||||
index 792b316c61..ed690162bf 100644
|
||||
--- a/src/core/main.c
|
||||
+++ b/src/core/main.c
|
||||
@@ -116,6 +116,9 @@ static FILE* arg_serialization = NULL;
|
||||
static bool arg_default_cpu_accounting = false;
|
||||
static bool arg_default_blockio_accounting = false;
|
||||
static bool arg_default_memory_accounting = false;
|
||||
+static usec_t arg_start_timeout_usec = DEFAULT_MANAGER_START_TIMEOUT_USEC;
|
||||
+static FailureAction arg_start_timeout_action = FAILURE_ACTION_REBOOT_FORCE;
|
||||
+static char *arg_start_timeout_reboot_arg = NULL;
|
||||
|
||||
static void nop_handler(int sig) {}
|
||||
|
||||
@@ -669,6 +672,9 @@ static int parse_config_file(void) {
|
||||
{ "Manager", "DefaultCPUAccounting", config_parse_bool, 0, &arg_default_cpu_accounting },
|
||||
{ "Manager", "DefaultBlockIOAccounting", config_parse_bool, 0, &arg_default_blockio_accounting },
|
||||
{ "Manager", "DefaultMemoryAccounting", config_parse_bool, 0, &arg_default_memory_accounting },
|
||||
+ { "Manager", "StartTimeoutSec", config_parse_sec, 0, &arg_start_timeout_usec },
|
||||
+ { "Manager", "StartTimeoutAction", config_parse_failure_action, 0, &arg_start_timeout_action },
|
||||
+ { "Manager", "StartTimeoutRebootArgument",config_parse_string, 0, &arg_start_timeout_reboot_arg },
|
||||
{}
|
||||
};
|
||||
|
||||
@@ -1628,6 +1634,10 @@ int main(int argc, char *argv[]) {
|
||||
m->default_memory_accounting = arg_default_memory_accounting;
|
||||
m->runtime_watchdog = arg_runtime_watchdog;
|
||||
m->shutdown_watchdog = arg_shutdown_watchdog;
|
||||
+ m->start_timeout_usec = arg_start_timeout_usec;
|
||||
+ m->start_timeout_action = arg_start_timeout_action;
|
||||
+ free_and_strdup(&m->start_timeout_reboot_arg, arg_start_timeout_reboot_arg);
|
||||
+
|
||||
m->userspace_timestamp = userspace_timestamp;
|
||||
m->kernel_timestamp = kernel_timestamp;
|
||||
m->initrd_timestamp = initrd_timestamp;
|
||||
@@ -1816,6 +1826,9 @@ finish:
|
||||
set_free(arg_syscall_archs);
|
||||
arg_syscall_archs = NULL;
|
||||
|
||||
+ free(arg_start_timeout_reboot_arg);
|
||||
+ arg_start_timeout_reboot_arg = NULL;
|
||||
+
|
||||
label_finish();
|
||||
|
||||
if (reexecute) {
|
||||
diff --git a/src/core/manager.c b/src/core/manager.c
|
||||
index 7401817844..1bb0c9025f 100644
|
||||
--- a/src/core/manager.c
|
||||
+++ b/src/core/manager.c
|
||||
@@ -435,6 +435,8 @@ int manager_new(SystemdRunningAs running_as, bool test_run, Manager **_m) {
|
||||
m->running_as = running_as;
|
||||
m->exit_code = _MANAGER_EXIT_CODE_INVALID;
|
||||
m->default_timer_accuracy_usec = USEC_PER_MINUTE;
|
||||
+ m->start_timeout_usec = DEFAULT_MANAGER_START_TIMEOUT_USEC;
|
||||
+ m->start_timeout_action = FAILURE_ACTION_REBOOT_FORCE;
|
||||
|
||||
m->idle_pipe[0] = m->idle_pipe[1] = m->idle_pipe[2] = m->idle_pipe[3] = -1;
|
||||
|
||||
@@ -823,6 +825,9 @@ void manager_free(Manager *m) {
|
||||
|
||||
manager_close_idle_pipe(m);
|
||||
|
||||
+ sd_event_source_unref(m->start_timeout_event_source);
|
||||
+ free(m->start_timeout_reboot_arg);
|
||||
+
|
||||
udev_unref(m->udev);
|
||||
sd_event_unref(m->event);
|
||||
|
||||
@@ -970,6 +975,20 @@ static int manager_distribute_fds(Manager *m, FDSet *fds) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
+static int on_start_timeout(sd_event_source *s, usec_t usec, void *userdata) {
|
||||
+ Manager *m = userdata;
|
||||
+
|
||||
+ assert(s);
|
||||
+ assert(m);
|
||||
+
|
||||
+ m->start_timeout_event_source = sd_event_source_unref(m->start_timeout_event_source);
|
||||
+
|
||||
+ log_error("Startup timed out.");
|
||||
+
|
||||
+ failure_action(m, m->start_timeout_action, m->start_timeout_reboot_arg);
|
||||
+ return 0;
|
||||
+}
|
||||
+
|
||||
int manager_startup(Manager *m, FILE *serialization, FDSet *fds) {
|
||||
int r, q;
|
||||
|
||||
@@ -1042,6 +1061,22 @@ int manager_startup(Manager *m, FILE *serialization, FDSet *fds) {
|
||||
m->send_reloading_done = true;
|
||||
}
|
||||
|
||||
+ /* Possibly set up a start timeout */
|
||||
+ if (!dual_timestamp_is_set(&m->finish_timestamp)) {
|
||||
+ m->start_timeout_event_source = sd_event_source_unref(m->start_timeout_event_source);
|
||||
+
|
||||
+ if (m->start_timeout_usec) {
|
||||
+ r = sd_event_add_time(
|
||||
+ m->event,
|
||||
+ &m->start_timeout_event_source,
|
||||
+ CLOCK_MONOTONIC,
|
||||
+ now(CLOCK_MONOTONIC) + m->start_timeout_usec, 0,
|
||||
+ on_start_timeout, m);
|
||||
+ if (r < 0)
|
||||
+ log_error("Failed to add start timeout event: %s", strerror(-r));
|
||||
+ }
|
||||
+ }
|
||||
+
|
||||
return r;
|
||||
}
|
||||
|
||||
@@ -2462,10 +2497,8 @@ void manager_check_finished(Manager *m) {
|
||||
|
||||
if (hashmap_size(m->jobs) > 0) {
|
||||
|
||||
- if (m->jobs_in_progress_event_source) {
|
||||
- sd_event_source_set_time(m->jobs_in_progress_event_source,
|
||||
- now(CLOCK_MONOTONIC) + JOBS_IN_PROGRESS_WAIT_USEC);
|
||||
- }
|
||||
+ if (m->jobs_in_progress_event_source)
|
||||
+ sd_event_source_set_time(m->jobs_in_progress_event_source, now(CLOCK_MONOTONIC) + JOBS_IN_PROGRESS_WAIT_USEC);
|
||||
|
||||
return;
|
||||
}
|
||||
@@ -2487,6 +2520,8 @@ void manager_check_finished(Manager *m) {
|
||||
|
||||
dual_timestamp_get(&m->finish_timestamp);
|
||||
|
||||
+ m->start_timeout_event_source = sd_event_source_unref(m->start_timeout_event_source);
|
||||
+
|
||||
if (m->running_as == SYSTEMD_SYSTEM && detect_container(NULL) <= 0) {
|
||||
|
||||
/* Note that m->kernel_usec.monotonic is always at 0,
|
||||
diff --git a/src/core/manager.h b/src/core/manager.h
|
||||
index 7cb76f7f00..7d26c3adea 100644
|
||||
--- a/src/core/manager.h
|
||||
+++ b/src/core/manager.h
|
||||
@@ -33,6 +33,8 @@
|
||||
/* Enforce upper limit how many names we allow */
|
||||
#define MANAGER_MAX_NAMES 131072 /* 128K */
|
||||
|
||||
+#define DEFAULT_MANAGER_START_TIMEOUT_USEC (15*USEC_PER_MINUTE)
|
||||
+
|
||||
typedef struct Manager Manager;
|
||||
|
||||
typedef enum ManagerState {
|
||||
@@ -69,6 +71,7 @@ typedef enum ManagerExitCode {
|
||||
#include "unit-name.h"
|
||||
#include "exit-status.h"
|
||||
#include "show-status.h"
|
||||
+#include "failure-action.h"
|
||||
|
||||
struct Manager {
|
||||
/* Note that the set of units we know of is allowed to be
|
||||
@@ -152,6 +155,7 @@ struct Manager {
|
||||
dual_timestamp initrd_timestamp;
|
||||
dual_timestamp userspace_timestamp;
|
||||
dual_timestamp finish_timestamp;
|
||||
+
|
||||
dual_timestamp security_start_timestamp;
|
||||
dual_timestamp security_finish_timestamp;
|
||||
dual_timestamp generators_start_timestamp;
|
||||
@@ -279,6 +283,12 @@ struct Manager {
|
||||
|
||||
/* Used for processing polkit authorization responses */
|
||||
Hashmap *polkit_registry;
|
||||
+
|
||||
+ /* System wide startup timeouts */
|
||||
+ usec_t start_timeout_usec;
|
||||
+ sd_event_source *start_timeout_event_source;
|
||||
+ FailureAction start_timeout_action;
|
||||
+ char *start_timeout_reboot_arg;
|
||||
};
|
||||
|
||||
int manager_new(SystemdRunningAs running_as, bool test_run, Manager **m);
|
||||
diff --git a/src/core/service.c b/src/core/service.c
|
||||
index 1b864c4c8c..223e4b3a41 100644
|
||||
--- a/src/core/service.c
|
||||
+++ b/src/core/service.c
|
||||
@@ -23,9 +23,6 @@
|
||||
#include <signal.h>
|
||||
#include <dirent.h>
|
||||
#include <unistd.h>
|
||||
-#include <sys/reboot.h>
|
||||
-#include <linux/reboot.h>
|
||||
-#include <sys/syscall.h>
|
||||
|
||||
#include "async.h"
|
||||
#include "manager.h"
|
||||
@@ -1052,8 +1049,6 @@ static int cgroup_good(Service *s) {
|
||||
return !r;
|
||||
}
|
||||
|
||||
-static int service_execute_action(Service *s, FailureAction action, const char *reason, bool log_action_none);
|
||||
-
|
||||
static void service_enter_dead(Service *s, ServiceResult f, bool allow_restart) {
|
||||
int r;
|
||||
assert(s);
|
||||
@@ -1063,8 +1058,10 @@ static void service_enter_dead(Service *s, ServiceResult f, bool allow_restart)
|
||||
|
||||
service_set_state(s, s->result != SERVICE_SUCCESS ? SERVICE_FAILED : SERVICE_DEAD);
|
||||
|
||||
- if (s->result != SERVICE_SUCCESS)
|
||||
- service_execute_action(s, s->failure_action, "failed", false);
|
||||
+ if (s->result != SERVICE_SUCCESS) {
|
||||
+ log_warning_unit(UNIT(s)->id, "%s failed.", UNIT(s)->id);
|
||||
+ failure_action(UNIT(s)->manager, s->failure_action, s->reboot_arg);
|
||||
+ }
|
||||
|
||||
if (allow_restart &&
|
||||
!s->forbid_restart &&
|
||||
@@ -1601,67 +1598,15 @@ fail:
|
||||
service_enter_stop(s, SERVICE_FAILURE_RESOURCES);
|
||||
}
|
||||
|
||||
-static int service_execute_action(Service *s, FailureAction action, const char *reason, bool log_action_none) {
|
||||
- assert(s);
|
||||
-
|
||||
- if (action == SERVICE_FAILURE_ACTION_REBOOT ||
|
||||
- action == SERVICE_FAILURE_ACTION_REBOOT_FORCE)
|
||||
- update_reboot_param_file(s->reboot_arg);
|
||||
-
|
||||
- switch (action) {
|
||||
-
|
||||
- case SERVICE_FAILURE_ACTION_NONE:
|
||||
- if (log_action_none)
|
||||
- log_warning_unit(UNIT(s)->id, "%s %s, refusing to start.", UNIT(s)->id, reason);
|
||||
- break;
|
||||
-
|
||||
- case SERVICE_FAILURE_ACTION_REBOOT: {
|
||||
- _cleanup_bus_error_free_ sd_bus_error error = SD_BUS_ERROR_NULL;
|
||||
- int r;
|
||||
-
|
||||
- log_warning_unit(UNIT(s)->id, "%s %s, rebooting.", UNIT(s)->id, reason);
|
||||
-
|
||||
- r = manager_add_job_by_name(UNIT(s)->manager, JOB_START, SPECIAL_REBOOT_TARGET, JOB_REPLACE, true, &error, NULL);
|
||||
- if (r < 0)
|
||||
- log_error_unit(UNIT(s)->id, "Failed to reboot: %s.", bus_error_message(&error, r));
|
||||
-
|
||||
- break;
|
||||
- }
|
||||
-
|
||||
- case SERVICE_FAILURE_ACTION_REBOOT_FORCE:
|
||||
- log_warning_unit(UNIT(s)->id, "%s %s, forcibly rebooting.", UNIT(s)->id, reason);
|
||||
- UNIT(s)->manager->exit_code = MANAGER_REBOOT;
|
||||
- break;
|
||||
-
|
||||
- case SERVICE_FAILURE_ACTION_REBOOT_IMMEDIATE:
|
||||
- log_warning_unit(UNIT(s)->id, "%s %s, rebooting immediately.", UNIT(s)->id, reason);
|
||||
-
|
||||
- sync();
|
||||
-
|
||||
- if (s->reboot_arg) {
|
||||
- log_info("Rebooting with argument '%s'.", s->reboot_arg);
|
||||
- syscall(SYS_reboot, LINUX_REBOOT_MAGIC1, LINUX_REBOOT_MAGIC2, LINUX_REBOOT_CMD_RESTART2, s->reboot_arg);
|
||||
- }
|
||||
-
|
||||
- log_info("Rebooting.");
|
||||
- reboot(RB_AUTOBOOT);
|
||||
- break;
|
||||
-
|
||||
- default:
|
||||
- log_error_unit(UNIT(s)->id, "failure action=%i", action);
|
||||
- assert_not_reached("Unknown FailureAction.");
|
||||
- }
|
||||
-
|
||||
- return -ECANCELED;
|
||||
-}
|
||||
-
|
||||
static int service_start_limit_test(Service *s) {
|
||||
assert(s);
|
||||
|
||||
if (ratelimit_test(&s->start_limit))
|
||||
return 0;
|
||||
|
||||
- return service_execute_action(s, s->start_limit_action, "start request repeated too quickly", true);
|
||||
+ log_warning_unit(UNIT(s)->id, "start request repeated too quickly for %s", UNIT(s)->id);
|
||||
+
|
||||
+ return failure_action(UNIT(s)->manager, s->start_limit_action, s->reboot_arg);
|
||||
}
|
||||
|
||||
static int service_start(Unit *u) {
|
||||
@@ -2908,14 +2853,6 @@ static const char* const service_result_table[_SERVICE_RESULT_MAX] = {
|
||||
|
||||
DEFINE_STRING_TABLE_LOOKUP(service_result, ServiceResult);
|
||||
|
||||
-static const char* const failure_action_table[_SERVICE_FAILURE_ACTION_MAX] = {
|
||||
- [SERVICE_FAILURE_ACTION_NONE] = "none",
|
||||
- [SERVICE_FAILURE_ACTION_REBOOT] = "reboot",
|
||||
- [SERVICE_FAILURE_ACTION_REBOOT_FORCE] = "reboot-force",
|
||||
- [SERVICE_FAILURE_ACTION_REBOOT_IMMEDIATE] = "reboot-immediate"
|
||||
-};
|
||||
-DEFINE_STRING_TABLE_LOOKUP(failure_action, FailureAction);
|
||||
-
|
||||
const UnitVTable service_vtable = {
|
||||
.object_size = sizeof(Service),
|
||||
.exec_context_offset = offsetof(Service, exec_context),
|
||||
diff --git a/src/core/service.h b/src/core/service.h
|
||||
index 0227321d99..5bcfd14339 100644
|
||||
--- a/src/core/service.h
|
||||
+++ b/src/core/service.h
|
||||
@@ -28,6 +28,7 @@ typedef struct Service Service;
|
||||
#include "ratelimit.h"
|
||||
#include "kill.h"
|
||||
#include "exit-status.h"
|
||||
+#include "failure-action.h"
|
||||
|
||||
typedef enum ServiceState {
|
||||
SERVICE_DEAD,
|
||||
@@ -113,15 +114,6 @@ typedef enum ServiceResult {
|
||||
_SERVICE_RESULT_INVALID = -1
|
||||
} ServiceResult;
|
||||
|
||||
-typedef enum FailureAction {
|
||||
- SERVICE_FAILURE_ACTION_NONE,
|
||||
- SERVICE_FAILURE_ACTION_REBOOT,
|
||||
- SERVICE_FAILURE_ACTION_REBOOT_FORCE,
|
||||
- SERVICE_FAILURE_ACTION_REBOOT_IMMEDIATE,
|
||||
- _SERVICE_FAILURE_ACTION_MAX,
|
||||
- _SERVICE_FAILURE_ACTION_INVALID = -1
|
||||
-} FailureAction;
|
||||
-
|
||||
struct Service {
|
||||
Unit meta;
|
||||
|
||||
@@ -193,10 +185,9 @@ struct Service {
|
||||
char *status_text;
|
||||
int status_errno;
|
||||
|
||||
- FailureAction failure_action;
|
||||
-
|
||||
RateLimit start_limit;
|
||||
FailureAction start_limit_action;
|
||||
+ FailureAction failure_action;
|
||||
char *reboot_arg;
|
||||
|
||||
UnitRef accept_socket;
|
||||
@@ -234,6 +225,3 @@ NotifyState notify_state_from_string(const char *s) _pure_;
|
||||
|
||||
const char* service_result_to_string(ServiceResult i) _const_;
|
||||
ServiceResult service_result_from_string(const char *s) _pure_;
|
||||
-
|
||||
-const char* failure_action_to_string(FailureAction i) _const_;
|
||||
-FailureAction failure_action_from_string(const char *s) _pure_;
|
||||
diff --git a/src/core/system.conf b/src/core/system.conf
|
||||
index 65a35a0689..45448de328 100644
|
||||
--- a/src/core/system.conf
|
||||
+++ b/src/core/system.conf
|
||||
@@ -23,6 +23,9 @@
|
||||
#CapabilityBoundingSet=
|
||||
#SystemCallArchitectures=
|
||||
#TimerSlackNSec=
|
||||
+#StartTimeoutSec=15min
|
||||
+#StartTimeoutAction=reboot-force
|
||||
+#StartTimeoutRebootArgument=
|
||||
#DefaultTimerAccuracySec=1min
|
||||
#DefaultStandardOutput=journal
|
||||
#DefaultStandardError=inherit
|
||||
diff --git a/src/shared/util.c b/src/shared/util.c
|
||||
index a54e879953..fc6f668726 100644
|
||||
--- a/src/shared/util.c
|
||||
+++ b/src/shared/util.c
|
||||
@@ -7137,3 +7137,24 @@ int unquote_many_words(const char **p, ...) {
|
||||
|
||||
return c;
|
||||
}
|
||||
+
|
||||
+int free_and_strdup(char **p, const char *s) {
|
||||
+ char *t;
|
||||
+
|
||||
+ assert(p);
|
||||
+
|
||||
+ /* Replaces a string pointer with an strdup()ed new string,
|
||||
+ * possibly freeing the old one. */
|
||||
+
|
||||
+ if (s) {
|
||||
+ t = strdup(s);
|
||||
+ if (!t)
|
||||
+ return -ENOMEM;
|
||||
+ } else
|
||||
+ t = NULL;
|
||||
+
|
||||
+ free(*p);
|
||||
+ *p = t;
|
||||
+
|
||||
+ return 0;
|
||||
+}
|
||||
diff --git a/src/shared/util.h b/src/shared/util.h
|
||||
index 8cd47b8294..cd947dbbef 100644
|
||||
--- a/src/shared/util.h
|
||||
+++ b/src/shared/util.h
|
||||
@@ -978,3 +978,5 @@ int is_symlink(const char *path);
|
||||
|
||||
int unquote_first_word(const char **p, char **ret);
|
||||
int unquote_many_words(const char **p, ...) _sentinel_;
|
||||
+
|
||||
+int free_and_strdup(char **p, const char *s);
|
||||
diff --git a/src/test/test-tables.c b/src/test/test-tables.c
|
||||
index 88e7d10c60..58fe4433b7 100644
|
||||
--- a/src/test/test-tables.c
|
||||
+++ b/src/test/test-tables.c
|
||||
@@ -63,7 +63,7 @@ int main(int argc, char **argv) {
|
||||
test_table(device_state, DEVICE_STATE);
|
||||
test_table(exec_input, EXEC_INPUT);
|
||||
test_table(exec_output, EXEC_OUTPUT);
|
||||
- test_table(failure_action, SERVICE_FAILURE_ACTION);
|
||||
+ test_table(failure_action, FAILURE_ACTION);
|
||||
test_table(job_mode, JOB_MODE);
|
||||
test_table(job_result, JOB_RESULT);
|
||||
test_table(job_state, JOB_STATE);
|
@ -0,0 +1,85 @@
|
||||
From e12919e8be5c80efe09a57f642bbd2411b313ced Mon Sep 17 00:00:00 2001
|
||||
From: Lennart Poettering <lennart@poettering.net>
|
||||
Date: Fri, 22 Aug 2014 16:41:00 +0200
|
||||
Subject: [PATCH] core: print 'startup finished' messages even if we log to
|
||||
console
|
||||
|
||||
---
|
||||
src/core/manager.c | 55 ++++++++++++++++++++++++++----------------------------
|
||||
1 file changed, 26 insertions(+), 29 deletions(-)
|
||||
|
||||
diff --git a/src/core/manager.c b/src/core/manager.c
|
||||
index 1bb0c9025f..7508fefaef 100644
|
||||
--- a/src/core/manager.c
|
||||
+++ b/src/core/manager.c
|
||||
@@ -2539,44 +2539,41 @@ void manager_check_finished(Manager *m) {
|
||||
kernel_usec = m->initrd_timestamp.monotonic - m->kernel_timestamp.monotonic;
|
||||
initrd_usec = m->userspace_timestamp.monotonic - m->initrd_timestamp.monotonic;
|
||||
|
||||
- if (!log_on_console())
|
||||
- log_struct(LOG_INFO,
|
||||
- MESSAGE_ID(SD_MESSAGE_STARTUP_FINISHED),
|
||||
- "KERNEL_USEC="USEC_FMT, kernel_usec,
|
||||
- "INITRD_USEC="USEC_FMT, initrd_usec,
|
||||
- "USERSPACE_USEC="USEC_FMT, userspace_usec,
|
||||
- "MESSAGE=Startup finished in %s (kernel) + %s (initrd) + %s (userspace) = %s.",
|
||||
- format_timespan(kernel, sizeof(kernel), kernel_usec, USEC_PER_MSEC),
|
||||
- format_timespan(initrd, sizeof(initrd), initrd_usec, USEC_PER_MSEC),
|
||||
- format_timespan(userspace, sizeof(userspace), userspace_usec, USEC_PER_MSEC),
|
||||
- format_timespan(sum, sizeof(sum), total_usec, USEC_PER_MSEC),
|
||||
- NULL);
|
||||
+ log_struct(LOG_INFO,
|
||||
+ MESSAGE_ID(SD_MESSAGE_STARTUP_FINISHED),
|
||||
+ "KERNEL_USEC="USEC_FMT, kernel_usec,
|
||||
+ "INITRD_USEC="USEC_FMT, initrd_usec,
|
||||
+ "USERSPACE_USEC="USEC_FMT, userspace_usec,
|
||||
+ "MESSAGE=Startup finished in %s (kernel) + %s (initrd) + %s (userspace) = %s.",
|
||||
+ format_timespan(kernel, sizeof(kernel), kernel_usec, USEC_PER_MSEC),
|
||||
+ format_timespan(initrd, sizeof(initrd), initrd_usec, USEC_PER_MSEC),
|
||||
+ format_timespan(userspace, sizeof(userspace), userspace_usec, USEC_PER_MSEC),
|
||||
+ format_timespan(sum, sizeof(sum), total_usec, USEC_PER_MSEC),
|
||||
+ NULL);
|
||||
} else {
|
||||
kernel_usec = m->userspace_timestamp.monotonic - m->kernel_timestamp.monotonic;
|
||||
initrd_usec = 0;
|
||||
|
||||
- if (!log_on_console())
|
||||
- log_struct(LOG_INFO,
|
||||
- MESSAGE_ID(SD_MESSAGE_STARTUP_FINISHED),
|
||||
- "KERNEL_USEC="USEC_FMT, kernel_usec,
|
||||
- "USERSPACE_USEC="USEC_FMT, userspace_usec,
|
||||
- "MESSAGE=Startup finished in %s (kernel) + %s (userspace) = %s.",
|
||||
- format_timespan(kernel, sizeof(kernel), kernel_usec, USEC_PER_MSEC),
|
||||
- format_timespan(userspace, sizeof(userspace), userspace_usec, USEC_PER_MSEC),
|
||||
- format_timespan(sum, sizeof(sum), total_usec, USEC_PER_MSEC),
|
||||
- NULL);
|
||||
- }
|
||||
- } else {
|
||||
- firmware_usec = loader_usec = initrd_usec = kernel_usec = 0;
|
||||
- total_usec = userspace_usec = m->finish_timestamp.monotonic - m->userspace_timestamp.monotonic;
|
||||
-
|
||||
- if (!log_on_console())
|
||||
log_struct(LOG_INFO,
|
||||
MESSAGE_ID(SD_MESSAGE_STARTUP_FINISHED),
|
||||
+ "KERNEL_USEC="USEC_FMT, kernel_usec,
|
||||
"USERSPACE_USEC="USEC_FMT, userspace_usec,
|
||||
- "MESSAGE=Startup finished in %s.",
|
||||
+ "MESSAGE=Startup finished in %s (kernel) + %s (userspace) = %s.",
|
||||
+ format_timespan(kernel, sizeof(kernel), kernel_usec, USEC_PER_MSEC),
|
||||
+ format_timespan(userspace, sizeof(userspace), userspace_usec, USEC_PER_MSEC),
|
||||
format_timespan(sum, sizeof(sum), total_usec, USEC_PER_MSEC),
|
||||
NULL);
|
||||
+ }
|
||||
+ } else {
|
||||
+ firmware_usec = loader_usec = initrd_usec = kernel_usec = 0;
|
||||
+ total_usec = userspace_usec = m->finish_timestamp.monotonic - m->userspace_timestamp.monotonic;
|
||||
+
|
||||
+ log_struct(LOG_INFO,
|
||||
+ MESSAGE_ID(SD_MESSAGE_STARTUP_FINISHED),
|
||||
+ "USERSPACE_USEC="USEC_FMT, userspace_usec,
|
||||
+ "MESSAGE=Startup finished in %s.",
|
||||
+ format_timespan(sum, sizeof(sum), total_usec, USEC_PER_MSEC),
|
||||
+ NULL);
|
||||
}
|
||||
|
||||
SET_FOREACH(u, m->startup_units, i)
|
22
0040-resolved-fix-typo-in-log-message.patch
Normal file
22
0040-resolved-fix-typo-in-log-message.patch
Normal file
@ -0,0 +1,22 @@
|
||||
From c4147df156835513c43260a14fc9f7af177f737f Mon Sep 17 00:00:00 2001
|
||||
From: Lennart Poettering <lennart@poettering.net>
|
||||
Date: Fri, 22 Aug 2014 16:58:25 +0200
|
||||
Subject: [PATCH] resolved: fix typo in log message
|
||||
|
||||
---
|
||||
src/resolve/resolved-manager.c | 2 +-
|
||||
1 file changed, 1 insertion(+), 1 deletion(-)
|
||||
|
||||
diff --git a/src/resolve/resolved-manager.c b/src/resolve/resolved-manager.c
|
||||
index 659b1dacc8..f97989754d 100644
|
||||
--- a/src/resolve/resolved-manager.c
|
||||
+++ b/src/resolve/resolved-manager.c
|
||||
@@ -449,7 +449,7 @@ static int manager_llmnr_start(Manager *m) {
|
||||
return 0;
|
||||
|
||||
eaddrinuse:
|
||||
- log_warning("There appears to be another LLMNR respondering running. Turning off LLMNR support.");
|
||||
+ log_warning("There appears to be another LLMNR responder running. Turning off LLMNR support.");
|
||||
m->llmnr_support = SUPPORT_NO;
|
||||
manager_llmnr_stop(m);
|
||||
|
219
0041-core-introduce-poweroff-as-new-failure-action-types.patch
Normal file
219
0041-core-introduce-poweroff-as-new-failure-action-types.patch
Normal file
@ -0,0 +1,219 @@
|
||||
From f07756bfe25c64119704c93a634162d6c88b5c89 Mon Sep 17 00:00:00 2001
|
||||
From: Lennart Poettering <lennart@poettering.net>
|
||||
Date: Fri, 22 Aug 2014 16:59:46 +0200
|
||||
Subject: [PATCH] core: introduce "poweroff" as new failure action types
|
||||
|
||||
Also, change the default action on a system start-up timeout to powering off.
|
||||
---
|
||||
man/systemd-system.conf.xml | 2 +-
|
||||
man/systemd.service.xml | 31 +++++++++++++++++++-----------
|
||||
src/core/failure-action.c | 46 +++++++++++++++++++++++++++++++++++++++++----
|
||||
src/core/failure-action.h | 3 +++
|
||||
src/core/main.c | 2 +-
|
||||
src/core/manager.c | 2 +-
|
||||
src/core/shutdown.c | 3 +--
|
||||
src/core/system.conf | 2 +-
|
||||
8 files changed, 70 insertions(+), 21 deletions(-)
|
||||
|
||||
diff --git a/man/systemd-system.conf.xml b/man/systemd-system.conf.xml
|
||||
index 48690024f4..1fad1dba80 100644
|
||||
--- a/man/systemd-system.conf.xml
|
||||
+++ b/man/systemd-system.conf.xml
|
||||
@@ -298,7 +298,7 @@
|
||||
setting, see
|
||||
<citerefentry><refentrytitle>systemd.service</refentrytitle><manvolnum>5</manvolnum></citerefentry>
|
||||
for details. Defaults to
|
||||
- <option>reboot-force</option>. <varname>StartTimeoutRebootArgument=</varname>
|
||||
+ <option>poweroff-force</option>. <varname>StartTimeoutRebootArgument=</varname>
|
||||
configures an optional reboot string
|
||||
to pass to the
|
||||
<citerefentry><refentrytitle>reboot</refentrytitle><manvolnum>2</manvolnum></citerefentry>
|
||||
diff --git a/man/systemd.service.xml b/man/systemd.service.xml
|
||||
index 20d2a0d755..8b17f857ce 100644
|
||||
--- a/man/systemd.service.xml
|
||||
+++ b/man/systemd.service.xml
|
||||
@@ -1131,26 +1131,35 @@ ExecStart=/bin/echo $ONE $TWO ${TWO}</programlisting>
|
||||
hit. Takes one of
|
||||
<option>none</option>,
|
||||
<option>reboot</option>,
|
||||
- <option>reboot-force</option>, or
|
||||
- <option>reboot-immediate</option>. If
|
||||
- <option>none</option> is set,
|
||||
- hitting the rate limit will trigger no
|
||||
- action besides that the start will not
|
||||
- be permitted. <option>reboot</option>
|
||||
+ <option>reboot-force</option>,
|
||||
+ <option>reboot-immediate</option>,
|
||||
+ <option>poweroff</option>,
|
||||
+ <option>poweroff-force</option> or
|
||||
+ <option>poweroff-immediate</option>. If
|
||||
+ <option>none</option> is set, hitting
|
||||
+ the rate limit will trigger no action
|
||||
+ besides that the start will not be
|
||||
+ permitted. <option>reboot</option>
|
||||
causes a reboot following the normal
|
||||
shutdown procedure (i.e. equivalent to
|
||||
<command>systemctl reboot</command>).
|
||||
- <option>reboot-force</option> causes
|
||||
- a forced reboot which will terminate
|
||||
- all processes forcibly but should
|
||||
- cause no dirty file systems on reboot
|
||||
+ <option>reboot-force</option> causes a
|
||||
+ forced reboot which will terminate all
|
||||
+ processes forcibly but should cause no
|
||||
+ dirty file systems on reboot
|
||||
(i.e. equivalent to <command>systemctl
|
||||
reboot -f</command>) and
|
||||
<option>reboot-immediate</option>
|
||||
causes immediate execution of the
|
||||
<citerefentry><refentrytitle>reboot</refentrytitle><manvolnum>2</manvolnum></citerefentry>
|
||||
system call, which might result in
|
||||
- data loss. Defaults to
|
||||
+ data loss. Similar,
|
||||
+ <option>poweroff</option>,
|
||||
+ <option>poweroff-force</option>,
|
||||
+ <option>poweroff-immediate</option>
|
||||
+ have the effect of powering down the
|
||||
+ system with similar
|
||||
+ semantics. Defaults to
|
||||
<option>none</option>.</para></listitem>
|
||||
</varlistentry>
|
||||
|
||||
diff --git a/src/core/failure-action.c b/src/core/failure-action.c
|
||||
index ca807b68da..941747429f 100644
|
||||
--- a/src/core/failure-action.c
|
||||
+++ b/src/core/failure-action.c
|
||||
@@ -40,10 +40,19 @@ int failure_action(
|
||||
assert(action >= 0);
|
||||
assert(action < _FAILURE_ACTION_MAX);
|
||||
|
||||
- switch (action) {
|
||||
+ if (action == FAILURE_ACTION_NONE)
|
||||
+ return -ECANCELED;
|
||||
|
||||
- case FAILURE_ACTION_NONE:
|
||||
- break;
|
||||
+ if (m->running_as == SYSTEMD_USER) {
|
||||
+ /* Downgrade all options to simply exiting if we run
|
||||
+ * in user mode */
|
||||
+
|
||||
+ log_warning("Exiting as result of failure.");
|
||||
+ m->exit_code = MANAGER_EXIT;
|
||||
+ return -ECANCELED;
|
||||
+ }
|
||||
+
|
||||
+ switch (action) {
|
||||
|
||||
case FAILURE_ACTION_REBOOT: {
|
||||
_cleanup_bus_error_free_ sd_bus_error error = SD_BUS_ERROR_NULL;
|
||||
@@ -78,6 +87,32 @@ int failure_action(
|
||||
reboot(RB_AUTOBOOT);
|
||||
break;
|
||||
|
||||
+ case FAILURE_ACTION_POWEROFF: {
|
||||
+ _cleanup_bus_error_free_ sd_bus_error error = SD_BUS_ERROR_NULL;
|
||||
+
|
||||
+ log_warning("Powering off as result of failure.");
|
||||
+
|
||||
+ r = manager_add_job_by_name(m, JOB_START, SPECIAL_POWEROFF_TARGET, JOB_REPLACE, true, &error, NULL);
|
||||
+ if (r < 0)
|
||||
+ log_error("Failed to poweroff: %s.", bus_error_message(&error, r));
|
||||
+
|
||||
+ break;
|
||||
+ }
|
||||
+
|
||||
+ case FAILURE_ACTION_POWEROFF_FORCE:
|
||||
+ log_warning("Forcibly powering off as result of failure.");
|
||||
+ m->exit_code = MANAGER_POWEROFF;
|
||||
+ break;
|
||||
+
|
||||
+ case FAILURE_ACTION_POWEROFF_IMMEDIATE:
|
||||
+ log_warning("Powering off immediately as result of failure.");
|
||||
+
|
||||
+ sync();
|
||||
+
|
||||
+ log_info("Powering off.");
|
||||
+ reboot(RB_POWER_OFF);
|
||||
+ break;
|
||||
+
|
||||
default:
|
||||
assert_not_reached("Unknown failure action");
|
||||
}
|
||||
@@ -89,6 +124,9 @@ static const char* const failure_action_table[_FAILURE_ACTION_MAX] = {
|
||||
[FAILURE_ACTION_NONE] = "none",
|
||||
[FAILURE_ACTION_REBOOT] = "reboot",
|
||||
[FAILURE_ACTION_REBOOT_FORCE] = "reboot-force",
|
||||
- [FAILURE_ACTION_REBOOT_IMMEDIATE] = "reboot-immediate"
|
||||
+ [FAILURE_ACTION_REBOOT_IMMEDIATE] = "reboot-immediate",
|
||||
+ [FAILURE_ACTION_POWEROFF] = "poweroff",
|
||||
+ [FAILURE_ACTION_POWEROFF_FORCE] = "poweroff-force",
|
||||
+ [FAILURE_ACTION_POWEROFF_IMMEDIATE] = "poweroff-immediate"
|
||||
};
|
||||
DEFINE_STRING_TABLE_LOOKUP(failure_action, FailureAction);
|
||||
diff --git a/src/core/failure-action.h b/src/core/failure-action.h
|
||||
index 5353192f31..1af4dd987b 100644
|
||||
--- a/src/core/failure-action.h
|
||||
+++ b/src/core/failure-action.h
|
||||
@@ -27,6 +27,9 @@ typedef enum FailureAction {
|
||||
FAILURE_ACTION_REBOOT,
|
||||
FAILURE_ACTION_REBOOT_FORCE,
|
||||
FAILURE_ACTION_REBOOT_IMMEDIATE,
|
||||
+ FAILURE_ACTION_POWEROFF,
|
||||
+ FAILURE_ACTION_POWEROFF_FORCE,
|
||||
+ FAILURE_ACTION_POWEROFF_IMMEDIATE,
|
||||
_FAILURE_ACTION_MAX,
|
||||
_FAILURE_ACTION_INVALID = -1
|
||||
} FailureAction;
|
||||
diff --git a/src/core/main.c b/src/core/main.c
|
||||
index ed690162bf..bd148b1b33 100644
|
||||
--- a/src/core/main.c
|
||||
+++ b/src/core/main.c
|
||||
@@ -117,7 +117,7 @@ static bool arg_default_cpu_accounting = false;
|
||||
static bool arg_default_blockio_accounting = false;
|
||||
static bool arg_default_memory_accounting = false;
|
||||
static usec_t arg_start_timeout_usec = DEFAULT_MANAGER_START_TIMEOUT_USEC;
|
||||
-static FailureAction arg_start_timeout_action = FAILURE_ACTION_REBOOT_FORCE;
|
||||
+static FailureAction arg_start_timeout_action = FAILURE_ACTION_POWEROFF_FORCE;
|
||||
static char *arg_start_timeout_reboot_arg = NULL;
|
||||
|
||||
static void nop_handler(int sig) {}
|
||||
diff --git a/src/core/manager.c b/src/core/manager.c
|
||||
index 7508fefaef..7639aeef19 100644
|
||||
--- a/src/core/manager.c
|
||||
+++ b/src/core/manager.c
|
||||
@@ -436,7 +436,7 @@ int manager_new(SystemdRunningAs running_as, bool test_run, Manager **_m) {
|
||||
m->exit_code = _MANAGER_EXIT_CODE_INVALID;
|
||||
m->default_timer_accuracy_usec = USEC_PER_MINUTE;
|
||||
m->start_timeout_usec = DEFAULT_MANAGER_START_TIMEOUT_USEC;
|
||||
- m->start_timeout_action = FAILURE_ACTION_REBOOT_FORCE;
|
||||
+ m->start_timeout_action = FAILURE_ACTION_POWEROFF_FORCE;
|
||||
|
||||
m->idle_pipe[0] = m->idle_pipe[1] = m->idle_pipe[2] = m->idle_pipe[3] = -1;
|
||||
|
||||
diff --git a/src/core/shutdown.c b/src/core/shutdown.c
|
||||
index 1abc140e7d..0e2ea5754f 100644
|
||||
--- a/src/core/shutdown.c
|
||||
+++ b/src/core/shutdown.c
|
||||
@@ -435,8 +435,7 @@ int main(int argc, char *argv[]) {
|
||||
|
||||
if (read_one_line_file(REBOOT_PARAM_FILE, ¶m) >= 0) {
|
||||
log_info("Rebooting with argument '%s'.", param);
|
||||
- syscall(SYS_reboot, LINUX_REBOOT_MAGIC1, LINUX_REBOOT_MAGIC2,
|
||||
- LINUX_REBOOT_CMD_RESTART2, param);
|
||||
+ syscall(SYS_reboot, LINUX_REBOOT_MAGIC1, LINUX_REBOOT_MAGIC2, LINUX_REBOOT_CMD_RESTART2, param);
|
||||
}
|
||||
}
|
||||
|
||||
diff --git a/src/core/system.conf b/src/core/system.conf
|
||||
index 45448de328..5a723bb20e 100644
|
||||
--- a/src/core/system.conf
|
||||
+++ b/src/core/system.conf
|
||||
@@ -24,7 +24,7 @@
|
||||
#SystemCallArchitectures=
|
||||
#TimerSlackNSec=
|
||||
#StartTimeoutSec=15min
|
||||
-#StartTimeoutAction=reboot-force
|
||||
+#StartTimeoutAction=poweroff-force
|
||||
#StartTimeoutRebootArgument=
|
||||
#DefaultTimerAccuracySec=1min
|
||||
#DefaultStandardOutput=journal
|
@ -0,0 +1,88 @@
|
||||
From d81afec1c9bf4b73e3df8996d65ecae95d19b6db Mon Sep 17 00:00:00 2001
|
||||
From: Lennart Poettering <lennart@poettering.net>
|
||||
Date: Fri, 22 Aug 2014 18:07:18 +0200
|
||||
Subject: [PATCH] core: split up "starting" manager state into "initializing"
|
||||
and "starting"
|
||||
|
||||
We'll stay in "initializing" until basic.target has reached, at which
|
||||
point we will enter "starting".
|
||||
|
||||
This is preparation so that we can change the startip timeout to only
|
||||
apply to the first phase of startup, not the full procedure.
|
||||
---
|
||||
src/core/cgroup.c | 4 ++--
|
||||
src/core/manager.c | 11 +++++++++--
|
||||
src/core/manager.h | 1 +
|
||||
3 files changed, 12 insertions(+), 4 deletions(-)
|
||||
|
||||
diff --git a/src/core/cgroup.c b/src/core/cgroup.c
|
||||
index 9248cb523b..6c6e4f5e7b 100644
|
||||
--- a/src/core/cgroup.c
|
||||
+++ b/src/core/cgroup.c
|
||||
@@ -300,7 +300,7 @@ void cgroup_context_apply(CGroupContext *c, CGroupControllerMask mask, const cha
|
||||
char buf[MAX(DECIMAL_STR_MAX(unsigned long), DECIMAL_STR_MAX(usec_t)) + 1];
|
||||
|
||||
sprintf(buf, "%lu\n",
|
||||
- state == MANAGER_STARTING && c->startup_cpu_shares != (unsigned long) -1 ? c->startup_cpu_shares :
|
||||
+ IN_SET(state, MANAGER_STARTING, MANAGER_INITIALIZING) && c->startup_cpu_shares != (unsigned long) -1 ? c->startup_cpu_shares :
|
||||
c->cpu_shares != (unsigned long) -1 ? c->cpu_shares : 1024);
|
||||
r = cg_set_attribute("cpu", path, "cpu.shares", buf);
|
||||
if (r < 0)
|
||||
@@ -328,7 +328,7 @@ void cgroup_context_apply(CGroupContext *c, CGroupControllerMask mask, const cha
|
||||
CGroupBlockIODeviceBandwidth *b;
|
||||
|
||||
if (!is_root) {
|
||||
- sprintf(buf, "%lu\n", state == MANAGER_STARTING && c->startup_blockio_weight != (unsigned long) -1 ? c->startup_blockio_weight :
|
||||
+ sprintf(buf, "%lu\n", IN_SET(state, MANAGER_STARTING, MANAGER_INITIALIZING) && c->startup_blockio_weight != (unsigned long) -1 ? c->startup_blockio_weight :
|
||||
c->blockio_weight != (unsigned long) -1 ? c->blockio_weight : 1000);
|
||||
r = cg_set_attribute("blkio", path, "blkio.weight", buf);
|
||||
if (r < 0)
|
||||
diff --git a/src/core/manager.c b/src/core/manager.c
|
||||
index 7639aeef19..9abdf475cf 100644
|
||||
--- a/src/core/manager.c
|
||||
+++ b/src/core/manager.c
|
||||
@@ -2837,7 +2837,7 @@ static bool manager_get_show_status(Manager *m) {
|
||||
if (m->no_console_output)
|
||||
return false;
|
||||
|
||||
- if (!IN_SET(manager_state(m), MANAGER_STARTING, MANAGER_STOPPING))
|
||||
+ if (!IN_SET(manager_state(m), MANAGER_INITIALIZING, MANAGER_STARTING, MANAGER_STOPPING))
|
||||
return false;
|
||||
|
||||
if (m->show_status > 0)
|
||||
@@ -2928,8 +2928,14 @@ ManagerState manager_state(Manager *m) {
|
||||
assert(m);
|
||||
|
||||
/* Did we ever finish booting? If not then we are still starting up */
|
||||
- if (!dual_timestamp_is_set(&m->finish_timestamp))
|
||||
+ if (!dual_timestamp_is_set(&m->finish_timestamp)) {
|
||||
+
|
||||
+ u = manager_get_unit(m, SPECIAL_BASIC_TARGET);
|
||||
+ if (!u || !UNIT_IS_ACTIVE_OR_RELOADING(unit_active_state(u)))
|
||||
+ return MANAGER_INITIALIZING;
|
||||
+
|
||||
return MANAGER_STARTING;
|
||||
+ }
|
||||
|
||||
/* Is the special shutdown target queued? If so, we are in shutdown state */
|
||||
u = manager_get_unit(m, SPECIAL_SHUTDOWN_TARGET);
|
||||
@@ -2955,6 +2961,7 @@ ManagerState manager_state(Manager *m) {
|
||||
}
|
||||
|
||||
static const char *const manager_state_table[_MANAGER_STATE_MAX] = {
|
||||
+ [MANAGER_INITIALIZING] = "initializing",
|
||||
[MANAGER_STARTING] = "starting",
|
||||
[MANAGER_RUNNING] = "running",
|
||||
[MANAGER_DEGRADED] = "degraded",
|
||||
diff --git a/src/core/manager.h b/src/core/manager.h
|
||||
index 7d26c3adea..8e3c146b42 100644
|
||||
--- a/src/core/manager.h
|
||||
+++ b/src/core/manager.h
|
||||
@@ -38,6 +38,7 @@
|
||||
typedef struct Manager Manager;
|
||||
|
||||
typedef enum ManagerState {
|
||||
+ MANAGER_INITIALIZING,
|
||||
MANAGER_STARTING,
|
||||
MANAGER_RUNNING,
|
||||
MANAGER_DEGRADED,
|
32
0043-update-TODO.patch
Normal file
32
0043-update-TODO.patch
Normal file
@ -0,0 +1,32 @@
|
||||
From d74f9e8e8a3dcddb043ef193e4bb14f58efa095f Mon Sep 17 00:00:00 2001
|
||||
From: Lennart Poettering <lennart@poettering.net>
|
||||
Date: Fri, 22 Aug 2014 18:10:22 +0200
|
||||
Subject: [PATCH] update TODO
|
||||
|
||||
---
|
||||
TODO | 5 +++--
|
||||
1 file changed, 3 insertions(+), 2 deletions(-)
|
||||
|
||||
diff --git a/TODO b/TODO
|
||||
index 3073f3a5a2..0fcd3a0b8e 100644
|
||||
--- a/TODO
|
||||
+++ b/TODO
|
||||
@@ -24,6 +24,9 @@ External:
|
||||
|
||||
Features:
|
||||
|
||||
+* apply start timeout during the "initializing" manager state only,
|
||||
+ instead of both "initializing" and "starting".
|
||||
+
|
||||
* journald: make use of uid-range.h to managed uid ranges to split
|
||||
journals in.
|
||||
|
||||
@@ -138,8 +141,6 @@ Features:
|
||||
* For timer units: add some mechanisms so that timer units that trigger immediately on boot do not have the services
|
||||
they run added to the initial transaction and thus confuse Type=idle.
|
||||
|
||||
-* Add timeout to early-boot, and shut down the system if it is hit. Solves the laptop-in-bag problem and is useful for embedded cases
|
||||
-
|
||||
* Run most system services with cgroupfs read-only and procfs with a more secure mode (doesn't work, since the hidepid= option is per-pid-namespace, not per-mount)
|
||||
|
||||
* sd-event: generate a failure of a default event loop is executed out-of-thread
|
27
0044-systemctl-fix-broken-list-unit-files-with-root.patch
Normal file
27
0044-systemctl-fix-broken-list-unit-files-with-root.patch
Normal file
@ -0,0 +1,27 @@
|
||||
From 41a451cc2901a5deb985aea4cc8de204a22e5612 Mon Sep 17 00:00:00 2001
|
||||
From: Lukas Nykryn <lnykryn@redhat.com>
|
||||
Date: Mon, 25 Aug 2014 15:29:50 +0200
|
||||
Subject: [PATCH] systemctl: fix broken list-unit-files with --root
|
||||
|
||||
This patch modifies unit_file_get_list which will now return
|
||||
hashmap of structures where f->path is *without* root_dir prefix.
|
||||
|
||||
This change should be ok, because current code either does not use
|
||||
root_dir at all or calls basename() on the f->path.
|
||||
---
|
||||
src/shared/install.c | 2 +-
|
||||
1 file changed, 1 insertion(+), 1 deletion(-)
|
||||
|
||||
diff --git a/src/shared/install.c b/src/shared/install.c
|
||||
index 4b09a69456..a07d1dd315 100644
|
||||
--- a/src/shared/install.c
|
||||
+++ b/src/shared/install.c
|
||||
@@ -2099,7 +2099,7 @@ int unit_file_get_list(
|
||||
if (!f)
|
||||
return -ENOMEM;
|
||||
|
||||
- f->path = path_make_absolute(de->d_name, units_dir);
|
||||
+ f->path = path_make_absolute(de->d_name, *i);
|
||||
if (!f->path)
|
||||
return -ENOMEM;
|
||||
|
244
0045-sd-event-split-run-into-prepare-wait-dispatch.patch
Normal file
244
0045-sd-event-split-run-into-prepare-wait-dispatch.patch
Normal file
@ -0,0 +1,244 @@
|
||||
From c45a5a74465a39280b855f9d720b2ab4779a47fa Mon Sep 17 00:00:00 2001
|
||||
From: Tom Gundersen <teg@jklm.no>
|
||||
Date: Fri, 15 Aug 2014 18:49:29 +0200
|
||||
Subject: [PATCH] sd-event: split run into prepare/wait/dispatch
|
||||
|
||||
This will allow sd-event to be integrated into an external event loop, which
|
||||
in turn will allow (say) glib-based applications to use our various libraries,
|
||||
without manually integrating each of them (bus, rtnl, dhcp, ...).
|
||||
|
||||
The external event-loop should integrate sd-event int he following way:
|
||||
|
||||
Every iteration must start with a call to sd_event_prepare(), which will
|
||||
return 0 if no event sources are ready to be processed, a positive value if
|
||||
they are and a negative value on error. sd_event_prepare() may only be called
|
||||
following sd_event_dispatch(); a call to sd_event_wait() indicating that no
|
||||
sources are ready to be dispatched; or a failed call to sd_event_dispatch() or
|
||||
sd_event_wait().
|
||||
|
||||
A successful call to sd_event_prepare() indicating that no event sources are
|
||||
ready to be dispatched must be followed by a call to sd_event_wait(),
|
||||
which will return 0 if it timed out without event sources being ready to
|
||||
be processed, a negative value on error and a positive value otherwise.
|
||||
sd_event_wait() may only be called following a successful call to
|
||||
sd_event_prepare() indicating that no event sources are ready to be dispatched.
|
||||
|
||||
If sd_event_wait() indicates that some events sources are ready to be
|
||||
dispatched, it must be followed by a call to sd_event_dispatch(). This
|
||||
is the only time sd_event_dispatch() may be called.
|
||||
---
|
||||
src/libsystemd/sd-event/sd-event.c | 122 +++++++++++++++++++++++++++++--------
|
||||
src/systemd/sd-event.h | 5 ++
|
||||
2 files changed, 102 insertions(+), 25 deletions(-)
|
||||
|
||||
diff --git a/src/libsystemd/sd-event/sd-event.c b/src/libsystemd/sd-event/sd-event.c
|
||||
index e062997a80..a71962c24c 100644
|
||||
--- a/src/libsystemd/sd-event/sd-event.c
|
||||
+++ b/src/libsystemd/sd-event/sd-event.c
|
||||
@@ -2210,12 +2210,8 @@ static int process_watchdog(sd_event *e) {
|
||||
return arm_watchdog(e);
|
||||
}
|
||||
|
||||
-_public_ int sd_event_run(sd_event *e, uint64_t timeout) {
|
||||
- struct epoll_event *ev_queue;
|
||||
- unsigned ev_queue_max;
|
||||
- sd_event_source *p;
|
||||
- int r, i, m;
|
||||
- bool timedout;
|
||||
+_public_ int sd_event_prepare(sd_event *e) {
|
||||
+ int r;
|
||||
|
||||
assert_return(e, -EINVAL);
|
||||
assert_return(!event_pid_changed(e), -ECHILD);
|
||||
@@ -2223,38 +2219,60 @@ _public_ int sd_event_run(sd_event *e, uint64_t timeout) {
|
||||
assert_return(e->state == SD_EVENT_PASSIVE, -EBUSY);
|
||||
|
||||
if (e->exit_requested)
|
||||
- return dispatch_exit(e);
|
||||
+ goto pending;
|
||||
|
||||
- sd_event_ref(e);
|
||||
e->iteration++;
|
||||
- e->state = SD_EVENT_RUNNING;
|
||||
|
||||
r = event_prepare(e);
|
||||
if (r < 0)
|
||||
- goto finish;
|
||||
+ return r;
|
||||
|
||||
r = event_arm_timer(e, &e->realtime);
|
||||
if (r < 0)
|
||||
- goto finish;
|
||||
+ return r;
|
||||
|
||||
r = event_arm_timer(e, &e->boottime);
|
||||
if (r < 0)
|
||||
- goto finish;
|
||||
+ return r;
|
||||
|
||||
r = event_arm_timer(e, &e->monotonic);
|
||||
if (r < 0)
|
||||
- goto finish;
|
||||
+ return r;
|
||||
|
||||
r = event_arm_timer(e, &e->realtime_alarm);
|
||||
if (r < 0)
|
||||
- goto finish;
|
||||
+ return r;
|
||||
|
||||
r = event_arm_timer(e, &e->boottime_alarm);
|
||||
if (r < 0)
|
||||
- goto finish;
|
||||
+ return r;
|
||||
|
||||
if (event_next_pending(e) || e->need_process_child)
|
||||
- timeout = 0;
|
||||
+ goto pending;
|
||||
+
|
||||
+ e->state = SD_EVENT_PREPARED;
|
||||
+
|
||||
+ return 0;
|
||||
+
|
||||
+pending:
|
||||
+ e->state = SD_EVENT_PREPARED;
|
||||
+ return sd_event_wait(e, 0);
|
||||
+}
|
||||
+
|
||||
+_public_ int sd_event_wait(sd_event *e, uint64_t timeout) {
|
||||
+ struct epoll_event *ev_queue;
|
||||
+ unsigned ev_queue_max;
|
||||
+ int r, m, i;
|
||||
+
|
||||
+ assert_return(e, -EINVAL);
|
||||
+ assert_return(!event_pid_changed(e), -ECHILD);
|
||||
+ assert_return(e->state != SD_EVENT_FINISHED, -ESTALE);
|
||||
+ assert_return(e->state == SD_EVENT_PREPARED, -EBUSY);
|
||||
+
|
||||
+ if (e->exit_requested) {
|
||||
+ e->state = SD_EVENT_PENDING;
|
||||
+ return 1;
|
||||
+ }
|
||||
|
||||
ev_queue_max = CLAMP(e->n_sources, 1U, EPOLL_QUEUE_MAX);
|
||||
ev_queue = newa(struct epoll_event, ev_queue_max);
|
||||
@@ -2262,12 +2280,16 @@ _public_ int sd_event_run(sd_event *e, uint64_t timeout) {
|
||||
m = epoll_wait(e->epoll_fd, ev_queue, ev_queue_max,
|
||||
timeout == (uint64_t) -1 ? -1 : (int) ((timeout + USEC_PER_MSEC - 1) / USEC_PER_MSEC));
|
||||
if (m < 0) {
|
||||
- r = errno == EAGAIN || errno == EINTR ? 1 : -errno;
|
||||
+ if (errno == EINTR) {
|
||||
+ e->state = SD_EVENT_PENDING;
|
||||
+ return 1;
|
||||
+ }
|
||||
+
|
||||
+ r = -errno;
|
||||
+
|
||||
goto finish;
|
||||
}
|
||||
|
||||
- timedout = m == 0;
|
||||
-
|
||||
dual_timestamp_get(&e->timestamp);
|
||||
e->timestamp_boottime = now(CLOCK_BOOTTIME);
|
||||
|
||||
@@ -2324,21 +2346,71 @@ _public_ int sd_event_run(sd_event *e, uint64_t timeout) {
|
||||
goto finish;
|
||||
}
|
||||
|
||||
- p = event_next_pending(e);
|
||||
- if (!p) {
|
||||
- r = !timedout;
|
||||
- goto finish;
|
||||
+ if (event_next_pending(e)) {
|
||||
+ e->state = SD_EVENT_PENDING;
|
||||
+
|
||||
+ return 1;
|
||||
}
|
||||
|
||||
- r = source_dispatch(p);
|
||||
+ r = 0;
|
||||
|
||||
finish:
|
||||
e->state = SD_EVENT_PASSIVE;
|
||||
- sd_event_unref(e);
|
||||
|
||||
return r;
|
||||
}
|
||||
|
||||
+_public_ int sd_event_dispatch(sd_event *e) {
|
||||
+ sd_event_source *p;
|
||||
+ int r;
|
||||
+
|
||||
+ assert_return(e, -EINVAL);
|
||||
+ assert_return(!event_pid_changed(e), -ECHILD);
|
||||
+ assert_return(e->state != SD_EVENT_FINISHED, -ESTALE);
|
||||
+ assert_return(e->state == SD_EVENT_PENDING, -EBUSY);
|
||||
+
|
||||
+ if (e->exit_requested)
|
||||
+ return dispatch_exit(e);
|
||||
+
|
||||
+ p = event_next_pending(e);
|
||||
+ if (p) {
|
||||
+ sd_event_ref(e);
|
||||
+
|
||||
+ e->state = SD_EVENT_RUNNING;
|
||||
+ r = source_dispatch(p);
|
||||
+ e->state = SD_EVENT_PASSIVE;
|
||||
+
|
||||
+ sd_event_unref(e);
|
||||
+
|
||||
+ return r;
|
||||
+ }
|
||||
+
|
||||
+ e->state = SD_EVENT_PASSIVE;
|
||||
+
|
||||
+ return 1;
|
||||
+}
|
||||
+
|
||||
+_public_ int sd_event_run(sd_event *e, uint64_t timeout) {
|
||||
+ int r;
|
||||
+
|
||||
+ assert_return(e, -EINVAL);
|
||||
+ assert_return(!event_pid_changed(e), -ECHILD);
|
||||
+ assert_return(e->state != SD_EVENT_FINISHED, -ESTALE);
|
||||
+ assert_return(e->state == SD_EVENT_PASSIVE, -EBUSY);
|
||||
+
|
||||
+ r = sd_event_prepare(e);
|
||||
+ if (r > 0)
|
||||
+ return sd_event_dispatch(e);
|
||||
+ else if (r < 0)
|
||||
+ return r;
|
||||
+
|
||||
+ r = sd_event_wait(e, timeout);
|
||||
+ if (r > 0)
|
||||
+ return sd_event_dispatch(e);
|
||||
+ else
|
||||
+ return r;
|
||||
+}
|
||||
+
|
||||
_public_ int sd_event_loop(sd_event *e) {
|
||||
int r;
|
||||
|
||||
diff --git a/src/systemd/sd-event.h b/src/systemd/sd-event.h
|
||||
index d96852a763..8e013b33f6 100644
|
||||
--- a/src/systemd/sd-event.h
|
||||
+++ b/src/systemd/sd-event.h
|
||||
@@ -52,6 +52,8 @@ enum {
|
||||
|
||||
enum {
|
||||
SD_EVENT_PASSIVE,
|
||||
+ SD_EVENT_PREPARED,
|
||||
+ SD_EVENT_PENDING,
|
||||
SD_EVENT_RUNNING,
|
||||
SD_EVENT_EXITING,
|
||||
SD_EVENT_FINISHED
|
||||
@@ -84,6 +86,9 @@ int sd_event_add_defer(sd_event *e, sd_event_source **s, sd_event_handler_t call
|
||||
int sd_event_add_post(sd_event *e, sd_event_source **s, sd_event_handler_t callback, void *userdata);
|
||||
int sd_event_add_exit(sd_event *e, sd_event_source **s, sd_event_handler_t callback, void *userdata);
|
||||
|
||||
+int sd_event_prepare(sd_event *e);
|
||||
+int sd_event_wait(sd_event *e, uint64_t timeout);
|
||||
+int sd_event_dispatch(sd_event *e);
|
||||
int sd_event_run(sd_event *e, uint64_t timeout);
|
||||
int sd_event_loop(sd_event *e);
|
||||
int sd_event_exit(sd_event *e, int code);
|
@ -0,0 +1,27 @@
|
||||
From 6d148a842ebb04a9a9bc2853e167a9d8eddf8cd8 Mon Sep 17 00:00:00 2001
|
||||
From: Tom Gundersen <teg@jklm.no>
|
||||
Date: Tue, 26 Aug 2014 00:22:06 +0200
|
||||
Subject: [PATCH] sd-event: sd_event_prepare - stay in PREPARED if
|
||||
sd_event_wait() indicates that no sources are pending
|
||||
|
||||
---
|
||||
src/libsystemd/sd-event/sd-event.c | 6 +++++-
|
||||
1 file changed, 5 insertions(+), 1 deletion(-)
|
||||
|
||||
diff --git a/src/libsystemd/sd-event/sd-event.c b/src/libsystemd/sd-event/sd-event.c
|
||||
index a71962c24c..32777e386b 100644
|
||||
--- a/src/libsystemd/sd-event/sd-event.c
|
||||
+++ b/src/libsystemd/sd-event/sd-event.c
|
||||
@@ -2256,7 +2256,11 @@ _public_ int sd_event_prepare(sd_event *e) {
|
||||
|
||||
pending:
|
||||
e->state = SD_EVENT_PREPARED;
|
||||
- return sd_event_wait(e, 0);
|
||||
+ r = sd_event_wait(e, 0);
|
||||
+ if (r == 0)
|
||||
+ e->state = SD_EVENT_PREPARED;
|
||||
+
|
||||
+ return r;
|
||||
}
|
||||
|
||||
_public_ int sd_event_wait(sd_event *e, uint64_t timeout) {
|
30
0047-update-TODO.patch
Normal file
30
0047-update-TODO.patch
Normal file
@ -0,0 +1,30 @@
|
||||
From 42aeb14a4a0fa7d43da96a8ed0fb0e180a2dd5c8 Mon Sep 17 00:00:00 2001
|
||||
From: Lennart Poettering <lennart@poettering.net>
|
||||
Date: Tue, 26 Aug 2014 03:59:05 +0200
|
||||
Subject: [PATCH] update TODO
|
||||
|
||||
---
|
||||
TODO | 9 ++++++++-
|
||||
1 file changed, 8 insertions(+), 1 deletion(-)
|
||||
|
||||
diff --git a/TODO b/TODO
|
||||
index 0fcd3a0b8e..471d3b29bc 100644
|
||||
--- a/TODO
|
||||
+++ b/TODO
|
||||
@@ -24,8 +24,15 @@ External:
|
||||
|
||||
Features:
|
||||
|
||||
+* remove multi-seat-x now
|
||||
+
|
||||
+* refcounting in sd-resolve is borked
|
||||
+
|
||||
+* exponential backoff in timesyncd and resolved when we cannot reach a server
|
||||
+
|
||||
* apply start timeout during the "initializing" manager state only,
|
||||
- instead of both "initializing" and "starting".
|
||||
+ instead of both "initializing" and "starting". maybe rename the
|
||||
+ timeout to "initialization-timeout" then or so?
|
||||
|
||||
* journald: make use of uid-range.h to managed uid ranges to split
|
||||
journals in.
|
@ -0,0 +1,26 @@
|
||||
From 4fc13f521ab44eb55c599b07c18860c1aeca35a7 Mon Sep 17 00:00:00 2001
|
||||
From: Lennart Poettering <lennart@poettering.net>
|
||||
Date: Tue, 26 Aug 2014 04:03:24 +0200
|
||||
Subject: [PATCH] Revert "systemctl: fix broken list-unit-files with --root"
|
||||
|
||||
This reverts commit 41a451cc2901a5deb985aea4cc8de204a22e5612.
|
||||
|
||||
This breaks checks for masking of units file, since we invoke
|
||||
null_or_empty_path() on the resulting path.
|
||||
---
|
||||
src/shared/install.c | 2 +-
|
||||
1 file changed, 1 insertion(+), 1 deletion(-)
|
||||
|
||||
diff --git a/src/shared/install.c b/src/shared/install.c
|
||||
index a07d1dd315..4b09a69456 100644
|
||||
--- a/src/shared/install.c
|
||||
+++ b/src/shared/install.c
|
||||
@@ -2099,7 +2099,7 @@ int unit_file_get_list(
|
||||
if (!f)
|
||||
return -ENOMEM;
|
||||
|
||||
- f->path = path_make_absolute(de->d_name, *i);
|
||||
+ f->path = path_make_absolute(de->d_name, units_dir);
|
||||
if (!f->path)
|
||||
return -ENOMEM;
|
||||
|
60
0049-udev-hwdb-do-not-look-at-usb_device-parents.patch
Normal file
60
0049-udev-hwdb-do-not-look-at-usb_device-parents.patch
Normal file
@ -0,0 +1,60 @@
|
||||
From 77cf759ea05bea476cdcb8d0dcd04c4e6fb3b2ff Mon Sep 17 00:00:00 2001
|
||||
From: Kay Sievers <kay@vrfy.org>
|
||||
Date: Tue, 26 Aug 2014 18:27:36 +0200
|
||||
Subject: [PATCH] udev: hwdb - do not look at "usb_device" parents
|
||||
|
||||
Based on a patch from Simon McVittie <simon.mcvittie@collabora.co.uk>.
|
||||
|
||||
Bug-Debian: https://bugs.debian.org/cgi-bin/bugreport.cgi?bug=758050
|
||||
---
|
||||
src/udev/udev-builtin-hwdb.c | 22 ++++++++++++++--------
|
||||
1 file changed, 14 insertions(+), 8 deletions(-)
|
||||
|
||||
diff --git a/src/udev/udev-builtin-hwdb.c b/src/udev/udev-builtin-hwdb.c
|
||||
index cac97e756b..695a31a12f 100644
|
||||
--- a/src/udev/udev-builtin-hwdb.c
|
||||
+++ b/src/udev/udev-builtin-hwdb.c
|
||||
@@ -88,9 +88,10 @@ static int udev_builtin_hwdb_search(struct udev_device *dev, struct udev_device
|
||||
const char *filter, bool test) {
|
||||
struct udev_device *d;
|
||||
char s[16];
|
||||
- int n = 0;
|
||||
+ bool last = false;
|
||||
+ int r = 0;
|
||||
|
||||
- for (d = srcdev; d; d = udev_device_get_parent(d)) {
|
||||
+ for (d = srcdev; d && !last; d = udev_device_get_parent(d)) {
|
||||
const char *dsubsys;
|
||||
const char *modalias = NULL;
|
||||
|
||||
@@ -104,19 +105,24 @@ static int udev_builtin_hwdb_search(struct udev_device *dev, struct udev_device
|
||||
|
||||
modalias = udev_device_get_property_value(d, "MODALIAS");
|
||||
|
||||
- /* the usb_device does not have a modalias, compose one */
|
||||
- if (!modalias && streq(dsubsys, "usb"))
|
||||
- modalias = modalias_usb(d, s, sizeof(s));
|
||||
+ if (streq(dsubsys, "usb") && streq_ptr(udev_device_get_devtype(d), "usb_device")) {
|
||||
+ /* if the usb_device does not have a modalias, compose one */
|
||||
+ if (!modalias)
|
||||
+ modalias = modalias_usb(d, s, sizeof(s));
|
||||
+
|
||||
+ /* avoid looking at any parent device, they are usually just a USB hub */
|
||||
+ last = true;
|
||||
+ }
|
||||
|
||||
if (!modalias)
|
||||
continue;
|
||||
|
||||
- n = udev_builtin_hwdb_lookup(dev, prefix, modalias, filter, test);
|
||||
- if (n > 0)
|
||||
+ r = udev_builtin_hwdb_lookup(dev, prefix, modalias, filter, test);
|
||||
+ if (r > 0)
|
||||
break;
|
||||
}
|
||||
|
||||
- return n;
|
||||
+ return r;
|
||||
}
|
||||
|
||||
static int builtin_hwdb(struct udev_device *dev, int argc, char *argv[], bool test) {
|
24
0050-update-TODO.patch
Normal file
24
0050-update-TODO.patch
Normal file
@ -0,0 +1,24 @@
|
||||
From 8dac15b6e9792c2b0f503ddf78ac499817904a6f Mon Sep 17 00:00:00 2001
|
||||
From: Lennart Poettering <lennart@poettering.net>
|
||||
Date: Tue, 26 Aug 2014 20:23:49 +0200
|
||||
Subject: [PATCH] update TODO
|
||||
|
||||
---
|
||||
TODO | 4 ++++
|
||||
1 file changed, 4 insertions(+)
|
||||
|
||||
diff --git a/TODO b/TODO
|
||||
index 471d3b29bc..09f82d3c37 100644
|
||||
--- a/TODO
|
||||
+++ b/TODO
|
||||
@@ -24,6 +24,10 @@ External:
|
||||
|
||||
Features:
|
||||
|
||||
+* dbus: add new message hdr field for allowing interactive auth, write spec for it. update dbus spec to mandate that unknown flags *must* be ignored...
|
||||
+
|
||||
+* maybe introduce AssertXYZ= similar to ConditionXYZ= that causes a unit to fail (instead of skipping it) if some condition is not true...
|
||||
+
|
||||
* remove multi-seat-x now
|
||||
|
||||
* refcounting in sd-resolve is borked
|
33
0051-NEWS-Fix-typos.patch
Normal file
33
0051-NEWS-Fix-typos.patch
Normal file
@ -0,0 +1,33 @@
|
||||
From daa05349dfefb12638c96e034c11be613bdc39b7 Mon Sep 17 00:00:00 2001
|
||||
From: Ansgar Burchardt <ansgar@43-1.org>
|
||||
Date: Tue, 26 Aug 2014 00:19:54 +0200
|
||||
Subject: [PATCH] NEWS: Fix typos.
|
||||
|
||||
---
|
||||
NEWS | 6 +++---
|
||||
1 file changed, 3 insertions(+), 3 deletions(-)
|
||||
|
||||
diff --git a/NEWS b/NEWS
|
||||
index 7dad765a33..2fca2cdc93 100644
|
||||
--- a/NEWS
|
||||
+++ b/NEWS
|
||||
@@ -42,8 +42,8 @@ CHANGES WITH 216:
|
||||
|
||||
* systemd-resolved now includes a caching DNS stub resolver
|
||||
and a complete LLMNR name resolution implementation. A new
|
||||
- NSS module "nss-resolve" has been added which make be used
|
||||
- of glibc's own "nss-dns" to resolve hostnames via
|
||||
+ NSS module "nss-resolve" has been added which can be used
|
||||
+ instead of glibc's own "nss-dns" to resolve hostnames via
|
||||
systemd-resolved. Hostnames, addresses and arbitrary RRs may
|
||||
be resolved via systemd-resolved D-Bus APIs. In contrast to
|
||||
the glibc internal resolver systemd-resolved is aware of
|
||||
@@ -606,7 +606,7 @@ CHANGES WITH 214:
|
||||
|
||||
* Access modes specified in tmpfiles snippets may now be
|
||||
prefixed with "~", which indicates that they shall be masked
|
||||
- by whether the existing file or directly is currently
|
||||
+ by whether the existing file or directory is currently
|
||||
writable, readable or executable at all. Also, if specified,
|
||||
the sgid/suid/sticky bits will be masked for all
|
||||
non-directories.
|
22
0052-missing-add-BPF_XOR.patch
Normal file
22
0052-missing-add-BPF_XOR.patch
Normal file
@ -0,0 +1,22 @@
|
||||
From 7965435e588c8d2fb824c5fd4b8c2739bc30acdf Mon Sep 17 00:00:00 2001
|
||||
From: Michael Olbrich <m.olbrich@pengutronix.de>
|
||||
Date: Thu, 21 Aug 2014 12:38:08 +0200
|
||||
Subject: [PATCH] missing: add BPF_XOR
|
||||
|
||||
BPF_XOR was introduced in kernel 3.7
|
||||
---
|
||||
src/shared/missing.h | 4 ++++
|
||||
1 file changed, 4 insertions(+)
|
||||
|
||||
diff --git a/src/shared/missing.h b/src/shared/missing.h
|
||||
index a9dd274274..c80ed2ad99 100644
|
||||
--- a/src/shared/missing.h
|
||||
+++ b/src/shared/missing.h
|
||||
@@ -593,3 +593,7 @@ static inline int setns(int fd, int nstype) {
|
||||
#ifndef NET_NAME_RENAMED
|
||||
# define NET_NAME_RENAMED 4
|
||||
#endif
|
||||
+
|
||||
+#ifndef BPF_XOR
|
||||
+# define BPF_XOR 0xa0
|
||||
+#endif
|
@ -0,0 +1,23 @@
|
||||
From 32dfe42c66085c55916e5306a9a07d42d3958b6b Mon Sep 17 00:00:00 2001
|
||||
From: =?UTF-8?q?=C5=81ukasz=20Stelmach?= <stlman@poczta.fm>
|
||||
Date: Tue, 26 Aug 2014 12:28:28 +0200
|
||||
Subject: [PATCH] networkd-wait-online: add missing short option 'i' to
|
||||
optstring
|
||||
|
||||
---
|
||||
src/network/networkd-wait-online.c | 2 +-
|
||||
1 file changed, 1 insertion(+), 1 deletion(-)
|
||||
|
||||
diff --git a/src/network/networkd-wait-online.c b/src/network/networkd-wait-online.c
|
||||
index 6c2fdd1b2c..714343656b 100644
|
||||
--- a/src/network/networkd-wait-online.c
|
||||
+++ b/src/network/networkd-wait-online.c
|
||||
@@ -59,7 +59,7 @@ static int parse_argv(int argc, char *argv[]) {
|
||||
assert(argc >= 0);
|
||||
assert(argv);
|
||||
|
||||
- while ((c = getopt_long(argc, argv, "+hq", options, NULL)) >= 0)
|
||||
+ while ((c = getopt_long(argc, argv, "+hiq", options, NULL)) >= 0)
|
||||
|
||||
switch (c) {
|
||||
|
@ -0,0 +1,33 @@
|
||||
From 52754725e185f1331f821d85ed2ef78fb92af1fe Mon Sep 17 00:00:00 2001
|
||||
From: Filipe Brandenburger <filbranden@google.com>
|
||||
Date: Mon, 25 Aug 2014 22:05:02 -0700
|
||||
Subject: [PATCH] test-compress: make sure asserts with side effects use
|
||||
assert_se()
|
||||
|
||||
Otherwise the test fails when built with CPPFLAGS='-DNDEBUG' which disables
|
||||
assertions.
|
||||
|
||||
Tested:
|
||||
- make check TESTS='test-compress' CPPFLAGS='-DNDEBUG'
|
||||
---
|
||||
src/journal/test-compress.c | 4 ++--
|
||||
1 file changed, 2 insertions(+), 2 deletions(-)
|
||||
|
||||
diff --git a/src/journal/test-compress.c b/src/journal/test-compress.c
|
||||
index f5f5f8df39..026d630ac2 100644
|
||||
--- a/src/journal/test-compress.c
|
||||
+++ b/src/journal/test-compress.c
|
||||
@@ -145,11 +145,11 @@ static void test_compress_stream(int compression,
|
||||
|
||||
assert_se((dst = mkostemp_safe(pattern, O_RDWR|O_CLOEXEC)) >= 0);
|
||||
|
||||
- assert(compress(src, dst, -1) == 0);
|
||||
+ assert_se(compress(src, dst, -1) == 0);
|
||||
|
||||
if (cat) {
|
||||
assert_se(asprintf(&cmd, "%s %s | diff %s -", cat, pattern, srcfile) > 0);
|
||||
- assert(system(cmd) == 0);
|
||||
+ assert_se(system(cmd) == 0);
|
||||
}
|
||||
|
||||
log_debug("/* test decompression */");
|
78
0055-test-path-util-use-assert_se-in-all-assertions.patch
Normal file
78
0055-test-path-util-use-assert_se-in-all-assertions.patch
Normal file
@ -0,0 +1,78 @@
|
||||
From 8d95631ea6c039a60bb7ac456f687a8fdf0c4381 Mon Sep 17 00:00:00 2001
|
||||
From: Filipe Brandenburger <filbranden@google.com>
|
||||
Date: Mon, 25 Aug 2014 22:05:03 -0700
|
||||
Subject: [PATCH] test-path-util: use assert_se in all assertions
|
||||
|
||||
Otherwise they get optimized out when CPPFLAGS='-DNDEBUG' is used, and that
|
||||
causes the tests to fail.
|
||||
|
||||
Tested:
|
||||
- make check TESTS='test-path-util' CPPFLAGS='-DNDEBUG'
|
||||
---
|
||||
src/test/test-path-util.c | 30 +++++++++++++++---------------
|
||||
1 file changed, 15 insertions(+), 15 deletions(-)
|
||||
|
||||
diff --git a/src/test/test-path-util.c b/src/test/test-path-util.c
|
||||
index c8dcd85397..01afb3e6fe 100644
|
||||
--- a/src/test/test-path-util.c
|
||||
+++ b/src/test/test-path-util.c
|
||||
@@ -79,35 +79,35 @@ static void test_path(void) {
|
||||
char p2[] = "//aaa/.////ccc";
|
||||
char p3[] = "/./";
|
||||
|
||||
- assert(path_equal(path_kill_slashes(p1), "aaa/bbb/ccc"));
|
||||
- assert(path_equal(path_kill_slashes(p2), "/aaa/./ccc"));
|
||||
- assert(path_equal(path_kill_slashes(p3), "/./"));
|
||||
+ assert_se(path_equal(path_kill_slashes(p1), "aaa/bbb/ccc"));
|
||||
+ assert_se(path_equal(path_kill_slashes(p2), "/aaa/./ccc"));
|
||||
+ assert_se(path_equal(path_kill_slashes(p3), "/./"));
|
||||
}
|
||||
}
|
||||
|
||||
static void test_find_binary(const char *self) {
|
||||
char *p;
|
||||
|
||||
- assert(find_binary("/bin/sh", &p) == 0);
|
||||
+ assert_se(find_binary("/bin/sh", &p) == 0);
|
||||
puts(p);
|
||||
- assert(streq(p, "/bin/sh"));
|
||||
+ assert_se(streq(p, "/bin/sh"));
|
||||
free(p);
|
||||
|
||||
- assert(find_binary(self, &p) == 0);
|
||||
+ assert_se(find_binary(self, &p) == 0);
|
||||
puts(p);
|
||||
- assert(endswith(p, "/test-path-util"));
|
||||
- assert(path_is_absolute(p));
|
||||
+ assert_se(endswith(p, "/test-path-util"));
|
||||
+ assert_se(path_is_absolute(p));
|
||||
free(p);
|
||||
|
||||
- assert(find_binary("sh", &p) == 0);
|
||||
+ assert_se(find_binary("sh", &p) == 0);
|
||||
puts(p);
|
||||
- assert(endswith(p, "/sh"));
|
||||
- assert(path_is_absolute(p));
|
||||
+ assert_se(endswith(p, "/sh"));
|
||||
+ assert_se(path_is_absolute(p));
|
||||
free(p);
|
||||
|
||||
- assert(find_binary("xxxx-xxxx", &p) == -ENOENT);
|
||||
+ assert_se(find_binary("xxxx-xxxx", &p) == -ENOENT);
|
||||
|
||||
- assert(find_binary("/some/dir/xxxx-xxxx", &p) == -ENOENT);
|
||||
+ assert_se(find_binary("/some/dir/xxxx-xxxx", &p) == -ENOENT);
|
||||
}
|
||||
|
||||
static void test_prefixes(void) {
|
||||
@@ -156,8 +156,8 @@ static void test_prefixes(void) {
|
||||
|
||||
b = false;
|
||||
PATH_FOREACH_PREFIX_MORE(s, "") {
|
||||
- assert(!b);
|
||||
- assert(streq(s, ""));
|
||||
+ assert_se(!b);
|
||||
+ assert_se(streq(s, ""));
|
||||
b = true;
|
||||
}
|
||||
}
|
@ -0,0 +1,27 @@
|
||||
From 684fc8927e0f83496d4384ac434e265f7cd7a87b Mon Sep 17 00:00:00 2001
|
||||
From: Filipe Brandenburger <filbranden@google.com>
|
||||
Date: Mon, 25 Aug 2014 22:05:04 -0700
|
||||
Subject: [PATCH] test-util: use assert_se() for call to safe_mkdir with side
|
||||
effect
|
||||
|
||||
Otherwise it gets optimized out when CPPFLAGS='-DNDEBUG' is used.
|
||||
|
||||
Tested:
|
||||
- make check TESTS='test-util' CPPFLAGS='-DNDEBUG'
|
||||
---
|
||||
src/test/test-util.c | 2 +-
|
||||
1 file changed, 1 insertion(+), 1 deletion(-)
|
||||
|
||||
diff --git a/src/test/test-util.c b/src/test/test-util.c
|
||||
index 34d5f2ed7d..4d9b28f9c8 100644
|
||||
--- a/src/test/test-util.c
|
||||
+++ b/src/test/test-util.c
|
||||
@@ -863,7 +863,7 @@ static void test_readlink_and_make_absolute(void) {
|
||||
char name_alias[] = "/tmp/test-readlink_and_make_absolute-alias";
|
||||
char *r = NULL;
|
||||
|
||||
- assert(mkdir_safe(tempdir, 0755, getuid(), getgid()) >= 0);
|
||||
+ assert_se(mkdir_safe(tempdir, 0755, getuid(), getgid()) >= 0);
|
||||
assert_se(touch(name) >= 0);
|
||||
|
||||
assert_se(symlink(name, name_alias) >= 0);
|
@ -0,0 +1,65 @@
|
||||
From bb19cb17076bbec942ad08f94d41ba36b28a5a13 Mon Sep 17 00:00:00 2001
|
||||
From: Lennart Poettering <lennart@poettering.net>
|
||||
Date: Tue, 26 Aug 2014 20:35:31 +0200
|
||||
Subject: [PATCH] sd-bus: remove unused call bus_kernel_create_monitor()
|
||||
|
||||
Noticed by Djalal Harouni
|
||||
---
|
||||
src/libsystemd/sd-bus/bus-kernel.c | 31 -------------------------------
|
||||
src/libsystemd/sd-bus/bus-kernel.h | 1 -
|
||||
2 files changed, 32 deletions(-)
|
||||
|
||||
diff --git a/src/libsystemd/sd-bus/bus-kernel.c b/src/libsystemd/sd-bus/bus-kernel.c
|
||||
index 3ca271c704..03c4165095 100644
|
||||
--- a/src/libsystemd/sd-bus/bus-kernel.c
|
||||
+++ b/src/libsystemd/sd-bus/bus-kernel.c
|
||||
@@ -1535,37 +1535,6 @@ int bus_kernel_create_domain(const char *name, char **s) {
|
||||
return fd;
|
||||
}
|
||||
|
||||
-int bus_kernel_create_monitor(const char *bus) {
|
||||
- struct kdbus_cmd_hello *hello;
|
||||
- int fd;
|
||||
-
|
||||
- assert(bus);
|
||||
-
|
||||
- fd = bus_kernel_open_bus_fd(bus, NULL);
|
||||
- if (fd < 0)
|
||||
- return fd;
|
||||
-
|
||||
- hello = alloca0(sizeof(struct kdbus_cmd_hello));
|
||||
- hello->size = sizeof(struct kdbus_cmd_hello);
|
||||
- hello->conn_flags = KDBUS_HELLO_ACTIVATOR;
|
||||
- hello->pool_size = KDBUS_POOL_SIZE;
|
||||
-
|
||||
- if (ioctl(fd, KDBUS_CMD_HELLO, hello) < 0) {
|
||||
- safe_close(fd);
|
||||
- return -errno;
|
||||
- }
|
||||
-
|
||||
- /* The higher 32bit of both flags fields are considered
|
||||
- * 'incompatible flags'. Refuse them all for now. */
|
||||
- if (hello->bus_flags > 0xFFFFFFFFULL ||
|
||||
- hello->conn_flags > 0xFFFFFFFFULL) {
|
||||
- safe_close(fd);
|
||||
- return -ENOTSUP;
|
||||
- }
|
||||
-
|
||||
- return fd;
|
||||
-}
|
||||
-
|
||||
int bus_kernel_try_close(sd_bus *bus) {
|
||||
assert(bus);
|
||||
assert(bus->is_kernel);
|
||||
diff --git a/src/libsystemd/sd-bus/bus-kernel.h b/src/libsystemd/sd-bus/bus-kernel.h
|
||||
index 87f98c58bf..448dd3a797 100644
|
||||
--- a/src/libsystemd/sd-bus/bus-kernel.h
|
||||
+++ b/src/libsystemd/sd-bus/bus-kernel.h
|
||||
@@ -70,7 +70,6 @@ int bus_kernel_make_starter(int fd, const char *name, bool activating, bool acce
|
||||
|
||||
int bus_kernel_create_bus(const char *name, bool world, char **s);
|
||||
int bus_kernel_create_domain(const char *name, char **s);
|
||||
-int bus_kernel_create_monitor(const char *bus);
|
||||
|
||||
int bus_kernel_pop_memfd(sd_bus *bus, void **address, size_t *mapped, size_t *allocated);
|
||||
void bus_kernel_push_memfd(sd_bus *bus, int fd, void *address, size_t mapped, size_t allocated);
|
@ -0,0 +1,25 @@
|
||||
From 498cfc230af8f83675be2e92057956f1792969e4 Mon Sep 17 00:00:00 2001
|
||||
From: Sjoerd Simons <sjoerd.simons@collabora.co.uk>
|
||||
Date: Sat, 23 Aug 2014 21:11:44 +0200
|
||||
Subject: [PATCH] systemctl: Correct error message printed when
|
||||
bus_process_wait fails
|
||||
|
||||
Actually use the variable containing the return code of bus_process_wait when
|
||||
printing the error message as a result of it failing.
|
||||
---
|
||||
src/systemctl/systemctl.c | 2 +-
|
||||
1 file changed, 1 insertion(+), 1 deletion(-)
|
||||
|
||||
diff --git a/src/systemctl/systemctl.c b/src/systemctl/systemctl.c
|
||||
index d9b8bee28d..65348193b7 100644
|
||||
--- a/src/systemctl/systemctl.c
|
||||
+++ b/src/systemctl/systemctl.c
|
||||
@@ -2382,7 +2382,7 @@ static int wait_for_jobs(sd_bus *bus, Set *s) {
|
||||
while (!set_isempty(s)) {
|
||||
q = bus_process_wait(bus);
|
||||
if (q < 0) {
|
||||
- log_error("Failed to wait for response: %s", strerror(-r));
|
||||
+ log_error("Failed to wait for response: %s", strerror(-q));
|
||||
return q;
|
||||
}
|
||||
|
@ -0,0 +1,36 @@
|
||||
From f2322f0b64107b2eee1fadb6c59857381277a9f8 Mon Sep 17 00:00:00 2001
|
||||
From: Hristo Venev <mustrumr97@gmail.com>
|
||||
Date: Tue, 26 Aug 2014 20:40:35 +0200
|
||||
Subject: [PATCH] sd-bus: don't include internal header memfd.h in public
|
||||
header sd-bus.h
|
||||
|
||||
https://bugs.freedesktop.org/show_bug.cgi?id=83097
|
||||
---
|
||||
src/libsystemd/sd-bus/bus-message.c | 1 +
|
||||
src/systemd/sd-bus.h | 1 -
|
||||
2 files changed, 1 insertion(+), 1 deletion(-)
|
||||
|
||||
diff --git a/src/libsystemd/sd-bus/bus-message.c b/src/libsystemd/sd-bus/bus-message.c
|
||||
index c058b06f41..d00455a112 100644
|
||||
--- a/src/libsystemd/sd-bus/bus-message.c
|
||||
+++ b/src/libsystemd/sd-bus/bus-message.c
|
||||
@@ -28,6 +28,7 @@
|
||||
#include "strv.h"
|
||||
#include "time-util.h"
|
||||
#include "cgroup-util.h"
|
||||
+#include "memfd.h"
|
||||
|
||||
#include "sd-bus.h"
|
||||
#include "bus-message.h"
|
||||
diff --git a/src/systemd/sd-bus.h b/src/systemd/sd-bus.h
|
||||
index 1e23a93a60..036ab556c1 100644
|
||||
--- a/src/systemd/sd-bus.h
|
||||
+++ b/src/systemd/sd-bus.h
|
||||
@@ -28,7 +28,6 @@
|
||||
|
||||
#include "sd-id128.h"
|
||||
#include "sd-event.h"
|
||||
-#include "memfd.h"
|
||||
#include "_sd-common.h"
|
||||
|
||||
_SD_BEGIN_DECLARATIONS;
|
@ -0,0 +1,47 @@
|
||||
From 24a5d6b04e17d447cf122f02a8a2dedd843cce45 Mon Sep 17 00:00:00 2001
|
||||
From: Lennart Poettering <lennart@poettering.net>
|
||||
Date: Tue, 26 Aug 2014 21:03:20 +0200
|
||||
Subject: [PATCH] util: make sure reset_all_signal_handlers() continues with
|
||||
all other signal handlers when one sigaction() fails
|
||||
|
||||
After all, we usually don't check for failures here, and it is better to
|
||||
do as much as we can...
|
||||
---
|
||||
src/shared/util.c | 9 +++++----
|
||||
1 file changed, 5 insertions(+), 4 deletions(-)
|
||||
|
||||
diff --git a/src/shared/util.c b/src/shared/util.c
|
||||
index fc6f668726..4af2d3ceba 100644
|
||||
--- a/src/shared/util.c
|
||||
+++ b/src/shared/util.c
|
||||
@@ -937,7 +937,7 @@ int readlink_and_canonicalize(const char *p, char **r) {
|
||||
}
|
||||
|
||||
int reset_all_signal_handlers(void) {
|
||||
- int sig;
|
||||
+ int sig, r = 0;
|
||||
|
||||
for (sig = 1; sig < _NSIG; sig++) {
|
||||
struct sigaction sa = {
|
||||
@@ -945,17 +945,18 @@ int reset_all_signal_handlers(void) {
|
||||
.sa_flags = SA_RESTART,
|
||||
};
|
||||
|
||||
+ /* These two cannot be caught... */
|
||||
if (sig == SIGKILL || sig == SIGSTOP)
|
||||
continue;
|
||||
|
||||
/* On Linux the first two RT signals are reserved by
|
||||
* glibc, and sigaction() will return EINVAL for them. */
|
||||
if ((sigaction(sig, &sa, NULL) < 0))
|
||||
- if (errno != EINVAL)
|
||||
- return -errno;
|
||||
+ if (errno != EINVAL && r == 0)
|
||||
+ r = -errno;
|
||||
}
|
||||
|
||||
- return 0;
|
||||
+ return r;
|
||||
}
|
||||
|
||||
char *strstrip(char *s) {
|
66
0061-util-reset-signals-when-we-fork-off-agents.patch
Normal file
66
0061-util-reset-signals-when-we-fork-off-agents.patch
Normal file
@ -0,0 +1,66 @@
|
||||
From 1dedb74a2e1d840b531b76b01a76979f3b57456b Mon Sep 17 00:00:00 2001
|
||||
From: Lennart Poettering <lennart@poettering.net>
|
||||
Date: Tue, 26 Aug 2014 21:04:21 +0200
|
||||
Subject: [PATCH] util: reset signals when we fork off agents
|
||||
|
||||
If we invoke agents, we should make sure we actually can kill them
|
||||
again. I mean, it's probably not our job to cleanup the signals if our
|
||||
tools are invoked in weird contexts, but at least we should make sure,
|
||||
that the subprocesses we invoke and intend to control work as intended.
|
||||
|
||||
Also see:
|
||||
|
||||
http://lists.freedesktop.org/archives/systemd-devel/2014-August/022460.html
|
||||
---
|
||||
src/shared/util.c | 18 ++++++++++++++++++
|
||||
src/shared/util.h | 1 +
|
||||
2 files changed, 19 insertions(+)
|
||||
|
||||
diff --git a/src/shared/util.c b/src/shared/util.c
|
||||
index 4af2d3ceba..98c07163da 100644
|
||||
--- a/src/shared/util.c
|
||||
+++ b/src/shared/util.c
|
||||
@@ -959,6 +959,18 @@ int reset_all_signal_handlers(void) {
|
||||
return r;
|
||||
}
|
||||
|
||||
+int reset_signal_mask(void) {
|
||||
+ sigset_t ss;
|
||||
+
|
||||
+ if (sigemptyset(&ss) < 0)
|
||||
+ return -errno;
|
||||
+
|
||||
+ if (sigprocmask(SIG_SETMASK, &ss, NULL) < 0)
|
||||
+ return -errno;
|
||||
+
|
||||
+ return 0;
|
||||
+}
|
||||
+
|
||||
char *strstrip(char *s) {
|
||||
char *e;
|
||||
|
||||
@@ -5131,6 +5143,12 @@ int fork_agent(pid_t *pid, const int except[], unsigned n_except, const char *pa
|
||||
/* Don't leak fds to the agent */
|
||||
close_all_fds(except, n_except);
|
||||
|
||||
+ /* Make sure we actually can kill the agent, if we need to, in
|
||||
+ * case somebody invoked us from a shell script that trapped
|
||||
+ * SIGTERM or so... */
|
||||
+ reset_all_signal_handlers();
|
||||
+ reset_signal_mask();
|
||||
+
|
||||
stdout_is_tty = isatty(STDOUT_FILENO);
|
||||
stderr_is_tty = isatty(STDERR_FILENO);
|
||||
|
||||
diff --git a/src/shared/util.h b/src/shared/util.h
|
||||
index cd947dbbef..ea87c96956 100644
|
||||
--- a/src/shared/util.h
|
||||
+++ b/src/shared/util.h
|
||||
@@ -274,6 +274,7 @@ int readlink_and_make_absolute(const char *p, char **r);
|
||||
int readlink_and_canonicalize(const char *p, char **r);
|
||||
|
||||
int reset_all_signal_handlers(void);
|
||||
+int reset_signal_mask(void);
|
||||
|
||||
char *strstrip(char *s);
|
||||
char *delete_chars(char *s, const char *bad);
|
101
0062-util-make-use-of-newly-added-reset_signal_mask-call-.patch
Normal file
101
0062-util-make-use-of-newly-added-reset_signal_mask-call-.patch
Normal file
@ -0,0 +1,101 @@
|
||||
From 1b6d7fa742e303611dff8d7ebfa86ee5fb8b7dc7 Mon Sep 17 00:00:00 2001
|
||||
From: Lennart Poettering <lennart@poettering.net>
|
||||
Date: Tue, 26 Aug 2014 21:11:35 +0200
|
||||
Subject: [PATCH] util: make use of newly added reset_signal_mask() call
|
||||
wherever appropriate
|
||||
|
||||
---
|
||||
src/core/execute.c | 6 ++----
|
||||
src/core/main.c | 7 ++-----
|
||||
src/nspawn/nspawn.c | 4 +---
|
||||
src/shared/util.c | 5 +----
|
||||
4 files changed, 6 insertions(+), 16 deletions(-)
|
||||
|
||||
diff --git a/src/core/execute.c b/src/core/execute.c
|
||||
index b5b22472d5..066efd6fdf 100644
|
||||
--- a/src/core/execute.c
|
||||
+++ b/src/core/execute.c
|
||||
@@ -1301,7 +1301,6 @@ int exec_spawn(ExecCommand *command,
|
||||
int dont_close[n_fds + 3];
|
||||
uid_t uid = (uid_t) -1;
|
||||
gid_t gid = (gid_t) -1;
|
||||
- sigset_t ss;
|
||||
int i, err;
|
||||
|
||||
/* child */
|
||||
@@ -1319,9 +1318,8 @@ int exec_spawn(ExecCommand *command,
|
||||
if (context->ignore_sigpipe)
|
||||
ignore_signals(SIGPIPE, -1);
|
||||
|
||||
- assert_se(sigemptyset(&ss) == 0);
|
||||
- if (sigprocmask(SIG_SETMASK, &ss, NULL) < 0) {
|
||||
- err = -errno;
|
||||
+ err = reset_signal_mask();
|
||||
+ if (err < 0) {
|
||||
r = EXIT_SIGNAL_MASK;
|
||||
goto fail_child;
|
||||
}
|
||||
diff --git a/src/core/main.c b/src/core/main.c
|
||||
index bd148b1b33..95ab40fffc 100644
|
||||
--- a/src/core/main.c
|
||||
+++ b/src/core/main.c
|
||||
@@ -1834,7 +1834,6 @@ finish:
|
||||
if (reexecute) {
|
||||
const char **args;
|
||||
unsigned i, args_size;
|
||||
- sigset_t ss;
|
||||
|
||||
/* Close and disarm the watchdog, so that the new
|
||||
* instance can reinitialize it, but doesn't get
|
||||
@@ -1918,12 +1917,10 @@ finish:
|
||||
args[i++] = NULL;
|
||||
assert(i <= args_size);
|
||||
|
||||
- /* reenable any blocked signals, especially important
|
||||
+ /* Reenable any blocked signals, especially important
|
||||
* if we switch from initial ramdisk to init=... */
|
||||
reset_all_signal_handlers();
|
||||
-
|
||||
- assert_se(sigemptyset(&ss) == 0);
|
||||
- assert_se(sigprocmask(SIG_SETMASK, &ss, NULL) == 0);
|
||||
+ reset_signal_mask();
|
||||
|
||||
if (switch_root_init) {
|
||||
args[0] = switch_root_init;
|
||||
diff --git a/src/nspawn/nspawn.c b/src/nspawn/nspawn.c
|
||||
index 2c718557ee..56d9cc68c6 100644
|
||||
--- a/src/nspawn/nspawn.c
|
||||
+++ b/src/nspawn/nspawn.c
|
||||
@@ -3156,9 +3156,7 @@ int main(int argc, char *argv[]) {
|
||||
kmsg_socket_pair[0] = safe_close(kmsg_socket_pair[0]);
|
||||
|
||||
reset_all_signal_handlers();
|
||||
-
|
||||
- assert_se(sigemptyset(&mask) == 0);
|
||||
- assert_se(sigprocmask(SIG_SETMASK, &mask, NULL) == 0);
|
||||
+ reset_signal_mask();
|
||||
|
||||
k = open_terminal(console, O_RDWR);
|
||||
if (k != STDIN_FILENO) {
|
||||
diff --git a/src/shared/util.c b/src/shared/util.c
|
||||
index 98c07163da..fdcf5719fa 100644
|
||||
--- a/src/shared/util.c
|
||||
+++ b/src/shared/util.c
|
||||
@@ -3890,16 +3890,13 @@ void execute_directory(const char *directory, DIR *d, usec_t timeout, char *argv
|
||||
_cleanup_hashmap_free_free_ Hashmap *pids = NULL;
|
||||
_cleanup_closedir_ DIR *_d = NULL;
|
||||
struct dirent *de;
|
||||
- sigset_t ss;
|
||||
|
||||
/* We fork this all off from a child process so that
|
||||
* we can somewhat cleanly make use of SIGALRM to set
|
||||
* a time limit */
|
||||
|
||||
reset_all_signal_handlers();
|
||||
-
|
||||
- assert_se(sigemptyset(&ss) == 0);
|
||||
- assert_se(sigprocmask(SIG_SETMASK, &ss, NULL) == 0);
|
||||
+ reset_signal_mask();
|
||||
|
||||
assert_se(prctl(PR_SET_PDEATHSIG, SIGTERM) == 0);
|
||||
|
@ -0,0 +1,22 @@
|
||||
From 36202fd2bc252616966166c98ccb0e0e5ece1fc9 Mon Sep 17 00:00:00 2001
|
||||
From: Lennart Poettering <lennart@poettering.net>
|
||||
Date: Tue, 26 Aug 2014 21:47:46 +0200
|
||||
Subject: [PATCH] sd-journal: never log anything by default from a library
|
||||
|
||||
---
|
||||
src/journal/sd-journal.c | 2 +-
|
||||
1 file changed, 1 insertion(+), 1 deletion(-)
|
||||
|
||||
diff --git a/src/journal/sd-journal.c b/src/journal/sd-journal.c
|
||||
index b9ec90230d..80ff8fef57 100644
|
||||
--- a/src/journal/sd-journal.c
|
||||
+++ b/src/journal/sd-journal.c
|
||||
@@ -2557,7 +2557,7 @@ _public_ int sd_journal_enumerate_unique(sd_journal *j, const void **data, size_
|
||||
|
||||
/* Let's do the type check by hand, since we used 0 context above. */
|
||||
if (o->object.type != OBJECT_DATA) {
|
||||
- log_error("%s:offset " OFSfmt ": object has type %d, expected %d",
|
||||
+ log_debug("%s:offset " OFSfmt ": object has type %d, expected %d",
|
||||
j->unique_file->path, j->unique_offset,
|
||||
o->object.type, OBJECT_DATA);
|
||||
return -EBADMSG;
|
244
0064-logind-add-HandleLidSwitchDocked-option-to-logind.co.patch
Normal file
244
0064-logind-add-HandleLidSwitchDocked-option-to-logind.co.patch
Normal file
@ -0,0 +1,244 @@
|
||||
From 3c56cab44150ad47323970cfadfb0257c6305a74 Mon Sep 17 00:00:00 2001
|
||||
From: Ben Wolsieffer <benwolsieffer@gmail.com>
|
||||
Date: Tue, 26 Aug 2014 22:08:02 +0200
|
||||
Subject: [PATCH] logind: add HandleLidSwitchDocked= option to logind.conf +
|
||||
documentation
|
||||
|
||||
https://bugs.freedesktop.org/show_bug.cgi?id=82485
|
||||
---
|
||||
man/logind.conf.xml | 16 +++++++++++-----
|
||||
src/login/logind-action.c | 18 ------------------
|
||||
src/login/logind-button.c | 18 ++++++++++++++++--
|
||||
src/login/logind-core.c | 22 ++++++++++++++++++++++
|
||||
src/login/logind-dbus.c | 1 +
|
||||
src/login/logind-gperf.gperf | 1 +
|
||||
src/login/logind.c | 7 +++++--
|
||||
src/login/logind.conf | 1 +
|
||||
src/login/logind.h | 2 ++
|
||||
9 files changed, 59 insertions(+), 27 deletions(-)
|
||||
|
||||
diff --git a/man/logind.conf.xml b/man/logind.conf.xml
|
||||
index f037da259b..8ba95230be 100644
|
||||
--- a/man/logind.conf.xml
|
||||
+++ b/man/logind.conf.xml
|
||||
@@ -224,6 +224,7 @@
|
||||
<term><varname>HandleSuspendKey=</varname></term>
|
||||
<term><varname>HandleHibernateKey=</varname></term>
|
||||
<term><varname>HandleLidSwitch=</varname></term>
|
||||
+ <term><varname>HandleLidSwitchDocked=</varname></term>
|
||||
|
||||
<listitem><para>Controls whether
|
||||
logind shall handle the system power
|
||||
@@ -255,13 +256,18 @@
|
||||
and
|
||||
<varname>HandleLidSwitch=</varname>
|
||||
default to <literal>suspend</literal>.
|
||||
+ <varname>HandleLidSwitchDocked=</varname>
|
||||
+ defaults to <literal>ignore</literal>.
|
||||
<varname>HandleHibernateKey=</varname>
|
||||
defaults to
|
||||
- <literal>hibernate</literal>. Note
|
||||
- that the lid switch is ignored if the
|
||||
- system is inserted in a docking
|
||||
- station, or if more than one display
|
||||
- is connected.</para></listitem>
|
||||
+ <literal>hibernate</literal>. If the
|
||||
+ system is inserted in a docking station,
|
||||
+ or if more than one display is connected,
|
||||
+ the action specified by
|
||||
+ <varname>HandleLidSwitchDocked=</varname>
|
||||
+ occurs; otherwise the
|
||||
+ <varname>HandleLidSwitch=</varname>
|
||||
+ action occurs.</para></listitem>
|
||||
</varlistentry>
|
||||
|
||||
<varlistentry>
|
||||
diff --git a/src/login/logind-action.c b/src/login/logind-action.c
|
||||
index 36ee4418b8..0844df20a9 100644
|
||||
--- a/src/login/logind-action.c
|
||||
+++ b/src/login/logind-action.c
|
||||
@@ -71,24 +71,6 @@ int manager_handle_action(
|
||||
}
|
||||
|
||||
if (inhibit_key == INHIBIT_HANDLE_LID_SWITCH) {
|
||||
- int n;
|
||||
-
|
||||
- /* If we are docked don't react to lid closing */
|
||||
- if (manager_is_docked(m)) {
|
||||
- log_debug("Ignoring lid switch request, system is docked.");
|
||||
- return 0;
|
||||
- }
|
||||
-
|
||||
- /* If we have more than one display connected,
|
||||
- * don't react to lid closing. */
|
||||
- n = manager_count_displays(m);
|
||||
- if (n < 0)
|
||||
- log_warning("Display counting failed: %s", strerror(-n));
|
||||
- else if (n > 1) {
|
||||
- log_debug("Ignoring lid switch request, %i displays connected.", n);
|
||||
- return 0;
|
||||
- }
|
||||
-
|
||||
/* If the last system suspend or startup is too close,
|
||||
* let's not suspend for now, to give USB docking
|
||||
* stations some time to settle so that we can
|
||||
diff --git a/src/login/logind-button.c b/src/login/logind-button.c
|
||||
index 2561d13c67..57e619efe6 100644
|
||||
--- a/src/login/logind-button.c
|
||||
+++ b/src/login/logind-button.c
|
||||
@@ -97,13 +97,27 @@ int button_set_seat(Button *b, const char *sn) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
+static void button_lid_switch_handle_action(Manager *manager, bool is_edge) {
|
||||
+ HandleAction handle_action;
|
||||
+
|
||||
+ assert(manager);
|
||||
+
|
||||
+ /* If we are docked, handle the lid switch differently */
|
||||
+ if (manager_is_docked_or_multiple_displays(manager))
|
||||
+ handle_action = manager->handle_lid_switch_docked;
|
||||
+ else
|
||||
+ handle_action = manager->handle_lid_switch;
|
||||
+
|
||||
+ manager_handle_action(manager, INHIBIT_HANDLE_LID_SWITCH, handle_action, manager->lid_switch_ignore_inhibited, is_edge);
|
||||
+}
|
||||
+
|
||||
static int button_recheck(sd_event_source *e, void *userdata) {
|
||||
Button *b = userdata;
|
||||
|
||||
assert(b);
|
||||
assert(b->lid_closed);
|
||||
|
||||
- manager_handle_action(b->manager, INHIBIT_HANDLE_LID_SWITCH, b->manager->handle_lid_switch, b->manager->lid_switch_ignore_inhibited, false);
|
||||
+ button_lid_switch_handle_action(b->manager, false);
|
||||
return 1;
|
||||
}
|
||||
|
||||
@@ -186,7 +200,7 @@ static int button_dispatch(sd_event_source *s, int fd, uint32_t revents, void *u
|
||||
NULL);
|
||||
|
||||
b->lid_closed = true;
|
||||
- manager_handle_action(b->manager, INHIBIT_HANDLE_LID_SWITCH, b->manager->handle_lid_switch, b->manager->lid_switch_ignore_inhibited, true);
|
||||
+ button_lid_switch_handle_action(b->manager, true);
|
||||
button_install_check_event_source(b);
|
||||
|
||||
} else if (ev.code == SW_DOCK) {
|
||||
diff --git a/src/login/logind-core.c b/src/login/logind-core.c
|
||||
index 053d2ed63e..ed7ea5da31 100644
|
||||
--- a/src/login/logind-core.c
|
||||
+++ b/src/login/logind-core.c
|
||||
@@ -537,3 +537,25 @@ int manager_count_displays(Manager *m) {
|
||||
|
||||
return n;
|
||||
}
|
||||
+
|
||||
+bool manager_is_docked_or_multiple_displays(Manager *m) {
|
||||
+ int n;
|
||||
+
|
||||
+ /* If we are docked don't react to lid closing */
|
||||
+ if (manager_is_docked(m)) {
|
||||
+ log_debug("System is docked.");
|
||||
+ return true;
|
||||
+ }
|
||||
+
|
||||
+ /* If we have more than one display connected,
|
||||
+ * assume that we are docked. */
|
||||
+ n = manager_count_displays(m);
|
||||
+ if (n < 0)
|
||||
+ log_warning("Display counting failed: %s", strerror(-n));
|
||||
+ else if (n > 1) {
|
||||
+ log_debug("Multiple (%i) displays connected.", n);
|
||||
+ return true;
|
||||
+ }
|
||||
+
|
||||
+ return false;
|
||||
+}
|
||||
diff --git a/src/login/logind-dbus.c b/src/login/logind-dbus.c
|
||||
index acef5119b1..0b2b7b5afe 100644
|
||||
--- a/src/login/logind-dbus.c
|
||||
+++ b/src/login/logind-dbus.c
|
||||
@@ -1919,6 +1919,7 @@ const sd_bus_vtable manager_vtable[] = {
|
||||
SD_BUS_PROPERTY("HandleSuspendKey", "s", property_get_handle_action, offsetof(Manager, handle_suspend_key), SD_BUS_VTABLE_PROPERTY_CONST),
|
||||
SD_BUS_PROPERTY("HandleHibernateKey", "s", property_get_handle_action, offsetof(Manager, handle_hibernate_key), SD_BUS_VTABLE_PROPERTY_CONST),
|
||||
SD_BUS_PROPERTY("HandleLidSwitch", "s", property_get_handle_action, offsetof(Manager, handle_lid_switch), SD_BUS_VTABLE_PROPERTY_CONST),
|
||||
+ SD_BUS_PROPERTY("HandleLidSwitchDocked", "s", property_get_handle_action, offsetof(Manager, handle_lid_switch_docked), SD_BUS_VTABLE_PROPERTY_CONST),
|
||||
SD_BUS_PROPERTY("IdleAction", "s", property_get_handle_action, offsetof(Manager, idle_action), SD_BUS_VTABLE_PROPERTY_CONST),
|
||||
SD_BUS_PROPERTY("IdleActionUSec", "t", NULL, offsetof(Manager, idle_action_usec), SD_BUS_VTABLE_PROPERTY_CONST),
|
||||
SD_BUS_PROPERTY("PreparingForShutdown", "b", property_get_preparing, 0, 0),
|
||||
diff --git a/src/login/logind-gperf.gperf b/src/login/logind-gperf.gperf
|
||||
index 006f7286c5..62460673b9 100644
|
||||
--- a/src/login/logind-gperf.gperf
|
||||
+++ b/src/login/logind-gperf.gperf
|
||||
@@ -24,6 +24,7 @@ Login.HandlePowerKey, config_parse_handle_action, 0, offsetof(Manag
|
||||
Login.HandleSuspendKey, config_parse_handle_action, 0, offsetof(Manager, handle_suspend_key)
|
||||
Login.HandleHibernateKey, config_parse_handle_action, 0, offsetof(Manager, handle_hibernate_key)
|
||||
Login.HandleLidSwitch, config_parse_handle_action, 0, offsetof(Manager, handle_lid_switch)
|
||||
+Login.HandleLidSwitchDocked, config_parse_handle_action, 0, offsetof(Manager, handle_lid_switch_docked)
|
||||
Login.PowerKeyIgnoreInhibited, config_parse_bool, 0, offsetof(Manager, power_key_ignore_inhibited)
|
||||
Login.SuspendKeyIgnoreInhibited, config_parse_bool, 0, offsetof(Manager, suspend_key_ignore_inhibited)
|
||||
Login.HibernateKeyIgnoreInhibited, config_parse_bool, 0, offsetof(Manager, hibernate_key_ignore_inhibited)
|
||||
diff --git a/src/login/logind.c b/src/login/logind.c
|
||||
index 52e1c43a47..1f94a97bd0 100644
|
||||
--- a/src/login/logind.c
|
||||
+++ b/src/login/logind.c
|
||||
@@ -55,6 +55,7 @@ Manager *manager_new(void) {
|
||||
m->handle_suspend_key = HANDLE_SUSPEND;
|
||||
m->handle_hibernate_key = HANDLE_HIBERNATE;
|
||||
m->handle_lid_switch = HANDLE_SUSPEND;
|
||||
+ m->handle_lid_switch_docked = HANDLE_IGNORE;
|
||||
m->lid_switch_ignore_inhibited = true;
|
||||
|
||||
m->idle_action_usec = 30 * USEC_PER_MINUTE;
|
||||
@@ -232,7 +233,8 @@ static int manager_enumerate_buttons(Manager *m) {
|
||||
if (m->handle_power_key == HANDLE_IGNORE &&
|
||||
m->handle_suspend_key == HANDLE_IGNORE &&
|
||||
m->handle_hibernate_key == HANDLE_IGNORE &&
|
||||
- m->handle_lid_switch == HANDLE_IGNORE)
|
||||
+ m->handle_lid_switch == HANDLE_IGNORE &&
|
||||
+ m->handle_lid_switch_docked == HANDLE_IGNORE)
|
||||
return 0;
|
||||
|
||||
e = udev_enumerate_new(m->udev);
|
||||
@@ -875,7 +877,8 @@ static int manager_connect_udev(Manager *m) {
|
||||
if (m->handle_power_key != HANDLE_IGNORE ||
|
||||
m->handle_suspend_key != HANDLE_IGNORE ||
|
||||
m->handle_hibernate_key != HANDLE_IGNORE ||
|
||||
- m->handle_lid_switch != HANDLE_IGNORE) {
|
||||
+ m->handle_lid_switch != HANDLE_IGNORE ||
|
||||
+ m->handle_lid_switch_docked != HANDLE_IGNORE) {
|
||||
|
||||
m->udev_button_monitor = udev_monitor_new_from_netlink(m->udev, "udev");
|
||||
if (!m->udev_button_monitor)
|
||||
diff --git a/src/login/logind.conf b/src/login/logind.conf
|
||||
index 79f96ec05b..4608a2c0e2 100644
|
||||
--- a/src/login/logind.conf
|
||||
+++ b/src/login/logind.conf
|
||||
@@ -18,6 +18,7 @@
|
||||
#HandleSuspendKey=suspend
|
||||
#HandleHibernateKey=hibernate
|
||||
#HandleLidSwitch=suspend
|
||||
+#HandleLidSwitchDocked=ignore
|
||||
#PowerKeyIgnoreInhibited=no
|
||||
#SuspendKeyIgnoreInhibited=no
|
||||
#HibernateKeyIgnoreInhibited=no
|
||||
diff --git a/src/login/logind.h b/src/login/logind.h
|
||||
index 31353eff02..2f76572580 100644
|
||||
--- a/src/login/logind.h
|
||||
+++ b/src/login/logind.h
|
||||
@@ -114,6 +114,7 @@ struct Manager {
|
||||
HandleAction handle_suspend_key;
|
||||
HandleAction handle_hibernate_key;
|
||||
HandleAction handle_lid_switch;
|
||||
+ HandleAction handle_lid_switch_docked;
|
||||
|
||||
bool power_key_ignore_inhibited;
|
||||
bool suspend_key_ignore_inhibited;
|
||||
@@ -159,6 +160,7 @@ int manager_get_session_by_pid(Manager *m, pid_t pid, Session **session);
|
||||
|
||||
bool manager_is_docked(Manager *m);
|
||||
int manager_count_displays(Manager *m);
|
||||
+bool manager_is_docked_or_multiple_displays(Manager *m);
|
||||
|
||||
extern const sd_bus_vtable manager_vtable[];
|
||||
|
@ -0,0 +1,25 @@
|
||||
From 66f311206e908a5b6f21e66fad73e1e5ea3e31d6 Mon Sep 17 00:00:00 2001
|
||||
From: Ivan Shapovalov <intelfx100@gmail.com>
|
||||
Date: Wed, 27 Aug 2014 00:17:43 +0400
|
||||
Subject: [PATCH] units: order systemd-fsck@.service after local-fs-pre.target.
|
||||
|
||||
With this change, it becomes possible to order a unit to activate before any
|
||||
modifications to the file systems. This is especially useful for supporting
|
||||
resume from hibernation.
|
||||
---
|
||||
units/systemd-fsck@.service.in | 2 +-
|
||||
1 file changed, 1 insertion(+), 1 deletion(-)
|
||||
|
||||
diff --git a/units/systemd-fsck@.service.in b/units/systemd-fsck@.service.in
|
||||
index c12efa8e76..d2cda6a466 100644
|
||||
--- a/units/systemd-fsck@.service.in
|
||||
+++ b/units/systemd-fsck@.service.in
|
||||
@@ -10,7 +10,7 @@ Description=File System Check on %f
|
||||
Documentation=man:systemd-fsck@.service(8)
|
||||
DefaultDependencies=no
|
||||
BindsTo=%i.device
|
||||
-After=systemd-readahead-collect.service systemd-readahead-replay.service %i.device systemd-fsck-root.service
|
||||
+After=systemd-readahead-collect.service systemd-readahead-replay.service %i.device systemd-fsck-root.service local-fs-pre.target
|
||||
Before=shutdown.target
|
||||
|
||||
[Service]
|
353
0066-hibernate-resume-add-a-tool-to-write-a-device-node-s.patch
Normal file
353
0066-hibernate-resume-add-a-tool-to-write-a-device-node-s.patch
Normal file
@ -0,0 +1,353 @@
|
||||
From 42483a747489ff46aed3588b78bf4b9480dbeaf7 Mon Sep 17 00:00:00 2001
|
||||
From: Ivan Shapovalov <intelfx100@gmail.com>
|
||||
Date: Wed, 27 Aug 2014 00:17:44 +0400
|
||||
Subject: [PATCH] hibernate-resume: add a tool to write a device node's
|
||||
major:minor to /sys/power/resume.
|
||||
|
||||
This can be used to initiate a resume from hibernation by path to a swap
|
||||
device containing the hibernation image.
|
||||
|
||||
The respective templated unit is also added. It is instantiated using
|
||||
path to the desired resume device.
|
||||
---
|
||||
.gitignore | 1 +
|
||||
Makefile-man.am | 7 +++
|
||||
Makefile.am | 17 +++++--
|
||||
man/systemd-hibernate-resume@.service.xml | 81 ++++++++++++++++++++++++++++++
|
||||
src/hibernate-resume/Makefile | 1 +
|
||||
src/hibernate-resume/hibernate-resume.c | 81 ++++++++++++++++++++++++++++++
|
||||
units/.gitignore | 1 +
|
||||
units/systemd-hibernate-resume@.service.in | 20 ++++++++
|
||||
8 files changed, 206 insertions(+), 3 deletions(-)
|
||||
create mode 100644 man/systemd-hibernate-resume@.service.xml
|
||||
create mode 120000 src/hibernate-resume/Makefile
|
||||
create mode 100644 src/hibernate-resume/hibernate-resume.c
|
||||
create mode 100644 units/systemd-hibernate-resume@.service.in
|
||||
|
||||
diff --git a/.gitignore b/.gitignore
|
||||
index 8189da71f0..0b5608ccf9 100644
|
||||
--- a/.gitignore
|
||||
+++ b/.gitignore
|
||||
@@ -75,6 +75,7 @@
|
||||
/systemd-getty-generator
|
||||
/systemd-gnome-ask-password-agent
|
||||
/systemd-gpt-auto-generator
|
||||
+/systemd-hibernate-resume
|
||||
/systemd-hostnamed
|
||||
/systemd-inhibit
|
||||
/systemd-initctl
|
||||
diff --git a/Makefile-man.am b/Makefile-man.am
|
||||
index 562ecba435..09a10383a9 100644
|
||||
--- a/Makefile-man.am
|
||||
+++ b/Makefile-man.am
|
||||
@@ -70,6 +70,7 @@ MANPAGES += \
|
||||
man/systemd-getty-generator.8 \
|
||||
man/systemd-gpt-auto-generator.8 \
|
||||
man/systemd-halt.service.8 \
|
||||
+ man/systemd-hibernate-resume@.service.8 \
|
||||
man/systemd-inhibit.1 \
|
||||
man/systemd-initctl.service.8 \
|
||||
man/systemd-journald.service.8 \
|
||||
@@ -199,6 +200,7 @@ MANPAGES_ALIAS += \
|
||||
man/systemd-firstboot.service.1 \
|
||||
man/systemd-fsck-root.service.8 \
|
||||
man/systemd-fsck.8 \
|
||||
+ man/systemd-hibernate-resume.8 \
|
||||
man/systemd-hibernate.service.8 \
|
||||
man/systemd-hybrid-sleep.service.8 \
|
||||
man/systemd-initctl.8 \
|
||||
@@ -305,6 +307,7 @@ man/systemd-ask-password-wall.service.8: man/systemd-ask-password-console.servic
|
||||
man/systemd-firstboot.service.1: man/systemd-firstboot.1
|
||||
man/systemd-fsck-root.service.8: man/systemd-fsck@.service.8
|
||||
man/systemd-fsck.8: man/systemd-fsck@.service.8
|
||||
+man/systemd-hibernate-resume.8: man/systemd-hibernate-resume@.service.8
|
||||
man/systemd-hibernate.service.8: man/systemd-suspend.service.8
|
||||
man/systemd-hybrid-sleep.service.8: man/systemd-suspend.service.8
|
||||
man/systemd-initctl.8: man/systemd-initctl.service.8
|
||||
@@ -567,6 +570,9 @@ man/systemd-fsck-root.service.html: man/systemd-fsck@.service.html
|
||||
man/systemd-fsck.html: man/systemd-fsck@.service.html
|
||||
$(html-alias)
|
||||
|
||||
+man/systemd-hibernate-resume.html: man/systemd-hibernate-resume@.service.html
|
||||
+ $(html-alias)
|
||||
+
|
||||
man/systemd-hibernate.service.html: man/systemd-suspend.service.html
|
||||
$(html-alias)
|
||||
|
||||
@@ -1619,6 +1625,7 @@ EXTRA_DIST += \
|
||||
man/systemd-getty-generator.xml \
|
||||
man/systemd-gpt-auto-generator.xml \
|
||||
man/systemd-halt.service.xml \
|
||||
+ man/systemd-hibernate-resume@.service.xml \
|
||||
man/systemd-hostnamed.service.xml \
|
||||
man/systemd-inhibit.xml \
|
||||
man/systemd-initctl.service.xml \
|
||||
diff --git a/Makefile.am b/Makefile.am
|
||||
index cbf98bdac3..a487caa7bc 100644
|
||||
--- a/Makefile.am
|
||||
+++ b/Makefile.am
|
||||
@@ -378,7 +378,8 @@ rootlibexec_PROGRAMS = \
|
||||
systemd-sleep \
|
||||
systemd-bus-proxyd \
|
||||
systemd-socket-proxyd \
|
||||
- systemd-update-done
|
||||
+ systemd-update-done \
|
||||
+ systemd-hibernate-resume
|
||||
|
||||
systemgenerator_PROGRAMS = \
|
||||
systemd-getty-generator \
|
||||
@@ -528,7 +529,8 @@ nodist_systemunit_DATA = \
|
||||
units/initrd-udevadm-cleanup-db.service \
|
||||
units/initrd-switch-root.service \
|
||||
units/systemd-nspawn@.service \
|
||||
- units/systemd-update-done.service
|
||||
+ units/systemd-update-done.service \
|
||||
+ units/systemd-hibernate-resume@.service
|
||||
|
||||
dist_userunit_DATA = \
|
||||
units/user/basic.target \
|
||||
@@ -575,7 +577,8 @@ EXTRA_DIST += \
|
||||
units/initrd-udevadm-cleanup-db.service.in \
|
||||
units/initrd-switch-root.service.in \
|
||||
units/systemd-nspawn@.service.in \
|
||||
- units/systemd-update-done.service.in
|
||||
+ units/systemd-update-done.service.in \
|
||||
+ units/systemd-hibernate-resume@.service.in
|
||||
|
||||
CLEANFILES += \
|
||||
units/console-shell.service.m4 \
|
||||
@@ -2103,6 +2106,14 @@ systemd_delta_LDADD = \
|
||||
libsystemd-shared.la
|
||||
|
||||
# ------------------------------------------------------------------------------
|
||||
+systemd_hibernate_resume_SOURCES = \
|
||||
+ src/hibernate-resume/hibernate-resume.c
|
||||
+
|
||||
+systemd_hibernate_resume_LDADD = \
|
||||
+ libsystemd-internal.la \
|
||||
+ libsystemd-shared.la
|
||||
+
|
||||
+# ------------------------------------------------------------------------------
|
||||
systemd_getty_generator_SOURCES = \
|
||||
src/getty-generator/getty-generator.c
|
||||
|
||||
diff --git a/man/systemd-hibernate-resume@.service.xml b/man/systemd-hibernate-resume@.service.xml
|
||||
new file mode 100644
|
||||
index 0000000000..9b188b0d96
|
||||
--- /dev/null
|
||||
+++ b/man/systemd-hibernate-resume@.service.xml
|
||||
@@ -0,0 +1,81 @@
|
||||
+<?xml version="1.0"?>
|
||||
+<!--*-nxml-*-->
|
||||
+<!DOCTYPE refentry PUBLIC "-//OASIS//DTD DocBook XML V4.2//EN" "http://www.oasis-open.org/docbook/xml/4.2/docbookx.dtd">
|
||||
+<!--
|
||||
+ This file is part of systemd.
|
||||
+
|
||||
+ Copyright 2014 Ivan Shapovalov
|
||||
+
|
||||
+ 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
|
||||
+ the Free Software Foundation; either version 2.1 of the License, or
|
||||
+ (at your option) any later version.
|
||||
+
|
||||
+ systemd is distributed in the hope that it will be useful, but
|
||||
+ WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
+ Lesser General Public License for more details.
|
||||
+
|
||||
+ You should have received a copy of the GNU Lesser General Public License
|
||||
+ along with systemd; If not, see <http://www.gnu.org/licenses/>.
|
||||
+-->
|
||||
+<refentry id="systemd-hibernate-resume@.service">
|
||||
+
|
||||
+ <refentryinfo>
|
||||
+ <title>systemd-hibernate-resume@.service</title>
|
||||
+ <productname>systemd</productname>
|
||||
+
|
||||
+ <authorgroup>
|
||||
+ <author>
|
||||
+ <contrib>Developer</contrib>
|
||||
+ <firstname>Ivan</firstname>
|
||||
+ <surname>Shapovalov</surname>
|
||||
+ <email>intelfx100@gmail.com</email>
|
||||
+ </author>
|
||||
+ </authorgroup>
|
||||
+ </refentryinfo>
|
||||
+
|
||||
+ <refmeta>
|
||||
+ <refentrytitle>systemd-hibernate-resume@.service</refentrytitle>
|
||||
+ <manvolnum>8</manvolnum>
|
||||
+ </refmeta>
|
||||
+
|
||||
+ <refnamediv>
|
||||
+ <refname>systemd-hibernate-resume@.service</refname>
|
||||
+ <refname>systemd-hibernate-resume</refname>
|
||||
+ <refpurpose>Resume from hibernation</refpurpose>
|
||||
+ </refnamediv>
|
||||
+
|
||||
+ <refsynopsisdiv>
|
||||
+ <para><filename>systemd-hibernate-resume@.service</filename></para>
|
||||
+ <para><filename>/usr/lib/systemd/systemd-hibernate-resume</filename></para>
|
||||
+ </refsynopsisdiv>
|
||||
+
|
||||
+ <refsect1>
|
||||
+ <title>Description</title>
|
||||
+
|
||||
+ <para><filename>systemd-hibernate-resume@.service</filename> is a
|
||||
+ service that initiates hibernation resume from a device
|
||||
+ containing the resume image. It is instantiated for each
|
||||
+ device that is configured for resuming from.</para>
|
||||
+
|
||||
+ <para><filename>systemd-hibernate-resume</filename> only supports
|
||||
+ the in-kernel hibernation implementation, known as swsusp.
|
||||
+ Internally, it works by writing the major:minor of specified
|
||||
+ device node to <filename>/sys/power/resume</filename>.</para>
|
||||
+
|
||||
+ <para>Failing to initiate a resume is not an error condition.
|
||||
+ It may mean that there was no resume image (e. g. if the
|
||||
+ system has been simply powered off and not hibernated). In
|
||||
+ such case, the boot is ordinarily continued.</para>
|
||||
+ </refsect1>
|
||||
+
|
||||
+ <refsect1>
|
||||
+ <title>See Also</title>
|
||||
+ <para>
|
||||
+ <citerefentry><refentrytitle>systemd</refentrytitle><manvolnum>1</manvolnum></citerefentry>,
|
||||
+ <citerefentry><refentrytitle>systemd-hibernate-resume-generator</refentrytitle><manvolnum>8</manvolnum></citerefentry>
|
||||
+ </para>
|
||||
+ </refsect1>
|
||||
+
|
||||
+</refentry>
|
||||
diff --git a/src/hibernate-resume/Makefile b/src/hibernate-resume/Makefile
|
||||
new file mode 120000
|
||||
index 0000000000..d0b0e8e008
|
||||
--- /dev/null
|
||||
+++ b/src/hibernate-resume/Makefile
|
||||
@@ -0,0 +1 @@
|
||||
+../Makefile
|
||||
\ No newline at end of file
|
||||
diff --git a/src/hibernate-resume/hibernate-resume.c b/src/hibernate-resume/hibernate-resume.c
|
||||
new file mode 100644
|
||||
index 0000000000..8f68f81f9e
|
||||
--- /dev/null
|
||||
+++ b/src/hibernate-resume/hibernate-resume.c
|
||||
@@ -0,0 +1,81 @@
|
||||
+/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
|
||||
+
|
||||
+/***
|
||||
+ This file is part of systemd.
|
||||
+
|
||||
+ Copyright 2014 Ivan Shapovalov
|
||||
+
|
||||
+ 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
|
||||
+ the Free Software Foundation; either version 2.1 of the License, or
|
||||
+ (at your option) any later version.
|
||||
+
|
||||
+ systemd is distributed in the hope that it will be useful, but
|
||||
+ WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
+ Lesser General Public License for more details.
|
||||
+
|
||||
+ You should have received a copy of the GNU Lesser General Public License
|
||||
+ along with systemd; If not, see <http://www.gnu.org/licenses/>.
|
||||
+***/
|
||||
+
|
||||
+#include <stdio.h>
|
||||
+#include <errno.h>
|
||||
+#include <sys/types.h>
|
||||
+#include <sys/stat.h>
|
||||
+#include <unistd.h>
|
||||
+
|
||||
+#include "log.h"
|
||||
+#include "util.h"
|
||||
+#include "fileio.h"
|
||||
+
|
||||
+int main(int argc, char *argv[]) {
|
||||
+ struct stat st;
|
||||
+ const char *device;
|
||||
+ _cleanup_free_ char *major_minor = NULL;
|
||||
+ int r;
|
||||
+
|
||||
+ if (argc != 2) {
|
||||
+ log_error("This program expects one argument.");
|
||||
+ return EXIT_FAILURE;
|
||||
+ }
|
||||
+
|
||||
+ log_set_target(LOG_TARGET_AUTO);
|
||||
+ log_parse_environment();
|
||||
+ log_open();
|
||||
+
|
||||
+ umask(0022);
|
||||
+
|
||||
+ device = argv[1];
|
||||
+
|
||||
+ if (stat(device, &st) < 0) {
|
||||
+ log_error("Failed to stat '%s': %m", device);
|
||||
+ return EXIT_FAILURE;
|
||||
+ }
|
||||
+
|
||||
+ if (!S_ISBLK(st.st_mode)) {
|
||||
+ log_error("Resume device '%s' is not a block device.", device);
|
||||
+ return EXIT_FAILURE;
|
||||
+ }
|
||||
+
|
||||
+ if (asprintf(&major_minor, "%d:%d", major(st.st_rdev), minor(st.st_rdev)) < 0) {
|
||||
+ log_oom();
|
||||
+ return EXIT_FAILURE;
|
||||
+ }
|
||||
+
|
||||
+ r = write_string_file("/sys/power/resume", major_minor);
|
||||
+ if (r < 0) {
|
||||
+ log_error("Failed to write '%s' to /sys/power/resume: %s", major_minor, strerror(-r));
|
||||
+ return EXIT_FAILURE;
|
||||
+ }
|
||||
+
|
||||
+ /*
|
||||
+ * The write above shall not return.
|
||||
+ *
|
||||
+ * However, failed resume is a normal condition (may mean that there is
|
||||
+ * no hibernation image).
|
||||
+ */
|
||||
+
|
||||
+ log_info("Could not resume from '%s' (%s).", device, major_minor);
|
||||
+ return EXIT_SUCCESS;
|
||||
+}
|
||||
diff --git a/units/.gitignore b/units/.gitignore
|
||||
index d9b60ac0fc..c60f357416 100644
|
||||
--- a/units/.gitignore
|
||||
+++ b/units/.gitignore
|
||||
@@ -54,6 +54,7 @@
|
||||
/systemd-reboot.service
|
||||
/systemd-remount-fs.service
|
||||
/systemd-resolved.service
|
||||
+/systemd-hibernate-resume@.service
|
||||
/systemd-rfkill@.service
|
||||
/systemd-shutdownd.service
|
||||
/systemd-suspend.service
|
||||
diff --git a/units/systemd-hibernate-resume@.service.in b/units/systemd-hibernate-resume@.service.in
|
||||
new file mode 100644
|
||||
index 0000000000..6db584dc4d
|
||||
--- /dev/null
|
||||
+++ b/units/systemd-hibernate-resume@.service.in
|
||||
@@ -0,0 +1,20 @@
|
||||
+# This file is part of systemd.
|
||||
+#
|
||||
+# 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
|
||||
+# the Free Software Foundation; either version 2.1 of the License, or
|
||||
+# (at your option) any later version.
|
||||
+
|
||||
+[Unit]
|
||||
+Description=Resume from hibernation using device %f
|
||||
+Documentation=man:systemd-hibernate-resume@.service(8)
|
||||
+DefaultDependencies=no
|
||||
+BindsTo=%i.device
|
||||
+Wants=local-fs-pre.target
|
||||
+After=%i.device
|
||||
+Before=local-fs-pre.target systemd-remount-fs.service systemd-fsck-root.service
|
||||
+ConditionPathExists=/etc/initrd-release
|
||||
+
|
||||
+[Service]
|
||||
+Type=oneshot
|
||||
+ExecStart=@rootlibexecdir@/systemd-hibernate-resume %f
|
330
0067-hibernate-resume-generator-add-a-generator-for-insta.patch
Normal file
330
0067-hibernate-resume-generator-add-a-generator-for-insta.patch
Normal file
@ -0,0 +1,330 @@
|
||||
From d2c68822c47e37b582820f45b496b2e7d1f9e642 Mon Sep 17 00:00:00 2001
|
||||
From: Ivan Shapovalov <intelfx100@gmail.com>
|
||||
Date: Wed, 27 Aug 2014 00:17:45 +0400
|
||||
Subject: [PATCH] hibernate-resume-generator: add a generator for instantiating
|
||||
the resume unit.
|
||||
|
||||
hibernate-resume-generator understands resume= kernel command line parameter
|
||||
and instantiates the systemd-resume@.service accordingly if it is passed.
|
||||
|
||||
This enables resume from hibernation using device specified on the kernel
|
||||
command line, and it may be specified either as "/dev/disk/by-foo/bar"
|
||||
or "FOO=bar", not only "/dev/sdXY" which is understood by the in-kernel
|
||||
implementation.
|
||||
|
||||
So now resume= is brought on par with root= in terms of possible ways to
|
||||
specify a device.
|
||||
---
|
||||
.gitignore | 1 +
|
||||
Makefile-man.am | 2 +
|
||||
Makefile.am | 11 +++-
|
||||
man/kernel-command-line.xml | 14 ++++-
|
||||
man/systemd-hibernate-resume-generator.xml | 93 +++++++++++++++++++++++++++++
|
||||
src/resume-generator/Makefile | 1 +
|
||||
src/resume-generator/resume-generator.c | 95 ++++++++++++++++++++++++++++++
|
||||
7 files changed, 215 insertions(+), 2 deletions(-)
|
||||
create mode 100644 man/systemd-hibernate-resume-generator.xml
|
||||
create mode 120000 src/resume-generator/Makefile
|
||||
create mode 100644 src/resume-generator/resume-generator.c
|
||||
|
||||
diff --git a/.gitignore b/.gitignore
|
||||
index 0b5608ccf9..8aed0b9ba6 100644
|
||||
--- a/.gitignore
|
||||
+++ b/.gitignore
|
||||
@@ -76,6 +76,7 @@
|
||||
/systemd-gnome-ask-password-agent
|
||||
/systemd-gpt-auto-generator
|
||||
/systemd-hibernate-resume
|
||||
+/systemd-hibernate-resume-generator
|
||||
/systemd-hostnamed
|
||||
/systemd-inhibit
|
||||
/systemd-initctl
|
||||
diff --git a/Makefile-man.am b/Makefile-man.am
|
||||
index 09a10383a9..5c27937152 100644
|
||||
--- a/Makefile-man.am
|
||||
+++ b/Makefile-man.am
|
||||
@@ -70,6 +70,7 @@ MANPAGES += \
|
||||
man/systemd-getty-generator.8 \
|
||||
man/systemd-gpt-auto-generator.8 \
|
||||
man/systemd-halt.service.8 \
|
||||
+ man/systemd-hibernate-resume-generator.8 \
|
||||
man/systemd-hibernate-resume@.service.8 \
|
||||
man/systemd-inhibit.1 \
|
||||
man/systemd-initctl.service.8 \
|
||||
@@ -1625,6 +1626,7 @@ EXTRA_DIST += \
|
||||
man/systemd-getty-generator.xml \
|
||||
man/systemd-gpt-auto-generator.xml \
|
||||
man/systemd-halt.service.xml \
|
||||
+ man/systemd-hibernate-resume-generator.xml \
|
||||
man/systemd-hibernate-resume@.service.xml \
|
||||
man/systemd-hostnamed.service.xml \
|
||||
man/systemd-inhibit.xml \
|
||||
diff --git a/Makefile.am b/Makefile.am
|
||||
index a487caa7bc..cbdf551fa8 100644
|
||||
--- a/Makefile.am
|
||||
+++ b/Makefile.am
|
||||
@@ -385,7 +385,8 @@ systemgenerator_PROGRAMS = \
|
||||
systemd-getty-generator \
|
||||
systemd-fstab-generator \
|
||||
systemd-system-update-generator \
|
||||
- systemd-debug-generator
|
||||
+ systemd-debug-generator \
|
||||
+ systemd-hibernate-resume-generator
|
||||
|
||||
dist_bashcompletion_DATA = \
|
||||
shell-completion/bash/busctl \
|
||||
@@ -2146,6 +2147,14 @@ systemd_system_update_generator_LDADD = \
|
||||
libsystemd-label.la \
|
||||
libsystemd-shared.la
|
||||
|
||||
+# ------------------------------------------------------------------------------
|
||||
+systemd_hibernate_resume_generator_SOURCES = \
|
||||
+ src/resume-generator/resume-generator.c
|
||||
+
|
||||
+systemd_hibernate_resume_generator_LDADD = \
|
||||
+ libsystemd-label.la \
|
||||
+ libsystemd-shared.la
|
||||
+
|
||||
if ENABLE_EFI
|
||||
# ------------------------------------------------------------------------------
|
||||
systemgenerator_PROGRAMS += \
|
||||
diff --git a/man/kernel-command-line.xml b/man/kernel-command-line.xml
|
||||
index 36428aaa94..d872e6d5b9 100644
|
||||
--- a/man/kernel-command-line.xml
|
||||
+++ b/man/kernel-command-line.xml
|
||||
@@ -351,6 +351,17 @@
|
||||
</listitem>
|
||||
</varlistentry>
|
||||
|
||||
+ <varlistentry>
|
||||
+ <term><varname>resume=</varname></term>
|
||||
+
|
||||
+ <listitem>
|
||||
+ <para>Enables resume from hibernation
|
||||
+ using the specified device.
|
||||
+ All <citerefentry><refentrytitle>fstab</refentrytitle><manvolnum>5</manvolnum></citerefentry>-like
|
||||
+ pathes are supported. For details, see
|
||||
+ <citerefentry><refentrytitle>systemd-hibernate-resume-generator</refentrytitle><manvolnum>8</manvolnum></citerefentry>.</para>
|
||||
+ </listitem>
|
||||
+ </varlistentry>
|
||||
</variablelist>
|
||||
|
||||
</refsect1>
|
||||
@@ -373,7 +384,8 @@
|
||||
<citerefentry><refentrytitle>systemd-gpt-auto-generator</refentrytitle><manvolnum>8</manvolnum></citerefentry>,
|
||||
<citerefentry><refentrytitle>systemd-modules-load.service</refentrytitle><manvolnum>8</manvolnum></citerefentry>,
|
||||
<citerefentry><refentrytitle>systemd-backlight@.service</refentrytitle><manvolnum>8</manvolnum></citerefentry>,
|
||||
- <citerefentry><refentrytitle>systemd-rfkill@.service</refentrytitle><manvolnum>8</manvolnum></citerefentry>
|
||||
+ <citerefentry><refentrytitle>systemd-rfkill@.service</refentrytitle><manvolnum>8</manvolnum></citerefentry>,
|
||||
+ <citerefentry><refentrytitle>systemd-hibernate-resume-generator</refentrytitle><manvolnum>8</manvolnum></citerefentry>
|
||||
</para>
|
||||
</refsect1>
|
||||
|
||||
diff --git a/man/systemd-hibernate-resume-generator.xml b/man/systemd-hibernate-resume-generator.xml
|
||||
new file mode 100644
|
||||
index 0000000000..1a4b99ced4
|
||||
--- /dev/null
|
||||
+++ b/man/systemd-hibernate-resume-generator.xml
|
||||
@@ -0,0 +1,93 @@
|
||||
+<?xml version="1.0"?>
|
||||
+<!--*-nxml-*-->
|
||||
+<!DOCTYPE refentry PUBLIC "-//OASIS//DTD DocBook XML V4.2//EN" "http://www.oasis-open.org/docbook/xml/4.2/docbookx.dtd">
|
||||
+<!--
|
||||
+ This file is part of systemd.
|
||||
+
|
||||
+ Copyright 2014 Ivan Shapovalov
|
||||
+
|
||||
+ 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
|
||||
+ the Free Software Foundation; either version 2.1 of the License, or
|
||||
+ (at your option) any later version.
|
||||
+
|
||||
+ systemd is distributed in the hope that it will be useful, but
|
||||
+ WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
+ Lesser General Public License for more details.
|
||||
+
|
||||
+ You should have received a copy of the GNU Lesser General Public License
|
||||
+ along with systemd; If not, see <http://www.gnu.org/licenses/>.
|
||||
+-->
|
||||
+<refentry id="systemd-hibernate-resume-generator">
|
||||
+
|
||||
+ <refentryinfo>
|
||||
+ <title>systemd-hibernate-resume-generator</title>
|
||||
+ <productname>systemd</productname>
|
||||
+
|
||||
+ <authorgroup>
|
||||
+ <author>
|
||||
+ <contrib>Developer</contrib>
|
||||
+ <firstname>Ivan</firstname>
|
||||
+ <surname>Shapovalov</surname>
|
||||
+ <email>intelfx100@gmail.com</email>
|
||||
+ </author>
|
||||
+ </authorgroup>
|
||||
+ </refentryinfo>
|
||||
+
|
||||
+ <refmeta>
|
||||
+ <refentrytitle>systemd-hibernate-resume-generator</refentrytitle>
|
||||
+ <manvolnum>8</manvolnum>
|
||||
+ </refmeta>
|
||||
+
|
||||
+ <refnamediv>
|
||||
+ <refname>systemd-hibernate-resume-generator</refname>
|
||||
+ <refpurpose>Unit generator for resume= kernel parameter</refpurpose>
|
||||
+ </refnamediv>
|
||||
+
|
||||
+ <refsynopsisdiv>
|
||||
+ <para><filename>/usr/lib/systemd/system-generators/systemd-hibernate-resume-generator</filename></para>
|
||||
+ </refsynopsisdiv>
|
||||
+
|
||||
+ <refsect1>
|
||||
+ <title>Description</title>
|
||||
+
|
||||
+ <para><filename>systemd-hibernate-resume-generator</filename> is
|
||||
+ a generator that instantiates
|
||||
+ <citerefentry><refentrytitle>systemd-hibernate-resume@.service</refentrytitle><manvolnum>8</manvolnum></citerefentry>
|
||||
+ unit according to the value of <option>resume=</option>
|
||||
+ parameter specified on the kernel command line.</para>
|
||||
+ </refsect1>
|
||||
+
|
||||
+ <refsect1>
|
||||
+ <title>Kernel Command Line</title>
|
||||
+
|
||||
+ <para><filename>systemd-hibernate-resume-generator</filename> understands
|
||||
+ the following kernel command line parameters:</para>
|
||||
+
|
||||
+ <variablelist class='kernel-commandline-options'>
|
||||
+
|
||||
+ <varlistentry>
|
||||
+ <term><varname>resume=</varname></term>
|
||||
+
|
||||
+ <listitem><para>Takes a path to the resume
|
||||
+ device. Both persistent block device pathes like
|
||||
+ <filename>/dev/disk/by-foo/bar</filename> and
|
||||
+ <citerefentry><refentrytitle>fstab</refentrytitle><manvolnum>5</manvolnum></citerefentry>-style
|
||||
+ specifiers like <literal>FOO=bar</literal>
|
||||
+ are supported.</para></listitem>
|
||||
+ </varlistentry>
|
||||
+
|
||||
+ </variablelist>
|
||||
+ </refsect1>
|
||||
+
|
||||
+ <refsect1>
|
||||
+ <title>See Also</title>
|
||||
+ <para>
|
||||
+ <citerefentry><refentrytitle>systemd</refentrytitle><manvolnum>1</manvolnum></citerefentry>,
|
||||
+ <citerefentry><refentrytitle>systemd-hibernate-resume@.service</refentrytitle><manvolnum>8</manvolnum></citerefentry>,
|
||||
+ <citerefentry><refentrytitle>kernel-command-line</refentrytitle><manvolnum>7</manvolnum></citerefentry>
|
||||
+ </para>
|
||||
+ </refsect1>
|
||||
+
|
||||
+</refentry>
|
||||
diff --git a/src/resume-generator/Makefile b/src/resume-generator/Makefile
|
||||
new file mode 120000
|
||||
index 0000000000..d0b0e8e008
|
||||
--- /dev/null
|
||||
+++ b/src/resume-generator/Makefile
|
||||
@@ -0,0 +1 @@
|
||||
+../Makefile
|
||||
\ No newline at end of file
|
||||
diff --git a/src/resume-generator/resume-generator.c b/src/resume-generator/resume-generator.c
|
||||
new file mode 100644
|
||||
index 0000000000..f40721662e
|
||||
--- /dev/null
|
||||
+++ b/src/resume-generator/resume-generator.c
|
||||
@@ -0,0 +1,95 @@
|
||||
+/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
|
||||
+
|
||||
+/***
|
||||
+ This file is part of systemd.
|
||||
+
|
||||
+ Copyright 2014 Ivan Shapovalov
|
||||
+
|
||||
+ 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
|
||||
+ the Free Software Foundation; either version 2.1 of the License, or
|
||||
+ (at your option) any later version.
|
||||
+
|
||||
+ systemd is distributed in the hope that it will be useful, but
|
||||
+ WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
+ Lesser General Public License for more details.
|
||||
+
|
||||
+ You should have received a copy of the GNU Lesser General Public License
|
||||
+ along with systemd; If not, see <http://www.gnu.org/licenses/>.
|
||||
+***/
|
||||
+
|
||||
+#include <stdio.h>
|
||||
+#include <errno.h>
|
||||
+
|
||||
+#include "log.h"
|
||||
+#include "util.h"
|
||||
+#include "special.h"
|
||||
+#include "mkdir.h"
|
||||
+#include "unit-name.h"
|
||||
+
|
||||
+static const char *arg_dest = "/tmp";
|
||||
+static char *arg_resume_dev = NULL;
|
||||
+
|
||||
+static int parse_proc_cmdline_item(const char *key, const char *value) {
|
||||
+ if (streq(key, "resume") && value) {
|
||||
+ free(arg_resume_dev);
|
||||
+ arg_resume_dev = fstab_node_to_udev_node(value);
|
||||
+ if (!arg_resume_dev)
|
||||
+ return log_oom();
|
||||
+ }
|
||||
+
|
||||
+ return 0;
|
||||
+}
|
||||
+
|
||||
+static int process_resume(void) {
|
||||
+ _cleanup_free_ char *name = NULL, *lnk = NULL;
|
||||
+
|
||||
+ name = unit_name_from_path_instance("systemd-hibernate-resume", arg_resume_dev, ".service");
|
||||
+ if (!name)
|
||||
+ return log_oom();
|
||||
+
|
||||
+ lnk = strjoin(arg_dest, "/" SPECIAL_SYSINIT_TARGET ".wants/", name, NULL);
|
||||
+ if (!lnk)
|
||||
+ return log_oom();
|
||||
+
|
||||
+ mkdir_parents_label(lnk, 0755);
|
||||
+ if (symlink(SYSTEM_DATA_UNIT_PATH "/systemd-hibernate-resume@.service", lnk) < 0) {
|
||||
+ log_error("Failed to create symlink %s: %m", lnk);
|
||||
+ return -errno;
|
||||
+ }
|
||||
+
|
||||
+ return 0;
|
||||
+}
|
||||
+
|
||||
+int main(int argc, char *argv[]) {
|
||||
+ int r = 0;
|
||||
+
|
||||
+ if (argc > 1 && argc != 4) {
|
||||
+ log_error("This program takes three or no arguments.");
|
||||
+ return EXIT_FAILURE;
|
||||
+ }
|
||||
+
|
||||
+ if (argc > 1)
|
||||
+ arg_dest = argv[1];
|
||||
+
|
||||
+ log_set_target(LOG_TARGET_SAFE);
|
||||
+ log_parse_environment();
|
||||
+ log_open();
|
||||
+
|
||||
+ umask(0022);
|
||||
+
|
||||
+ /* Don't even consider resuming outside of initramfs. */
|
||||
+ if (!in_initrd())
|
||||
+ return EXIT_SUCCESS;
|
||||
+
|
||||
+ if (parse_proc_cmdline(parse_proc_cmdline_item) < 0)
|
||||
+ return EXIT_FAILURE;
|
||||
+
|
||||
+ if (arg_resume_dev != NULL)
|
||||
+ r = process_resume();
|
||||
+
|
||||
+ free(arg_resume_dev);
|
||||
+
|
||||
+ return r < 0 ? EXIT_FAILURE : EXIT_SUCCESS;
|
||||
+}
|
@ -0,0 +1,35 @@
|
||||
From 36f5ace2db7fc43796107b2da9874e4c4bbc623e Mon Sep 17 00:00:00 2001
|
||||
From: =?UTF-8?q?Zbigniew=20J=C4=99drzejewski-Szmek?= <zbyszek@in.waw.pl>
|
||||
Date: Tue, 26 Aug 2014 21:14:11 -0400
|
||||
Subject: [PATCH] man: reword sd-hibernate-resume description and add link
|
||||
|
||||
"each device" was suggesting that this service might be instantiated
|
||||
multiple times. "hibernation resume" was too jargon-y.
|
||||
---
|
||||
man/systemd-hibernate-resume@.service.xml | 11 ++++++-----
|
||||
1 file changed, 6 insertions(+), 5 deletions(-)
|
||||
|
||||
diff --git a/man/systemd-hibernate-resume@.service.xml b/man/systemd-hibernate-resume@.service.xml
|
||||
index 9b188b0d96..30bfd88101 100644
|
||||
--- a/man/systemd-hibernate-resume@.service.xml
|
||||
+++ b/man/systemd-hibernate-resume@.service.xml
|
||||
@@ -54,13 +54,14 @@
|
||||
<refsect1>
|
||||
<title>Description</title>
|
||||
|
||||
- <para><filename>systemd-hibernate-resume@.service</filename> is a
|
||||
- service that initiates hibernation resume from a device
|
||||
- containing the resume image. It is instantiated for each
|
||||
- device that is configured for resuming from.</para>
|
||||
+ <para><filename>systemd-hibernate-resume@.service</filename>
|
||||
+ initiates the resume from hibernation. It is
|
||||
+ instantiated with the device to resume from as the
|
||||
+ template argument.</para>
|
||||
|
||||
<para><filename>systemd-hibernate-resume</filename> only supports
|
||||
- the in-kernel hibernation implementation, known as swsusp.
|
||||
+ the in-kernel hibernation implementation, known as
|
||||
+ <ulink url="https://www.kernel.org/doc/Documentation/power/swsusp.txt">swsusp</ulink>.
|
||||
Internally, it works by writing the major:minor of specified
|
||||
device node to <filename>/sys/power/resume</filename>.</para>
|
||||
|
39
0069-Document-.-.-udev-match-syntax.patch
Normal file
39
0069-Document-.-.-udev-match-syntax.patch
Normal file
@ -0,0 +1,39 @@
|
||||
From bf2e0ece853b888eb37055849975ddeab3f5f051 Mon Sep 17 00:00:00 2001
|
||||
From: Andrei Borzenkov <arvidjaar@gmail.com>
|
||||
Date: Sun, 24 Aug 2014 11:11:33 +0400
|
||||
Subject: [PATCH] Document "...|..." udev match syntax
|
||||
|
||||
---
|
||||
man/udev.xml | 12 ++++++++++--
|
||||
1 file changed, 10 insertions(+), 2 deletions(-)
|
||||
|
||||
diff --git a/man/udev.xml b/man/udev.xml
|
||||
index db729378c5..2948b9ce2b 100644
|
||||
--- a/man/udev.xml
|
||||
+++ b/man/udev.xml
|
||||
@@ -272,8 +272,8 @@
|
||||
</varlistentry>
|
||||
</variablelist>
|
||||
|
||||
- <para>Most of the fields support shell glob pattern matching. The following
|
||||
- pattern characters are supported:</para>
|
||||
+ <para>Most of the fields support shell glob pattern matching and
|
||||
+ alternate patterns. The following special characters are supported:</para>
|
||||
<variablelist>
|
||||
<varlistentry>
|
||||
<term><literal>*</literal></term>
|
||||
@@ -300,6 +300,14 @@
|
||||
any characters not enclosed are matched.</para>
|
||||
</listitem>
|
||||
</varlistentry>
|
||||
+ <varlistentry>
|
||||
+ <term><literal>|</literal></term>
|
||||
+ <listitem>
|
||||
+ <para>Separates alternative patterns. For example, the pattern string
|
||||
+ <literal>abc|x*</literal> would match either <literal>abc</literal>
|
||||
+ or <literal>x*</literal>.</para>
|
||||
+ </listitem>
|
||||
+ </varlistentry>
|
||||
</variablelist>
|
||||
|
||||
<para>The following keys can get values assigned:</para>
|
63
0070-po-update-Polish-translation.patch
Normal file
63
0070-po-update-Polish-translation.patch
Normal file
@ -0,0 +1,63 @@
|
||||
From 1977376274fc81f13e4220d224237e7cc71f0c63 Mon Sep 17 00:00:00 2001
|
||||
From: =?UTF-8?q?Piotr=20Dr=C4=85g?= <piotrdrag@gmail.com>
|
||||
Date: Sun, 24 Aug 2014 18:18:35 +0200
|
||||
Subject: [PATCH] po: update Polish translation
|
||||
|
||||
https://bugs.freedesktop.org/show_bug.cgi?id=83015
|
||||
---
|
||||
po/pl.po | 34 +++++++++++++++++++++++++++++++---
|
||||
1 file changed, 31 insertions(+), 3 deletions(-)
|
||||
|
||||
diff --git a/po/pl.po b/po/pl.po
|
||||
index 6a95d2fd74..0407fe0861 100644
|
||||
--- a/po/pl.po
|
||||
+++ b/po/pl.po
|
||||
@@ -1,13 +1,13 @@
|
||||
# translation of pl.po to Polish
|
||||
-# Piotr Drąg <piotrdrag@gmail.com>, 2011, 2013.
|
||||
+# Piotr Drąg <piotrdrag@gmail.com>, 2011, 2013, 2014.
|
||||
# Zbigniew Jędrzejewski-Szmek <zbyszek@in.waw.pl>, 2011.
|
||||
#
|
||||
msgid ""
|
||||
msgstr ""
|
||||
"Project-Id-Version: systemd\n"
|
||||
"Report-Msgid-Bugs-To: \n"
|
||||
-"POT-Creation-Date: 2013-01-12 19:29+0100\n"
|
||||
-"PO-Revision-Date: 2013-01-12 19:30+0100\n"
|
||||
+"POT-Creation-Date: 2014-08-24 18:10+0200\n"
|
||||
+"PO-Revision-Date: 2014-08-24 18:15+0200\n"
|
||||
"Last-Translator: Piotr Drąg <piotrdrag@gmail.com>\n"
|
||||
"Language-Team: Polish <trans-pl@lists.fedoraproject.org>\n"
|
||||
"Language: pl\n"
|
||||
@@ -389,3 +389,31 @@ msgid "Authentication is required to access the system and service manager."
|
||||
msgstr ""
|
||||
"Wymagane jest uwierzytelnienie, aby uzyskać dostęp do menedżera systemu i "
|
||||
"usług."
|
||||
+
|
||||
+#: ../src/core/org.freedesktop.systemd1.policy.in.in.h:5
|
||||
+msgid "Manage system services or units"
|
||||
+msgstr "Zarządzanie usługami lub jednostkami systemu"
|
||||
+
|
||||
+#: ../src/core/org.freedesktop.systemd1.policy.in.in.h:6
|
||||
+msgid "Authentication is required to manage system services or units."
|
||||
+msgstr ""
|
||||
+"Wymagane jest uwierzytelnienie, aby zarządzać usługami lub jednostkami "
|
||||
+"systemu."
|
||||
+
|
||||
+#: ../src/core/org.freedesktop.systemd1.policy.in.in.h:7
|
||||
+msgid "Manage system service or unit files"
|
||||
+msgstr "Zarządzanie plikami usług lub jednostek systemu"
|
||||
+
|
||||
+#: ../src/core/org.freedesktop.systemd1.policy.in.in.h:8
|
||||
+msgid "Authentication is required to manage system service or unit files."
|
||||
+msgstr ""
|
||||
+"Wymagane jest uwierzytelnienie, aby zarządzać plikami usług lub jednostek "
|
||||
+"systemu."
|
||||
+
|
||||
+#: ../src/core/org.freedesktop.systemd1.policy.in.in.h:9
|
||||
+msgid "Reload the systemd state"
|
||||
+msgstr "Ponowne wczytanie stanu systemd"
|
||||
+
|
||||
+#: ../src/core/org.freedesktop.systemd1.policy.in.in.h:10
|
||||
+msgid "Authentication is required to reload the systemd state."
|
||||
+msgstr "Wymagane jest uwierzytelnienie, aby ponownie wczytać stan systemd."
|
26
0071-keymap-Adjust-for-more-Samsung-900X4-series.patch
Normal file
26
0071-keymap-Adjust-for-more-Samsung-900X4-series.patch
Normal file
@ -0,0 +1,26 @@
|
||||
From e512e8a255ef29d5a8eb605f8849202ea3d3e4cb Mon Sep 17 00:00:00 2001
|
||||
From: Martin Pitt <martin.pitt@ubuntu.com>
|
||||
Date: Wed, 27 Aug 2014 08:41:10 +0200
|
||||
Subject: [PATCH] keymap: Adjust for more Samsung 900X4 series
|
||||
|
||||
Reportedly also applies to NP900X4B, so relax the match to apply to all models
|
||||
of this series.
|
||||
|
||||
https://launchpad.net/bugs/902332
|
||||
---
|
||||
hwdb/60-keyboard.hwdb | 2 +-
|
||||
1 file changed, 1 insertion(+), 1 deletion(-)
|
||||
|
||||
diff --git a/hwdb/60-keyboard.hwdb b/hwdb/60-keyboard.hwdb
|
||||
index ef0ebc5187..0ffcb83277 100644
|
||||
--- a/hwdb/60-keyboard.hwdb
|
||||
+++ b/hwdb/60-keyboard.hwdb
|
||||
@@ -939,7 +939,7 @@ keyboard:dmi:bvn*:bvr*:bd*:svn[sS][aA][mM][sS][uU][nN][gG]*:pn*550P*:pvr*
|
||||
# Series 7 / 9
|
||||
keyboard:dmi:bvn*:bvr*:bd*:svn[sS][aA][mM][sS][uU][nN][gG]*:pn*700Z*:pvr*
|
||||
keyboard:dmi:bvn*:bvr*:bd*:svn[sS][aA][mM][sS][uU][nN][gG]*:pn*700G*:pvr*
|
||||
-keyboard:dmi:bvn*:bvr*:bd*:svn[sS][aA][mM][sS][uU][nN][gG]*:pn*900X[34][CDEFG]*:pvr*
|
||||
+keyboard:dmi:bvn*:bvr*:bd*:svn[sS][aA][mM][sS][uU][nN][gG]*:pn*900X[34]*:pvr*
|
||||
keyboard:dmi:bvn*:bvr*:bd*:svn[sS][aA][mM][sS][uU][nN][gG]*:pn*940X3G*:pvr*
|
||||
KEYBOARD_KEY_ce=!prog1 # Fn+F1 launch settings
|
||||
KEYBOARD_KEY_a0=!mute # Fn+F6 mute
|
34
0072-systemctl-fix-broken-list-unit-files-with-root.patch
Normal file
34
0072-systemctl-fix-broken-list-unit-files-with-root.patch
Normal file
@ -0,0 +1,34 @@
|
||||
From 81fc054dc7c365545bca86d78bf36a12658cedb3 Mon Sep 17 00:00:00 2001
|
||||
From: Lukas Nykryn <lnykryn@redhat.com>
|
||||
Date: Tue, 26 Aug 2014 13:33:08 +0200
|
||||
Subject: [PATCH] systemctl: fix broken list-unit-files with --root
|
||||
|
||||
---
|
||||
src/shared/install.c | 7 ++++++-
|
||||
1 file changed, 6 insertions(+), 1 deletion(-)
|
||||
|
||||
diff --git a/src/shared/install.c b/src/shared/install.c
|
||||
index 4b09a69456..3ef995a928 100644
|
||||
--- a/src/shared/install.c
|
||||
+++ b/src/shared/install.c
|
||||
@@ -2072,6 +2072,7 @@ int unit_file_get_list(
|
||||
for (;;) {
|
||||
_cleanup_(unit_file_list_free_onep) UnitFileList *f = NULL;
|
||||
struct dirent *de;
|
||||
+ _cleanup_free_ char *path = NULL;
|
||||
|
||||
errno = 0;
|
||||
de = readdir(d);
|
||||
@@ -2121,7 +2122,11 @@ int unit_file_get_list(
|
||||
goto found;
|
||||
}
|
||||
|
||||
- r = unit_file_can_install(&paths, root_dir, f->path, true);
|
||||
+ path = path_make_absolute(de->d_name, *i);
|
||||
+ if (!path)
|
||||
+ return -ENOMEM;
|
||||
+
|
||||
+ r = unit_file_can_install(&paths, root_dir, path, true);
|
||||
if (r == -EINVAL || /* Invalid setting? */
|
||||
r == -EBADMSG || /* Invalid format? */
|
||||
r == -ENOENT /* Included file not found? */)
|
114
0073-tmpfiles-make-resolv.conf-entry-conditional-on-resol.patch
Normal file
114
0073-tmpfiles-make-resolv.conf-entry-conditional-on-resol.patch
Normal file
@ -0,0 +1,114 @@
|
||||
From aeb50ff0bd4bbbca74c4695072232348351d512d Mon Sep 17 00:00:00 2001
|
||||
From: Tom Gundersen <teg@jklm.no>
|
||||
Date: Wed, 27 Aug 2014 17:45:41 +0200
|
||||
Subject: [PATCH] tmpfiles: make resolv.conf entry conditional on resolved
|
||||
support
|
||||
|
||||
---
|
||||
Makefile.am | 15 +++++++++++++--
|
||||
TODO | 2 --
|
||||
configure.ac | 1 +
|
||||
tmpfiles.d/.gitignore | 1 +
|
||||
tmpfiles.d/{etc.conf => etc.conf.m4} | 2 ++
|
||||
5 files changed, 17 insertions(+), 4 deletions(-)
|
||||
create mode 100644 tmpfiles.d/.gitignore
|
||||
rename tmpfiles.d/{etc.conf => etc.conf.m4} (95%)
|
||||
|
||||
diff --git a/Makefile.am b/Makefile.am
|
||||
index cbdf551fa8..70faed4acb 100644
|
||||
--- a/Makefile.am
|
||||
+++ b/Makefile.am
|
||||
@@ -1940,14 +1940,16 @@ nodist_systemunit_DATA += \
|
||||
units/systemd-tmpfiles-setup.service \
|
||||
units/systemd-tmpfiles-clean.service
|
||||
|
||||
+nodist_tmpfiles_DATA = \
|
||||
+ tmpfiles.d/etc.conf
|
||||
+
|
||||
dist_tmpfiles_DATA = \
|
||||
tmpfiles.d/systemd.conf \
|
||||
tmpfiles.d/systemd-nologin.conf \
|
||||
tmpfiles.d/systemd-remote.conf \
|
||||
tmpfiles.d/tmp.conf \
|
||||
tmpfiles.d/x11.conf \
|
||||
- tmpfiles.d/var.conf \
|
||||
- tmpfiles.d/etc.conf
|
||||
+ tmpfiles.d/var.conf
|
||||
|
||||
if HAVE_SYSV_COMPAT
|
||||
dist_tmpfiles_DATA += \
|
||||
@@ -1970,10 +1972,14 @@ INSTALL_DIRS += \
|
||||
endif
|
||||
|
||||
EXTRA_DIST += \
|
||||
+ tmpfiles.d/etc.conf.m4 \
|
||||
units/systemd-tmpfiles-setup-dev.service.in \
|
||||
units/systemd-tmpfiles-setup.service.in \
|
||||
units/systemd-tmpfiles-clean.service.in
|
||||
|
||||
+CLEANFILES += \
|
||||
+ tmpfiles.d/etc.conf
|
||||
+
|
||||
# ------------------------------------------------------------------------------
|
||||
if ENABLE_SYSUSERS
|
||||
systemd_sysusers_SOURCES = \
|
||||
@@ -5708,6 +5714,11 @@ src/%: src/%.m4
|
||||
$(AM_V_at)$(MKDIR_P) $(dir $@)
|
||||
$(AM_V_M4)$(M4) -P $(M4_DEFINES) < $< > $@
|
||||
|
||||
+tmpfiles.d/%: tmpfiles.d/%.m4
|
||||
+ $(AM_V_at)$(MKDIR_P) $(dir $@)
|
||||
+ $(AM_V_M4)$(M4) -P $(M4_DEFINES) < $< > $@
|
||||
+
|
||||
+
|
||||
units/%: units/%.m4
|
||||
$(AM_V_at)$(MKDIR_P) $(dir $@)
|
||||
$(AM_V_M4)$(M4) -P $(M4_DEFINES) -DFOR_SYSTEM=1 < $< > $@
|
||||
diff --git a/TODO b/TODO
|
||||
index 09f82d3c37..372825e8bd 100644
|
||||
--- a/TODO
|
||||
+++ b/TODO
|
||||
@@ -120,8 +120,6 @@ Features:
|
||||
|
||||
* Allow multiple ExecStart= for all Type= settings, so that we can cover rescue.service nicely
|
||||
|
||||
-* the resolv.conf tmpfiles line should be covered by ENABLE_NETWORKD...
|
||||
-
|
||||
* Add a new verb "systemctl top"
|
||||
|
||||
* logind: allow users to kill or lock their own sessions
|
||||
diff --git a/configure.ac b/configure.ac
|
||||
index 18b719856b..08a8a105f8 100644
|
||||
--- a/configure.ac
|
||||
+++ b/configure.ac
|
||||
@@ -1023,6 +1023,7 @@ have_resolved=no
|
||||
AC_ARG_ENABLE(resolved, AS_HELP_STRING([--disable-resolved], [disable resolve daemon]))
|
||||
if test "x$enable_resolved" != "xno"; then
|
||||
have_resolved=yes
|
||||
+ M4_DEFINES="$M4_DEFINES -DENABLE_RESOLVED"
|
||||
fi
|
||||
AM_CONDITIONAL(ENABLE_RESOLVED, [test "$have_resolved" = "yes"])
|
||||
|
||||
diff --git a/tmpfiles.d/.gitignore b/tmpfiles.d/.gitignore
|
||||
new file mode 100644
|
||||
index 0000000000..eb323154ff
|
||||
--- /dev/null
|
||||
+++ b/tmpfiles.d/.gitignore
|
||||
@@ -0,0 +1 @@
|
||||
+etc.conf
|
||||
diff --git a/tmpfiles.d/etc.conf b/tmpfiles.d/etc.conf.m4
|
||||
similarity index 95%
|
||||
rename from tmpfiles.d/etc.conf
|
||||
rename to tmpfiles.d/etc.conf.m4
|
||||
index b23272cb27..f567c8d6ea 100644
|
||||
--- a/tmpfiles.d/etc.conf
|
||||
+++ b/tmpfiles.d/etc.conf.m4
|
||||
@@ -10,6 +10,8 @@
|
||||
L /etc/os-release - - - - ../usr/lib/os-release
|
||||
L /etc/localtime - - - - ../usr/share/zoneinfo/UTC
|
||||
L+ /etc/mtab - - - - ../proc/self/mounts
|
||||
+m4_ifdef(`ENABLE_RESOLVED',
|
||||
L /etc/resolv.conf - - - - ../run/systemd/resolve/resolv.conf
|
||||
+)
|
||||
C /etc/nsswitch.conf - - - -
|
||||
C /etc/pam.d - - - -
|
44
0074-TODO.patch
Normal file
44
0074-TODO.patch
Normal file
@ -0,0 +1,44 @@
|
||||
From 285e8c126b1607188249c42e74c172cb69cc99a6 Mon Sep 17 00:00:00 2001
|
||||
From: Tom Gundersen <teg@jklm.no>
|
||||
Date: Wed, 27 Aug 2014 17:46:00 +0200
|
||||
Subject: [PATCH] TODO
|
||||
|
||||
---
|
||||
TODO | 13 -------------
|
||||
1 file changed, 13 deletions(-)
|
||||
|
||||
diff --git a/TODO b/TODO
|
||||
index 372825e8bd..a00c13dab2 100644
|
||||
--- a/TODO
|
||||
+++ b/TODO
|
||||
@@ -61,11 +61,6 @@ Features:
|
||||
* systemd.show_status= should probably have a mode where only failed
|
||||
units are shown.
|
||||
|
||||
-* sd-event:
|
||||
- - make it possible to embedd our event loop into foreign event loops
|
||||
- by passing out the epoll fd and providing three functions that fit
|
||||
- into GSource nicely.
|
||||
-
|
||||
* networkd:
|
||||
- add LLDP client side support
|
||||
- ipv4ll with multiple interfaces doesn't work when both dhcp and
|
||||
@@ -74,18 +69,10 @@ Features:
|
||||
- dhcp and ipv4ll should probably be skipped for "lo" devices, even
|
||||
if the user has a catchall .network file installed, that might
|
||||
theoretically match it.
|
||||
- - we probably should introduce a new operational state that
|
||||
- indicates that we are trying to acquire some configuration for a
|
||||
- link but haven't acquired any yet. Just to inform the admin that
|
||||
- networkd cares about an interface, but is still in progress..
|
||||
- the DHCP lease data (such as NTP/DNS) is still made available when
|
||||
a carrier is lost on a link. It should be removed instantly.
|
||||
- .network setting that allows overriding of the hostname to send to the dhcp server
|
||||
http://lists.freedesktop.org/archives/systemd-devel/2014-July/021550.html
|
||||
- - add per-network Domains= settings, with a special syntax Domains=*
|
||||
- for routing all non-otherwise routed traffic to this link
|
||||
- - add UseDomains= setting to [DHCP] to add dhcp supplied domains to
|
||||
- per-interface Domains= list.
|
||||
- expose in the API the following bits:
|
||||
- option 15, domain name and/or option 119, search list
|
||||
- option 12, host name and/or option 81, fqdn
|
41
0075-shared-drop-UNIQUE.patch
Normal file
41
0075-shared-drop-UNIQUE.patch
Normal file
@ -0,0 +1,41 @@
|
||||
From 418bcb0ce3b704ea26ee1b4a68706abca536f65a Mon Sep 17 00:00:00 2001
|
||||
From: David Herrmann <dh.herrmann@gmail.com>
|
||||
Date: Fri, 22 Aug 2014 14:38:28 +0200
|
||||
Subject: [PATCH] shared: drop UNIQUE()
|
||||
|
||||
The UNIQUE() macro works fine if used in un-stacked macros. However, once
|
||||
you stack them like:
|
||||
MAX(MIN(a, b),
|
||||
CLAMP(MAX(c, d), e, f))
|
||||
you will get warnings due to shadowing other variables. gcc uses the last
|
||||
line of a macro expansion as value for __LINE__, therefore, we cannot even
|
||||
avoid this by splitting the expressions across lines.
|
||||
|
||||
Remove the only user of UNIQUE() so we introduce a new helper in
|
||||
follow-ups.
|
||||
---
|
||||
src/shared/macro.h | 4 +---
|
||||
1 file changed, 1 insertion(+), 3 deletions(-)
|
||||
|
||||
diff --git a/src/shared/macro.h b/src/shared/macro.h
|
||||
index 43fa3e556f..2807bc74e8 100644
|
||||
--- a/src/shared/macro.h
|
||||
+++ b/src/shared/macro.h
|
||||
@@ -79,8 +79,6 @@
|
||||
#define XCONCATENATE(x, y) x ## y
|
||||
#define CONCATENATE(x, y) XCONCATENATE(x, y)
|
||||
|
||||
-#define UNIQUE(prefix) CONCATENATE(prefix, __LINE__)
|
||||
-
|
||||
/* Rounds up */
|
||||
|
||||
#define ALIGN4(l) (((l) + 3) & ~3)
|
||||
@@ -219,7 +217,7 @@ static inline unsigned long ALIGN_POWER2(unsigned long u) {
|
||||
#else
|
||||
#define assert_cc(expr) \
|
||||
DISABLE_WARNING_DECLARATION_AFTER_STATEMENT; \
|
||||
- struct UNIQUE(_assert_struct_) { \
|
||||
+ struct CONCATENATE(_assert_struct_, __LINE__) { \
|
||||
char x[(expr) ? 0 : -1]; \
|
||||
}; \
|
||||
REENABLE_WARNING
|
119
0076-shared-make-container_of-use-unique-variable-names.patch
Normal file
119
0076-shared-make-container_of-use-unique-variable-names.patch
Normal file
@ -0,0 +1,119 @@
|
||||
From fb835651aff79a1e7fc5795086c9b26e59a8e6ca Mon Sep 17 00:00:00 2001
|
||||
From: David Herrmann <dh.herrmann@gmail.com>
|
||||
Date: Fri, 22 Aug 2014 14:41:37 +0200
|
||||
Subject: [PATCH] shared: make container_of() use unique variable names
|
||||
|
||||
If you stack container_of() macros, you will get warnings due to shadowing
|
||||
variables of the parent context. To avoid this, use unique names for
|
||||
variables.
|
||||
|
||||
Two new helpers are added:
|
||||
UNIQ: This evaluates to a truly unique value never returned by any
|
||||
evaluation of this macro. It's a shortcut for __COUNTER__.
|
||||
UNIQ_T: Takes two arguments and concatenates them. It is a shortcut for
|
||||
CONCATENATE, but meant to defined typed local variables.
|
||||
|
||||
As you usually want to use variables that you just defined, you need to
|
||||
reference the same unique value at least two times. However, UNIQ returns
|
||||
a new value on each evaluation, therefore, you have to pass the unique
|
||||
values into the macro like this:
|
||||
|
||||
#define my_macro(a, b) __max_macro(UNIQ, UNIQ, (a), (b))
|
||||
#define __my_macro(uniqa, uniqb, a, b) ({
|
||||
typeof(a) UNIQ_T(A, uniqa) = (a);
|
||||
typeof(b) UNIQ_T(B, uniqb) = (b);
|
||||
MY_UNSAFE_MACRO(UNIQ_T(A, uniqa), UNIQ_T(B, uniqb));
|
||||
})
|
||||
|
||||
This way, MY_UNSAFE_MACRO() can safely evaluate it's arguments multiple
|
||||
times as they are local variables. But you can also stack invocations to
|
||||
the macro my_macro() without clashing names.
|
||||
|
||||
This is the same as if you did:
|
||||
|
||||
#define my_macro(a, b) __max_macro(__COUNTER__, __COUNTER__, (a), (b))
|
||||
#define __my_macro(prefixa, prefixb, a, b) ({
|
||||
typeof(a) CONCATENATE(A, prefixa) = (a);
|
||||
typeof(b) CONCATENATE(B, prefixb) = (b);
|
||||
MY_UNSAFE_MACRO(CONCATENATE(A, prefixa), CONCATENATE(B, prefixb));
|
||||
})
|
||||
|
||||
...but in my opinion, the first macro is easier to write and read.
|
||||
|
||||
This patch starts by converting container_of() to use this new helper.
|
||||
Other macros may follow (like MIN, MAX, CLAMP, ...).
|
||||
---
|
||||
src/shared/macro.h | 13 ++++++++-----
|
||||
src/test/test-util.c | 19 +++++++++++++++++++
|
||||
2 files changed, 27 insertions(+), 5 deletions(-)
|
||||
|
||||
diff --git a/src/shared/macro.h b/src/shared/macro.h
|
||||
index 2807bc74e8..e6734804bd 100644
|
||||
--- a/src/shared/macro.h
|
||||
+++ b/src/shared/macro.h
|
||||
@@ -79,6 +79,9 @@
|
||||
#define XCONCATENATE(x, y) x ## y
|
||||
#define CONCATENATE(x, y) XCONCATENATE(x, y)
|
||||
|
||||
+#define UNIQ_T(x, uniq) CONCATENATE(__unique_prefix_, CONCATENATE(x, uniq))
|
||||
+#define UNIQ __COUNTER__
|
||||
+
|
||||
/* Rounds up */
|
||||
|
||||
#define ALIGN4(l) (((l) + 3) & ~3)
|
||||
@@ -122,13 +125,13 @@ static inline unsigned long ALIGN_POWER2(unsigned long u) {
|
||||
* @ptr: the pointer to the member.
|
||||
* @type: the type of the container struct this is embedded in.
|
||||
* @member: the name of the member within the struct.
|
||||
- *
|
||||
*/
|
||||
-#define container_of(ptr, type, member) \
|
||||
+#define container_of(ptr, type, member) __container_of(UNIQ, (ptr), type, member)
|
||||
+#define __container_of(uniq, ptr, type, member) \
|
||||
__extension__ ({ \
|
||||
- const typeof( ((type *)0)->member ) *__mptr = (ptr); \
|
||||
- (type *)( (char *)__mptr - offsetof(type,member) ); \
|
||||
- })
|
||||
+ const typeof( ((type*)0)->member ) *UNIQ_T(A, uniq) = (ptr); \
|
||||
+ (type*)( (char *)UNIQ_T(A, uniq) - offsetof(type,member) ); \
|
||||
+ })
|
||||
|
||||
#undef MAX
|
||||
#define MAX(a,b) \
|
||||
diff --git a/src/test/test-util.c b/src/test/test-util.c
|
||||
index 4d9b28f9c8..795f3a1b3d 100644
|
||||
--- a/src/test/test-util.c
|
||||
+++ b/src/test/test-util.c
|
||||
@@ -96,6 +96,24 @@ static void test_max(void) {
|
||||
assert_cc(MAXSIZE(char, long) == sizeof(long));
|
||||
}
|
||||
|
||||
+static void test_container_of(void) {
|
||||
+ struct mytype {
|
||||
+ uint8_t pad1[3];
|
||||
+ uint64_t v1;
|
||||
+ uint8_t pad2[2];
|
||||
+ uint32_t v2;
|
||||
+ } _packed_ myval = { };
|
||||
+
|
||||
+ assert_cc(sizeof(myval) == 17);
|
||||
+ assert_se(container_of(&myval.v1, struct mytype, v1) == &myval);
|
||||
+ assert_se(container_of(&myval.v2, struct mytype, v2) == &myval);
|
||||
+ assert_se(container_of(&container_of(&myval.v2,
|
||||
+ struct mytype,
|
||||
+ v2)->v1,
|
||||
+ struct mytype,
|
||||
+ v1) == &myval);
|
||||
+}
|
||||
+
|
||||
static void test_first_word(void) {
|
||||
assert_se(first_word("Hello", ""));
|
||||
assert_se(first_word("Hello", "Hello"));
|
||||
@@ -1218,6 +1236,7 @@ int main(int argc, char *argv[]) {
|
||||
test_streq_ptr();
|
||||
test_align_power2();
|
||||
test_max();
|
||||
+ test_container_of();
|
||||
test_first_word();
|
||||
test_close_many();
|
||||
test_parse_boolean();
|
33
0077-login-fix-memory-leak-on-DropController.patch
Normal file
33
0077-login-fix-memory-leak-on-DropController.patch
Normal file
@ -0,0 +1,33 @@
|
||||
From 60240797a4ce464ec7a0537ccbec4c83f599251c Mon Sep 17 00:00:00 2001
|
||||
From: David Herrmann <dh.herrmann@gmail.com>
|
||||
Date: Fri, 22 Aug 2014 14:57:11 +0200
|
||||
Subject: [PATCH] login: fix memory-leak on DropController()
|
||||
|
||||
Our bus-name watch helpers only remove a bus-name if it's not a
|
||||
controller, anymore. If we call manager_drop_busname() before
|
||||
unregistering the controller, the busname will not be dropped. Therefore,
|
||||
first drop the controller, then drop the bus-name.
|
||||
---
|
||||
src/login/logind-session.c | 6 ++++--
|
||||
1 file changed, 4 insertions(+), 2 deletions(-)
|
||||
|
||||
diff --git a/src/login/logind-session.c b/src/login/logind-session.c
|
||||
index 136bbce78e..0c6e425603 100644
|
||||
--- a/src/login/logind-session.c
|
||||
+++ b/src/login/logind-session.c
|
||||
@@ -1061,11 +1061,13 @@ bool session_is_controller(Session *s, const char *sender) {
|
||||
|
||||
static void session_swap_controller(Session *s, char *name) {
|
||||
SessionDevice *sd;
|
||||
+ char *c;
|
||||
|
||||
if (s->controller) {
|
||||
- manager_drop_busname(s->manager, s->controller);
|
||||
- free(s->controller);
|
||||
+ c = s->controller;
|
||||
s->controller = NULL;
|
||||
+ manager_drop_busname(s->manager, c);
|
||||
+ free(c);
|
||||
|
||||
/* Drop all devices as they're now unused. Do that after the
|
||||
* controller is released to avoid sending out useles
|
26
0078-udev-add-missing-new-line-in-udevadm-error.patch
Normal file
26
0078-udev-add-missing-new-line-in-udevadm-error.patch
Normal file
@ -0,0 +1,26 @@
|
||||
From 92e63a51052e9ba2fbe6e47a173b6264ae292a58 Mon Sep 17 00:00:00 2001
|
||||
From: David Herrmann <dh.herrmann@gmail.com>
|
||||
Date: Wed, 27 Aug 2014 18:02:17 +0200
|
||||
Subject: [PATCH] udev: add missing new-line in udevadm error
|
||||
|
||||
fprintf() does not add new-lines automatically like log_*() does. Add the
|
||||
missing \n specified so "udevadm" invoked without arguments adds a newline
|
||||
to:
|
||||
udevadm: missing or unknown command
|
||||
---
|
||||
src/udev/udevadm.c | 2 +-
|
||||
1 file changed, 1 insertion(+), 1 deletion(-)
|
||||
|
||||
diff --git a/src/udev/udevadm.c b/src/udev/udevadm.c
|
||||
index 2c11550467..df546dd823 100644
|
||||
--- a/src/udev/udevadm.c
|
||||
+++ b/src/udev/udevadm.c
|
||||
@@ -134,7 +134,7 @@ int main(int argc, char *argv[]) {
|
||||
goto out;
|
||||
}
|
||||
|
||||
- fprintf(stderr, "%s: missing or unknown command", program_invocation_short_name);
|
||||
+ fprintf(stderr, "%s: missing or unknown command\n", program_invocation_short_name);
|
||||
rc = 2;
|
||||
out:
|
||||
label_finish();
|
37
0079-util-make-lookup_uid-global.patch
Normal file
37
0079-util-make-lookup_uid-global.patch
Normal file
@ -0,0 +1,37 @@
|
||||
From f1566e63da92cee5cbc0074df9cd9a8dc078a62e Mon Sep 17 00:00:00 2001
|
||||
From: David Herrmann <dh.herrmann@gmail.com>
|
||||
Date: Wed, 27 Aug 2014 18:03:29 +0200
|
||||
Subject: [PATCH] util: make lookup_uid() global
|
||||
|
||||
This is a useful helper, make it global. It will be required for
|
||||
libsystemd-terminal, at minimum.
|
||||
---
|
||||
src/shared/util.c | 2 +-
|
||||
src/shared/util.h | 1 +
|
||||
2 files changed, 2 insertions(+), 1 deletion(-)
|
||||
|
||||
diff --git a/src/shared/util.c b/src/shared/util.c
|
||||
index fdcf5719fa..9e4ff85ffb 100644
|
||||
--- a/src/shared/util.c
|
||||
+++ b/src/shared/util.c
|
||||
@@ -2604,7 +2604,7 @@ bool hostname_is_set(void) {
|
||||
return !isempty(u.nodename) && !streq(u.nodename, "(none)");
|
||||
}
|
||||
|
||||
-static char *lookup_uid(uid_t uid) {
|
||||
+char *lookup_uid(uid_t uid) {
|
||||
long bufsize;
|
||||
char *name;
|
||||
_cleanup_free_ char *buf = NULL;
|
||||
diff --git a/src/shared/util.h b/src/shared/util.h
|
||||
index ea87c96956..3401280d09 100644
|
||||
--- a/src/shared/util.h
|
||||
+++ b/src/shared/util.h
|
||||
@@ -432,6 +432,7 @@ int sigprocmask_many(int how, ...);
|
||||
|
||||
bool hostname_is_set(void);
|
||||
|
||||
+char* lookup_uid(uid_t uid);
|
||||
char* gethostname_malloc(void);
|
||||
char* getlogname_malloc(void);
|
||||
char* getusername_malloc(void);
|
172
0080-bus-split-bus_map_all_properties-into-multiple-helpe.patch
Normal file
172
0080-bus-split-bus_map_all_properties-into-multiple-helpe.patch
Normal file
@ -0,0 +1,172 @@
|
||||
From aae2b488d084cf2af9a552a55e1d9cc614f2a12a Mon Sep 17 00:00:00 2001
|
||||
From: David Herrmann <dh.herrmann@gmail.com>
|
||||
Date: Sun, 24 Aug 2014 18:55:58 +0200
|
||||
Subject: [PATCH] bus: split bus_map_all_properties into multiple helpers
|
||||
|
||||
The bus_map_all_properties() helper calls
|
||||
org.freedesktop.DBus.Properties.GetAll() on a given target and parses the
|
||||
result according to a given property-table. This simplifies dealing with
|
||||
DBus.Properties significantly. However, the function is blocking and thus
|
||||
not really useful in many situations.
|
||||
|
||||
This patch extracts the core of this function and adds two new helpers
|
||||
which directly take dbus-messages as arguments. This way, you can issue
|
||||
asynchronous requests and parse the result via these helpers:
|
||||
|
||||
bus_message_map_all_properties():
|
||||
This is the same as bus_map_all_properties() but takes the result
|
||||
message from a GetAll() request as argument. You can thus issue an
|
||||
asynchronous GetAll() request and then use this helper once you got
|
||||
the result.
|
||||
|
||||
bus_message_map_properties_changed():
|
||||
This function takes a signal-message that was retrieved via a
|
||||
PropertiesChanged signal and then parses it like if you retrieved
|
||||
it via GetAll(). Furthermore, this function returns the number of
|
||||
matched properties that got invalidated by the PropertiesChanged
|
||||
signal, but didn't carry the new value. This way, the caller can
|
||||
issue a new GetAll() request and then parse the result.
|
||||
|
||||
The old function bus_map_all_properties() is functionally unchanged, but
|
||||
now uses bus_message_map_all_properties() internally.
|
||||
---
|
||||
src/libsystemd/sd-bus/bus-util.c | 93 +++++++++++++++++++++++++++++++---------
|
||||
src/libsystemd/sd-bus/bus-util.h | 8 ++++
|
||||
2 files changed, 80 insertions(+), 21 deletions(-)
|
||||
|
||||
diff --git a/src/libsystemd/sd-bus/bus-util.c b/src/libsystemd/sd-bus/bus-util.c
|
||||
index c97bf7d99d..aed3889b12 100644
|
||||
--- a/src/libsystemd/sd-bus/bus-util.c
|
||||
+++ b/src/libsystemd/sd-bus/bus-util.c
|
||||
@@ -974,32 +974,17 @@ static int map_basic(sd_bus *bus, const char *member, sd_bus_message *m, sd_bus_
|
||||
return r;
|
||||
}
|
||||
|
||||
-int bus_map_all_properties(sd_bus *bus,
|
||||
- const char *destination,
|
||||
- const char *path,
|
||||
- const struct bus_properties_map *map,
|
||||
- void *userdata) {
|
||||
- _cleanup_bus_message_unref_ sd_bus_message *m = NULL;
|
||||
+int bus_message_map_all_properties(sd_bus *bus,
|
||||
+ sd_bus_message *m,
|
||||
+ const struct bus_properties_map *map,
|
||||
+ void *userdata) {
|
||||
_cleanup_bus_error_free_ sd_bus_error error = SD_BUS_ERROR_NULL;
|
||||
int r;
|
||||
|
||||
assert(bus);
|
||||
- assert(destination);
|
||||
- assert(path);
|
||||
+ assert(m);
|
||||
assert(map);
|
||||
|
||||
- r = sd_bus_call_method(
|
||||
- bus,
|
||||
- destination,
|
||||
- path,
|
||||
- "org.freedesktop.DBus.Properties",
|
||||
- "GetAll",
|
||||
- &error,
|
||||
- &m,
|
||||
- "s", "");
|
||||
- if (r < 0)
|
||||
- return r;
|
||||
-
|
||||
r = sd_bus_message_enter_container(m, SD_BUS_TYPE_ARRAY, "{sv}");
|
||||
if (r < 0)
|
||||
return r;
|
||||
@@ -1052,7 +1037,73 @@ int bus_map_all_properties(sd_bus *bus,
|
||||
return r;
|
||||
}
|
||||
|
||||
- return r;
|
||||
+ return sd_bus_message_exit_container(m);
|
||||
+}
|
||||
+
|
||||
+int bus_message_map_properties_changed(sd_bus *bus,
|
||||
+ sd_bus_message *m,
|
||||
+ const struct bus_properties_map *map,
|
||||
+ void *userdata) {
|
||||
+ const char *member;
|
||||
+ int r, invalidated, i;
|
||||
+
|
||||
+ assert(bus);
|
||||
+ assert(m);
|
||||
+ assert(map);
|
||||
+
|
||||
+ /* skip interface, but allow callers to do that themselves */
|
||||
+ sd_bus_message_skip(m, "s");
|
||||
+
|
||||
+ r = bus_message_map_all_properties(bus, m, map, userdata);
|
||||
+ if (r < 0)
|
||||
+ return r;
|
||||
+
|
||||
+ r = sd_bus_message_enter_container(m, SD_BUS_TYPE_ARRAY, "s");
|
||||
+ if (r < 0)
|
||||
+ return r;
|
||||
+
|
||||
+ invalidated = 0;
|
||||
+ while ((r = sd_bus_message_read_basic(m, SD_BUS_TYPE_STRING, &member)) > 0)
|
||||
+ for (i = 0; map[i].member; i++)
|
||||
+ if (streq(map[i].member, member)) {
|
||||
+ ++invalidated;
|
||||
+ break;
|
||||
+ }
|
||||
+
|
||||
+ r = sd_bus_message_exit_container(m);
|
||||
+ if (r < 0)
|
||||
+ return r;
|
||||
+
|
||||
+ return invalidated;
|
||||
+}
|
||||
+
|
||||
+int bus_map_all_properties(sd_bus *bus,
|
||||
+ const char *destination,
|
||||
+ const char *path,
|
||||
+ const struct bus_properties_map *map,
|
||||
+ void *userdata) {
|
||||
+ _cleanup_bus_message_unref_ sd_bus_message *m = NULL;
|
||||
+ _cleanup_bus_error_free_ sd_bus_error error = SD_BUS_ERROR_NULL;
|
||||
+ int r;
|
||||
+
|
||||
+ assert(bus);
|
||||
+ assert(destination);
|
||||
+ assert(path);
|
||||
+ assert(map);
|
||||
+
|
||||
+ r = sd_bus_call_method(
|
||||
+ bus,
|
||||
+ destination,
|
||||
+ path,
|
||||
+ "org.freedesktop.DBus.Properties",
|
||||
+ "GetAll",
|
||||
+ &error,
|
||||
+ &m,
|
||||
+ "s", "");
|
||||
+ if (r < 0)
|
||||
+ return r;
|
||||
+
|
||||
+ return bus_message_map_all_properties(bus, m, map, userdata);
|
||||
}
|
||||
|
||||
int bus_open_transport(BusTransport transport, const char *host, bool user, sd_bus **bus) {
|
||||
diff --git a/src/libsystemd/sd-bus/bus-util.h b/src/libsystemd/sd-bus/bus-util.h
|
||||
index faf1775809..696daa1f03 100644
|
||||
--- a/src/libsystemd/sd-bus/bus-util.h
|
||||
+++ b/src/libsystemd/sd-bus/bus-util.h
|
||||
@@ -46,6 +46,14 @@ struct bus_properties_map {
|
||||
|
||||
int bus_map_id128(sd_bus *bus, const char *member, sd_bus_message *m, sd_bus_error *error, void *userdata);
|
||||
|
||||
+int bus_message_map_all_properties(sd_bus *bus,
|
||||
+ sd_bus_message *m,
|
||||
+ const struct bus_properties_map *map,
|
||||
+ void *userdata);
|
||||
+int bus_message_map_properties_changed(sd_bus *bus,
|
||||
+ sd_bus_message *m,
|
||||
+ const struct bus_properties_map *map,
|
||||
+ void *userdata);
|
||||
int bus_map_all_properties(sd_bus *bus,
|
||||
const char *destination,
|
||||
const char *path,
|
1828
0081-terminal-add-system-view-interface.patch
Normal file
1828
0081-terminal-add-system-view-interface.patch
Normal file
File diff suppressed because it is too large
Load Diff
975
0082-terminal-add-input-interface.patch
Normal file
975
0082-terminal-add-input-interface.patch
Normal file
@ -0,0 +1,975 @@
|
||||
From e202fa31fb2d60084e7b2ab7976a81c138184d40 Mon Sep 17 00:00:00 2001
|
||||
From: David Herrmann <dh.herrmann@gmail.com>
|
||||
Date: Wed, 27 Aug 2014 18:17:27 +0200
|
||||
Subject: [PATCH] terminal: add input interface
|
||||
|
||||
The idev-interface provides input drivers for all libsystemd-terminal
|
||||
based applications. It is split into 4 main objects:
|
||||
idev_context: The context object tracks global state of the input
|
||||
interface. This will include data like system-keymaps,
|
||||
xkb contexts and more.
|
||||
idev_session: A session serves as controller for a set of devices.
|
||||
Each session on an idev-context is independent of each
|
||||
other. The session is also the main notification object.
|
||||
All events raised via idev are reported through the
|
||||
session interface. Apart of that, the session is a
|
||||
pretty dumb object that just contains devices.
|
||||
idev_element: Elements provide real hardware in the idev stack. For
|
||||
each hardware device, one element is added. Elements
|
||||
have no knowledge of higher-level device types, they
|
||||
only provide raw input data to the upper levels. For
|
||||
example, each evdev device is represented by a different
|
||||
element in an idev session.
|
||||
idev_device: Devices are objects that the application deals with. An
|
||||
application is usually not interested in elements (and
|
||||
those are hidden to applications), instead, they want
|
||||
high-level input devices like keyboard, touchpads, mice
|
||||
and more. Device are the high-level interface provided
|
||||
by idev. Each device might be fed by a set of elements.
|
||||
Elements drive the device. If elements are removed,
|
||||
devices are destroyed. If elements are added, suitable
|
||||
devices are created.
|
||||
|
||||
Applications should monitor the system for sessions and hardware devices.
|
||||
For each session they want to operate on, they create an idev_session
|
||||
object and add hardware to that object. The idev interface requires the
|
||||
application to monitor the system (preferably via sysview_*, but not
|
||||
required) for hardware devices. Whenever hardware is added to the idev
|
||||
session, new devices *might* be created. The relationship between hardware
|
||||
and high-level idev-devices is hidden in the idev-session and not exposed.
|
||||
|
||||
Internally, the idev elements and devices are virtual objects. Each real
|
||||
hardware and device type inherits those virtual objects and provides real
|
||||
elements and devices. Those types will be added in follow-up commits.
|
||||
|
||||
Data flow from hardware to the application is done via idev_*_feed()
|
||||
functions. Data flow from applications to hardware is done via
|
||||
idev_*_feedback() functions. Feedback is usually used for LEDs, FF and
|
||||
similar operations.
|
||||
---
|
||||
Makefile.am | 3 +
|
||||
src/libsystemd-terminal/idev-internal.h | 165 +++++++++
|
||||
src/libsystemd-terminal/idev.c | 587 ++++++++++++++++++++++++++++++++
|
||||
src/libsystemd-terminal/idev.h | 133 ++++++++
|
||||
4 files changed, 888 insertions(+)
|
||||
create mode 100644 src/libsystemd-terminal/idev-internal.h
|
||||
create mode 100644 src/libsystemd-terminal/idev.c
|
||||
create mode 100644 src/libsystemd-terminal/idev.h
|
||||
|
||||
diff --git a/Makefile.am b/Makefile.am
|
||||
index 3a263f8c17..82f474e20e 100644
|
||||
--- a/Makefile.am
|
||||
+++ b/Makefile.am
|
||||
@@ -2971,6 +2971,9 @@ libsystemd_terminal_la_CFLAGS = \
|
||||
$(AM_CFLAGS)
|
||||
|
||||
libsystemd_terminal_la_SOURCES = \
|
||||
+ src/libsystemd-terminal/idev.h \
|
||||
+ src/libsystemd-terminal/idev-internal.h \
|
||||
+ src/libsystemd-terminal/idev.c \
|
||||
src/libsystemd-terminal/sysview.h \
|
||||
src/libsystemd-terminal/sysview-internal.h \
|
||||
src/libsystemd-terminal/sysview.c \
|
||||
diff --git a/src/libsystemd-terminal/idev-internal.h b/src/libsystemd-terminal/idev-internal.h
|
||||
new file mode 100644
|
||||
index 0000000000..bffefbb9c1
|
||||
--- /dev/null
|
||||
+++ b/src/libsystemd-terminal/idev-internal.h
|
||||
@@ -0,0 +1,165 @@
|
||||
+/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
|
||||
+
|
||||
+/***
|
||||
+ This file is part of systemd.
|
||||
+
|
||||
+ Copyright (C) 2014 David Herrmann <dh.herrmann@gmail.com>
|
||||
+
|
||||
+ 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
|
||||
+ the Free Software Foundation; either version 2.1 of the License, or
|
||||
+ (at your option) any later version.
|
||||
+
|
||||
+ systemd is distributed in the hope that it will be useful, but
|
||||
+ WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
+ Lesser General Public License for more details.
|
||||
+
|
||||
+ You should have received a copy of the GNU Lesser General Public License
|
||||
+ along with systemd; If not, see <http://www.gnu.org/licenses/>.
|
||||
+***/
|
||||
+
|
||||
+#pragma once
|
||||
+
|
||||
+#include <inttypes.h>
|
||||
+#include <stdbool.h>
|
||||
+#include <stdlib.h>
|
||||
+#include <systemd/sd-bus.h>
|
||||
+#include <systemd/sd-event.h>
|
||||
+#include "hashmap.h"
|
||||
+#include "idev.h"
|
||||
+#include "list.h"
|
||||
+#include "util.h"
|
||||
+
|
||||
+typedef struct idev_link idev_link;
|
||||
+typedef struct idev_device_vtable idev_device_vtable;
|
||||
+typedef struct idev_element idev_element;
|
||||
+typedef struct idev_element_vtable idev_element_vtable;
|
||||
+
|
||||
+/*
|
||||
+ * Element Links
|
||||
+ */
|
||||
+
|
||||
+struct idev_link {
|
||||
+ /* element-to-device connection */
|
||||
+ LIST_FIELDS(idev_link, links_by_element);
|
||||
+ idev_element *element;
|
||||
+
|
||||
+ /* device-to-element connection */
|
||||
+ LIST_FIELDS(idev_link, links_by_device);
|
||||
+ idev_device *device;
|
||||
+};
|
||||
+
|
||||
+/*
|
||||
+ * Devices
|
||||
+ */
|
||||
+
|
||||
+struct idev_device_vtable {
|
||||
+ void (*free) (idev_device *d);
|
||||
+ void (*attach) (idev_device *d, idev_link *l);
|
||||
+ void (*detach) (idev_device *d, idev_link *l);
|
||||
+ int (*feed) (idev_device *d, idev_data *data);
|
||||
+};
|
||||
+
|
||||
+struct idev_device {
|
||||
+ const idev_device_vtable *vtable;
|
||||
+ idev_session *session;
|
||||
+ char *name;
|
||||
+
|
||||
+ LIST_HEAD(idev_link, links);
|
||||
+
|
||||
+ bool public : 1;
|
||||
+ bool enabled : 1;
|
||||
+};
|
||||
+
|
||||
+#define IDEV_DEVICE_INIT(_vtable, _session) ((idev_device){ \
|
||||
+ .vtable = (_vtable), \
|
||||
+ .session = (_session), \
|
||||
+ })
|
||||
+
|
||||
+idev_device *idev_find_device(idev_session *s, const char *name);
|
||||
+
|
||||
+int idev_device_add(idev_device *d, const char *name);
|
||||
+idev_device *idev_device_free(idev_device *d);
|
||||
+
|
||||
+DEFINE_TRIVIAL_CLEANUP_FUNC(idev_device*, idev_device_free);
|
||||
+
|
||||
+int idev_device_feed(idev_device *d, idev_data *data);
|
||||
+void idev_device_feedback(idev_device *d, idev_data *data);
|
||||
+
|
||||
+/*
|
||||
+ * Elements
|
||||
+ */
|
||||
+
|
||||
+struct idev_element_vtable {
|
||||
+ void (*free) (idev_element *e);
|
||||
+ void (*enable) (idev_element *e);
|
||||
+ void (*disable) (idev_element *e);
|
||||
+ void (*open) (idev_element *e);
|
||||
+ void (*close) (idev_element *e);
|
||||
+ void (*feedback) (idev_element *e, idev_data *data);
|
||||
+};
|
||||
+
|
||||
+struct idev_element {
|
||||
+ const idev_element_vtable *vtable;
|
||||
+ idev_session *session;
|
||||
+ unsigned long n_open;
|
||||
+ char *name;
|
||||
+
|
||||
+ LIST_HEAD(idev_link, links);
|
||||
+
|
||||
+ bool enabled : 1;
|
||||
+ bool readable : 1;
|
||||
+ bool writable : 1;
|
||||
+};
|
||||
+
|
||||
+#define IDEV_ELEMENT_INIT(_vtable, _session) ((idev_element){ \
|
||||
+ .vtable = (_vtable), \
|
||||
+ .session = (_session), \
|
||||
+ })
|
||||
+
|
||||
+idev_element *idev_find_element(idev_session *s, const char *name);
|
||||
+
|
||||
+int idev_element_add(idev_element *e, const char *name);
|
||||
+idev_element *idev_element_free(idev_element *e);
|
||||
+
|
||||
+DEFINE_TRIVIAL_CLEANUP_FUNC(idev_element*, idev_element_free);
|
||||
+
|
||||
+int idev_element_feed(idev_element *e, idev_data *data);
|
||||
+void idev_element_feedback(idev_element *e, idev_data *data);
|
||||
+
|
||||
+/*
|
||||
+ * Sessions
|
||||
+ */
|
||||
+
|
||||
+struct idev_session {
|
||||
+ idev_context *context;
|
||||
+ char *name;
|
||||
+ char *path;
|
||||
+
|
||||
+ Hashmap *element_map;
|
||||
+ Hashmap *device_map;
|
||||
+
|
||||
+ idev_event_fn event_fn;
|
||||
+ void *userdata;
|
||||
+
|
||||
+ bool custom : 1;
|
||||
+ bool managed : 1;
|
||||
+ bool enabled : 1;
|
||||
+};
|
||||
+
|
||||
+idev_session *idev_find_session(idev_context *c, const char *name);
|
||||
+int idev_session_raise_device_data(idev_session *s, idev_device *d, idev_data *data);
|
||||
+
|
||||
+/*
|
||||
+ * Contexts
|
||||
+ */
|
||||
+
|
||||
+struct idev_context {
|
||||
+ unsigned long ref;
|
||||
+ sd_event *event;
|
||||
+ sd_bus *sysbus;
|
||||
+
|
||||
+ Hashmap *session_map;
|
||||
+ Hashmap *data_map;
|
||||
+};
|
||||
diff --git a/src/libsystemd-terminal/idev.c b/src/libsystemd-terminal/idev.c
|
||||
new file mode 100644
|
||||
index 0000000000..5e3080797a
|
||||
--- /dev/null
|
||||
+++ b/src/libsystemd-terminal/idev.c
|
||||
@@ -0,0 +1,587 @@
|
||||
+/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
|
||||
+
|
||||
+/***
|
||||
+ This file is part of systemd.
|
||||
+
|
||||
+ Copyright (C) 2014 David Herrmann <dh.herrmann@gmail.com>
|
||||
+
|
||||
+ 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
|
||||
+ the Free Software Foundation; either version 2.1 of the License, or
|
||||
+ (at your option) any later version.
|
||||
+
|
||||
+ systemd is distributed in the hope that it will be useful, but
|
||||
+ WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
+ Lesser General Public License for more details.
|
||||
+
|
||||
+ You should have received a copy of the GNU Lesser General Public License
|
||||
+ along with systemd; If not, see <http://www.gnu.org/licenses/>.
|
||||
+***/
|
||||
+
|
||||
+#include <inttypes.h>
|
||||
+#include <stdbool.h>
|
||||
+#include <stdlib.h>
|
||||
+#include <systemd/sd-bus.h>
|
||||
+#include <systemd/sd-event.h>
|
||||
+#include <systemd/sd-login.h>
|
||||
+#include "hashmap.h"
|
||||
+#include "idev.h"
|
||||
+#include "idev-internal.h"
|
||||
+#include "login-shared.h"
|
||||
+#include "macro.h"
|
||||
+#include "set.h"
|
||||
+#include "util.h"
|
||||
+
|
||||
+static void element_open(idev_element *e);
|
||||
+static void element_close(idev_element *e);
|
||||
+
|
||||
+/*
|
||||
+ * Devices
|
||||
+ */
|
||||
+
|
||||
+idev_device *idev_find_device(idev_session *s, const char *name) {
|
||||
+ assert_return(s, NULL);
|
||||
+ assert_return(name, NULL);
|
||||
+
|
||||
+ return hashmap_get(s->device_map, name);
|
||||
+}
|
||||
+
|
||||
+int idev_device_add(idev_device *d, const char *name) {
|
||||
+ int r;
|
||||
+
|
||||
+ assert_return(d, -EINVAL);
|
||||
+ assert_return(d->vtable, -EINVAL);
|
||||
+ assert_return(d->session, -EINVAL);
|
||||
+ assert_return(name, -EINVAL);
|
||||
+
|
||||
+ d->name = strdup(name);
|
||||
+ if (!d->name)
|
||||
+ return -ENOMEM;
|
||||
+
|
||||
+ r = hashmap_put(d->session->device_map, d->name, d);
|
||||
+ if (r < 0)
|
||||
+ return r;
|
||||
+
|
||||
+ return 0;
|
||||
+}
|
||||
+
|
||||
+idev_device *idev_device_free(idev_device *d) {
|
||||
+ idev_device tmp;
|
||||
+
|
||||
+ if (!d)
|
||||
+ return NULL;
|
||||
+
|
||||
+ assert(!d->enabled);
|
||||
+ assert(!d->public);
|
||||
+ assert(!d->links);
|
||||
+ assert(d->vtable);
|
||||
+ assert(d->vtable->free);
|
||||
+
|
||||
+ if (d->name)
|
||||
+ hashmap_remove_value(d->session->device_map, d->name, d);
|
||||
+
|
||||
+ tmp = *d;
|
||||
+ d->vtable->free(d);
|
||||
+
|
||||
+ free(tmp.name);
|
||||
+
|
||||
+ return NULL;
|
||||
+}
|
||||
+
|
||||
+int idev_device_feed(idev_device *d, idev_data *data) {
|
||||
+ assert(d);
|
||||
+ assert(data);
|
||||
+ assert(data->type < IDEV_DATA_CNT);
|
||||
+
|
||||
+ if (d->vtable->feed)
|
||||
+ return d->vtable->feed(d, data);
|
||||
+ else
|
||||
+ return 0;
|
||||
+}
|
||||
+
|
||||
+void idev_device_feedback(idev_device *d, idev_data *data) {
|
||||
+ idev_link *l;
|
||||
+
|
||||
+ assert(d);
|
||||
+ assert(data);
|
||||
+ assert(data->type < IDEV_DATA_CNT);
|
||||
+
|
||||
+ LIST_FOREACH(links_by_device, l, d->links)
|
||||
+ idev_element_feedback(l->element, data);
|
||||
+}
|
||||
+
|
||||
+static void device_attach(idev_device *d, idev_link *l) {
|
||||
+ assert(d);
|
||||
+ assert(l);
|
||||
+
|
||||
+ if (d->vtable->attach)
|
||||
+ d->vtable->attach(d, l);
|
||||
+
|
||||
+ if (d->enabled)
|
||||
+ element_open(l->element);
|
||||
+}
|
||||
+
|
||||
+static void device_detach(idev_device *d, idev_link *l) {
|
||||
+ assert(d);
|
||||
+ assert(l);
|
||||
+
|
||||
+ if (d->enabled)
|
||||
+ element_close(l->element);
|
||||
+
|
||||
+ if (d->vtable->detach)
|
||||
+ d->vtable->detach(d, l);
|
||||
+}
|
||||
+
|
||||
+void idev_device_enable(idev_device *d) {
|
||||
+ idev_link *l;
|
||||
+
|
||||
+ assert(d);
|
||||
+
|
||||
+ if (!d->enabled) {
|
||||
+ d->enabled = true;
|
||||
+ LIST_FOREACH(links_by_device, l, d->links)
|
||||
+ element_open(l->element);
|
||||
+ }
|
||||
+}
|
||||
+
|
||||
+void idev_device_disable(idev_device *d) {
|
||||
+ idev_link *l;
|
||||
+
|
||||
+ assert(d);
|
||||
+
|
||||
+ if (d->enabled) {
|
||||
+ d->enabled = false;
|
||||
+ LIST_FOREACH(links_by_device, l, d->links)
|
||||
+ element_close(l->element);
|
||||
+ }
|
||||
+}
|
||||
+
|
||||
+/*
|
||||
+ * Elements
|
||||
+ */
|
||||
+
|
||||
+idev_element *idev_find_element(idev_session *s, const char *name) {
|
||||
+ assert_return(s, NULL);
|
||||
+ assert_return(name, NULL);
|
||||
+
|
||||
+ return hashmap_get(s->element_map, name);
|
||||
+}
|
||||
+
|
||||
+int idev_element_add(idev_element *e, const char *name) {
|
||||
+ int r;
|
||||
+
|
||||
+ assert_return(e, -EINVAL);
|
||||
+ assert_return(e->vtable, -EINVAL);
|
||||
+ assert_return(e->session, -EINVAL);
|
||||
+ assert_return(name, -EINVAL);
|
||||
+
|
||||
+ e->name = strdup(name);
|
||||
+ if (!e->name)
|
||||
+ return -ENOMEM;
|
||||
+
|
||||
+ r = hashmap_put(e->session->element_map, e->name, e);
|
||||
+ if (r < 0)
|
||||
+ return r;
|
||||
+
|
||||
+ return 0;
|
||||
+}
|
||||
+
|
||||
+idev_element *idev_element_free(idev_element *e) {
|
||||
+ idev_element tmp;
|
||||
+
|
||||
+ if (!e)
|
||||
+ return NULL;
|
||||
+
|
||||
+ assert(!e->enabled);
|
||||
+ assert(!e->links);
|
||||
+ assert(e->n_open == 0);
|
||||
+ assert(e->vtable);
|
||||
+ assert(e->vtable->free);
|
||||
+
|
||||
+ if (e->name)
|
||||
+ hashmap_remove_value(e->session->element_map, e->name, e);
|
||||
+
|
||||
+ tmp = *e;
|
||||
+ e->vtable->free(e);
|
||||
+
|
||||
+ free(tmp.name);
|
||||
+
|
||||
+ return NULL;
|
||||
+}
|
||||
+
|
||||
+int idev_element_feed(idev_element *e, idev_data *data) {
|
||||
+ int r, error = 0;
|
||||
+ idev_link *l;
|
||||
+
|
||||
+ assert(e);
|
||||
+ assert(data);
|
||||
+ assert(data->type < IDEV_DATA_CNT);
|
||||
+
|
||||
+ LIST_FOREACH(links_by_element, l, e->links) {
|
||||
+ r = idev_device_feed(l->device, data);
|
||||
+ if (r != 0)
|
||||
+ error = r;
|
||||
+ }
|
||||
+
|
||||
+ return error;
|
||||
+}
|
||||
+
|
||||
+void idev_element_feedback(idev_element *e, idev_data *data) {
|
||||
+ assert(e);
|
||||
+ assert(data);
|
||||
+ assert(data->type < IDEV_DATA_CNT);
|
||||
+
|
||||
+ if (e->vtable->feedback)
|
||||
+ e->vtable->feedback(e, data);
|
||||
+}
|
||||
+
|
||||
+static void element_open(idev_element *e) {
|
||||
+ assert(e);
|
||||
+
|
||||
+ if (e->n_open++ == 0 && e->vtable->open)
|
||||
+ e->vtable->open(e);
|
||||
+}
|
||||
+
|
||||
+static void element_close(idev_element *e) {
|
||||
+ assert(e);
|
||||
+ assert(e->n_open > 0);
|
||||
+
|
||||
+ if (--e->n_open == 0 && e->vtable->close)
|
||||
+ e->vtable->close(e);
|
||||
+}
|
||||
+
|
||||
+static void element_enable(idev_element *e) {
|
||||
+ assert(e);
|
||||
+
|
||||
+ if (!e->enabled) {
|
||||
+ e->enabled = true;
|
||||
+ if (e->vtable->enable)
|
||||
+ e->vtable->enable(e);
|
||||
+ }
|
||||
+}
|
||||
+
|
||||
+static void element_disable(idev_element *e) {
|
||||
+ assert(e);
|
||||
+
|
||||
+ if (e->enabled) {
|
||||
+ e->enabled = false;
|
||||
+ if (e->vtable->disable)
|
||||
+ e->vtable->disable(e);
|
||||
+ }
|
||||
+}
|
||||
+
|
||||
+/*
|
||||
+ * Sessions
|
||||
+ */
|
||||
+
|
||||
+static int session_raise(idev_session *s, idev_event *ev) {
|
||||
+ return s->event_fn(s, s->userdata, ev);
|
||||
+}
|
||||
+
|
||||
+static int session_raise_device_add(idev_session *s, idev_device *d) {
|
||||
+ idev_event event = {
|
||||
+ .type = IDEV_EVENT_DEVICE_ADD,
|
||||
+ .device_add = {
|
||||
+ .device = d,
|
||||
+ },
|
||||
+ };
|
||||
+
|
||||
+ return session_raise(s, &event);
|
||||
+}
|
||||
+
|
||||
+static int session_raise_device_remove(idev_session *s, idev_device *d) {
|
||||
+ idev_event event = {
|
||||
+ .type = IDEV_EVENT_DEVICE_REMOVE,
|
||||
+ .device_remove = {
|
||||
+ .device = d,
|
||||
+ },
|
||||
+ };
|
||||
+
|
||||
+ return session_raise(s, &event);
|
||||
+}
|
||||
+
|
||||
+int idev_session_raise_device_data(idev_session *s, idev_device *d, idev_data *data) {
|
||||
+ idev_event event = {
|
||||
+ .type = IDEV_EVENT_DEVICE_DATA,
|
||||
+ .device_data = {
|
||||
+ .device = d,
|
||||
+ .data = *data,
|
||||
+ },
|
||||
+ };
|
||||
+
|
||||
+ return session_raise(s, &event);
|
||||
+}
|
||||
+
|
||||
+static int session_add_device(idev_session *s, idev_device *d) {
|
||||
+ int r;
|
||||
+
|
||||
+ assert(s);
|
||||
+ assert(d);
|
||||
+
|
||||
+ log_debug("idev: %s: add device '%s'", s->name, d->name);
|
||||
+
|
||||
+ d->public = true;
|
||||
+ r = session_raise_device_add(s, d);
|
||||
+ if (r != 0) {
|
||||
+ d->public = false;
|
||||
+ goto error;
|
||||
+ }
|
||||
+
|
||||
+ return 0;
|
||||
+
|
||||
+error:
|
||||
+ if (r < 0)
|
||||
+ log_debug("idev: %s: error while adding device '%s': %s",
|
||||
+ s->name, d->name, strerror(-r));
|
||||
+ return r;
|
||||
+}
|
||||
+
|
||||
+static int session_remove_device(idev_session *s, idev_device *d) {
|
||||
+ int r, error = 0;
|
||||
+
|
||||
+ assert(s);
|
||||
+ assert(d);
|
||||
+
|
||||
+ log_debug("idev: %s: remove device '%s'", s->name, d->name);
|
||||
+
|
||||
+ d->public = false;
|
||||
+ r = session_raise_device_remove(s, d);
|
||||
+ if (r != 0)
|
||||
+ error = r;
|
||||
+
|
||||
+ idev_device_disable(d);
|
||||
+
|
||||
+ if (error < 0)
|
||||
+ log_debug("idev: %s: error while removing device '%s': %s",
|
||||
+ s->name, d->name, strerror(-error));
|
||||
+ idev_device_free(d);
|
||||
+ return error;
|
||||
+}
|
||||
+
|
||||
+static int session_add_element(idev_session *s, idev_element *e) {
|
||||
+ assert(s);
|
||||
+ assert(e);
|
||||
+
|
||||
+ log_debug("idev: %s: add element '%s'", s->name, e->name);
|
||||
+
|
||||
+ if (s->enabled)
|
||||
+ element_enable(e);
|
||||
+
|
||||
+ return 0;
|
||||
+}
|
||||
+
|
||||
+static int session_remove_element(idev_session *s, idev_element *e) {
|
||||
+ int r, error = 0;
|
||||
+ idev_device *d;
|
||||
+ idev_link *l;
|
||||
+
|
||||
+ assert(s);
|
||||
+ assert(e);
|
||||
+
|
||||
+ log_debug("idev: %s: remove element '%s'", s->name, e->name);
|
||||
+
|
||||
+ while ((l = e->links)) {
|
||||
+ d = l->device;
|
||||
+ LIST_REMOVE(links_by_device, d->links, l);
|
||||
+ LIST_REMOVE(links_by_element, e->links, l);
|
||||
+ device_detach(d, l);
|
||||
+
|
||||
+ if (!d->links) {
|
||||
+ r = session_remove_device(s, d);
|
||||
+ if (r != 0)
|
||||
+ error = r;
|
||||
+ }
|
||||
+
|
||||
+ l->device = NULL;
|
||||
+ l->element = NULL;
|
||||
+ free(l);
|
||||
+ }
|
||||
+
|
||||
+ element_disable(e);
|
||||
+
|
||||
+ if (error < 0)
|
||||
+ log_debug("idev: %s: error while removing element '%s': %s",
|
||||
+ s->name, e->name, strerror(-r));
|
||||
+ idev_element_free(e);
|
||||
+ return error;
|
||||
+}
|
||||
+
|
||||
+idev_session *idev_find_session(idev_context *c, const char *name) {
|
||||
+ assert_return(c, NULL);
|
||||
+ assert_return(name, NULL);
|
||||
+
|
||||
+ return hashmap_get(c->session_map, name);
|
||||
+}
|
||||
+
|
||||
+int idev_session_new(idev_session **out,
|
||||
+ idev_context *c,
|
||||
+ unsigned int flags,
|
||||
+ const char *name,
|
||||
+ idev_event_fn event_fn,
|
||||
+ void *userdata) {
|
||||
+ _cleanup_(idev_session_freep) idev_session *s = NULL;
|
||||
+ int r;
|
||||
+
|
||||
+ assert_return(out, -EINVAL);
|
||||
+ assert_return(c, -EINVAL);
|
||||
+ assert_return(name, -EINVAL);
|
||||
+ assert_return(event_fn, -EINVAL);
|
||||
+ assert_return((flags & IDEV_SESSION_CUSTOM) == !session_id_valid(name), -EINVAL);
|
||||
+ assert_return(!(flags & IDEV_SESSION_CUSTOM) || !(flags & IDEV_SESSION_MANAGED), -EINVAL);
|
||||
+ assert_return(!(flags & IDEV_SESSION_MANAGED) || c->sysbus, -EINVAL);
|
||||
+
|
||||
+ s = new0(idev_session, 1);
|
||||
+ if (!s)
|
||||
+ return -ENOMEM;
|
||||
+
|
||||
+ s->context = idev_context_ref(c);
|
||||
+ s->custom = flags & IDEV_SESSION_CUSTOM;
|
||||
+ s->managed = flags & IDEV_SESSION_MANAGED;
|
||||
+ s->event_fn = event_fn;
|
||||
+ s->userdata = userdata;
|
||||
+
|
||||
+ s->name = strdup(name);
|
||||
+ if (!s->name)
|
||||
+ return -ENOMEM;
|
||||
+
|
||||
+ if (s->managed) {
|
||||
+ r = sd_bus_path_encode("/org/freedesktop/login1/session", s->name, &s->path);
|
||||
+ if (r < 0)
|
||||
+ return r;
|
||||
+ }
|
||||
+
|
||||
+ s->element_map = hashmap_new(string_hash_func, string_compare_func);
|
||||
+ if (!s->element_map)
|
||||
+ return -ENOMEM;
|
||||
+
|
||||
+ s->device_map = hashmap_new(string_hash_func, string_compare_func);
|
||||
+ if (!s->device_map)
|
||||
+ return -ENOMEM;
|
||||
+
|
||||
+ r = hashmap_put(c->session_map, s->name, s);
|
||||
+ if (r < 0)
|
||||
+ return r;
|
||||
+
|
||||
+ *out = s;
|
||||
+ s = NULL;
|
||||
+ return 0;
|
||||
+}
|
||||
+
|
||||
+idev_session *idev_session_free(idev_session *s) {
|
||||
+ idev_element *e;
|
||||
+
|
||||
+ if (!s)
|
||||
+ return NULL;
|
||||
+
|
||||
+ while ((e = hashmap_first(s->element_map)))
|
||||
+ session_remove_element(s, e);
|
||||
+
|
||||
+ assert(hashmap_size(s->device_map) == 0);
|
||||
+
|
||||
+ if (s->name)
|
||||
+ hashmap_remove_value(s->context->session_map, s->name, s);
|
||||
+
|
||||
+ s->context = idev_context_unref(s->context);
|
||||
+ hashmap_free(s->device_map);
|
||||
+ hashmap_free(s->element_map);
|
||||
+ free(s->path);
|
||||
+ free(s->name);
|
||||
+ free(s);
|
||||
+
|
||||
+ return NULL;
|
||||
+}
|
||||
+
|
||||
+bool idev_session_is_enabled(idev_session *s) {
|
||||
+ return s && s->enabled;
|
||||
+}
|
||||
+
|
||||
+void idev_session_enable(idev_session *s) {
|
||||
+ idev_element *e;
|
||||
+ Iterator i;
|
||||
+
|
||||
+ assert(s);
|
||||
+
|
||||
+ if (!s->enabled) {
|
||||
+ s->enabled = true;
|
||||
+ HASHMAP_FOREACH(e, s->element_map, i)
|
||||
+ element_enable(e);
|
||||
+ }
|
||||
+}
|
||||
+
|
||||
+void idev_session_disable(idev_session *s) {
|
||||
+ idev_element *e;
|
||||
+ Iterator i;
|
||||
+
|
||||
+ assert(s);
|
||||
+
|
||||
+ if (s->enabled) {
|
||||
+ s->enabled = false;
|
||||
+ HASHMAP_FOREACH(e, s->element_map, i)
|
||||
+ element_disable(e);
|
||||
+ }
|
||||
+}
|
||||
+
|
||||
+/*
|
||||
+ * Contexts
|
||||
+ */
|
||||
+
|
||||
+int idev_context_new(idev_context **out, sd_event *event, sd_bus *sysbus) {
|
||||
+ _cleanup_(idev_context_unrefp) idev_context *c = NULL;
|
||||
+
|
||||
+ assert_return(out, -EINVAL);
|
||||
+ assert_return(event, -EINVAL);
|
||||
+
|
||||
+ c = new0(idev_context, 1);
|
||||
+ if (!c)
|
||||
+ return -ENOMEM;
|
||||
+
|
||||
+ c->ref = 1;
|
||||
+ c->event = sd_event_ref(event);
|
||||
+
|
||||
+ if (sysbus)
|
||||
+ c->sysbus = sd_bus_ref(sysbus);
|
||||
+
|
||||
+ c->session_map = hashmap_new(string_hash_func, string_compare_func);
|
||||
+ if (!c->session_map)
|
||||
+ return -ENOMEM;
|
||||
+
|
||||
+ c->data_map = hashmap_new(string_hash_func, string_compare_func);
|
||||
+ if (!c->data_map)
|
||||
+ return -ENOMEM;
|
||||
+
|
||||
+ *out = c;
|
||||
+ c = NULL;
|
||||
+ return 0;
|
||||
+}
|
||||
+
|
||||
+static void context_cleanup(idev_context *c) {
|
||||
+ assert(hashmap_size(c->data_map) == 0);
|
||||
+ assert(hashmap_size(c->session_map) == 0);
|
||||
+
|
||||
+ hashmap_free(c->data_map);
|
||||
+ hashmap_free(c->session_map);
|
||||
+ c->sysbus = sd_bus_unref(c->sysbus);
|
||||
+ c->event = sd_event_unref(c->event);
|
||||
+ free(c);
|
||||
+}
|
||||
+
|
||||
+idev_context *idev_context_ref(idev_context *c) {
|
||||
+ assert_return(c, NULL);
|
||||
+ assert_return(c->ref > 0, NULL);
|
||||
+
|
||||
+ ++c->ref;
|
||||
+ return c;
|
||||
+}
|
||||
+
|
||||
+idev_context *idev_context_unref(idev_context *c) {
|
||||
+ if (!c)
|
||||
+ return NULL;
|
||||
+
|
||||
+ assert_return(c->ref > 0, NULL);
|
||||
+
|
||||
+ if (--c->ref == 0)
|
||||
+ context_cleanup(c);
|
||||
+
|
||||
+ return NULL;
|
||||
+}
|
||||
diff --git a/src/libsystemd-terminal/idev.h b/src/libsystemd-terminal/idev.h
|
||||
new file mode 100644
|
||||
index 0000000000..6f618f37af
|
||||
--- /dev/null
|
||||
+++ b/src/libsystemd-terminal/idev.h
|
||||
@@ -0,0 +1,133 @@
|
||||
+/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
|
||||
+
|
||||
+/***
|
||||
+ This file is part of systemd.
|
||||
+
|
||||
+ Copyright (C) 2014 David Herrmann <dh.herrmann@gmail.com>
|
||||
+
|
||||
+ 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
|
||||
+ the Free Software Foundation; either version 2.1 of the License, or
|
||||
+ (at your option) any later version.
|
||||
+
|
||||
+ systemd is distributed in the hope that it will be useful, but
|
||||
+ WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
+ Lesser General Public License for more details.
|
||||
+
|
||||
+ You should have received a copy of the GNU Lesser General Public License
|
||||
+ along with systemd; If not, see <http://www.gnu.org/licenses/>.
|
||||
+***/
|
||||
+
|
||||
+/*
|
||||
+ * IDev
|
||||
+ */
|
||||
+
|
||||
+#pragma once
|
||||
+
|
||||
+#include <inttypes.h>
|
||||
+#include <stdbool.h>
|
||||
+#include <stdlib.h>
|
||||
+#include <systemd/sd-bus.h>
|
||||
+#include <systemd/sd-event.h>
|
||||
+#include "util.h"
|
||||
+
|
||||
+typedef struct idev_data idev_data;
|
||||
+
|
||||
+typedef struct idev_event idev_event;
|
||||
+typedef struct idev_device idev_device;
|
||||
+typedef struct idev_session idev_session;
|
||||
+typedef struct idev_context idev_context;
|
||||
+
|
||||
+/*
|
||||
+ * Types
|
||||
+ */
|
||||
+
|
||||
+enum {
|
||||
+ IDEV_ELEMENT_CNT
|
||||
+};
|
||||
+
|
||||
+enum {
|
||||
+ IDEV_DEVICE_CNT
|
||||
+};
|
||||
+
|
||||
+/*
|
||||
+ * Data Packets
|
||||
+ */
|
||||
+
|
||||
+enum {
|
||||
+ IDEV_DATA_RESYNC,
|
||||
+ IDEV_DATA_CNT
|
||||
+};
|
||||
+
|
||||
+struct idev_data {
|
||||
+ unsigned int type;
|
||||
+ bool resync : 1;
|
||||
+};
|
||||
+
|
||||
+/*
|
||||
+ * Events
|
||||
+ */
|
||||
+
|
||||
+enum {
|
||||
+ IDEV_EVENT_DEVICE_ADD,
|
||||
+ IDEV_EVENT_DEVICE_REMOVE,
|
||||
+ IDEV_EVENT_DEVICE_DATA,
|
||||
+ IDEV_EVENT_CNT
|
||||
+};
|
||||
+
|
||||
+struct idev_event {
|
||||
+ unsigned int type;
|
||||
+ union {
|
||||
+ struct {
|
||||
+ idev_device *device;
|
||||
+ } device_add, device_remove;
|
||||
+
|
||||
+ struct {
|
||||
+ idev_device *device;
|
||||
+ idev_data data;
|
||||
+ } device_data;
|
||||
+ };
|
||||
+};
|
||||
+
|
||||
+typedef int (*idev_event_fn) (idev_session *s, void *userdata, idev_event *ev);
|
||||
+
|
||||
+/*
|
||||
+ * Devices
|
||||
+ */
|
||||
+
|
||||
+void idev_device_enable(idev_device *d);
|
||||
+void idev_device_disable(idev_device *d);
|
||||
+
|
||||
+/*
|
||||
+ * Sessions
|
||||
+ */
|
||||
+
|
||||
+enum {
|
||||
+ IDEV_SESSION_CUSTOM = (1 << 0),
|
||||
+ IDEV_SESSION_MANAGED = (1 << 1),
|
||||
+};
|
||||
+
|
||||
+int idev_session_new(idev_session **out,
|
||||
+ idev_context *c,
|
||||
+ unsigned int flags,
|
||||
+ const char *name,
|
||||
+ idev_event_fn event_fn,
|
||||
+ void *userdata);
|
||||
+idev_session *idev_session_free(idev_session *s);
|
||||
+
|
||||
+DEFINE_TRIVIAL_CLEANUP_FUNC(idev_session*, idev_session_free);
|
||||
+
|
||||
+bool idev_session_is_enabled(idev_session *s);
|
||||
+void idev_session_enable(idev_session *s);
|
||||
+void idev_session_disable(idev_session *s);
|
||||
+
|
||||
+/*
|
||||
+ * Contexts
|
||||
+ */
|
||||
+
|
||||
+int idev_context_new(idev_context **out, sd_event *event, sd_bus *sysbus);
|
||||
+idev_context *idev_context_ref(idev_context *c);
|
||||
+idev_context *idev_context_unref(idev_context *c);
|
||||
+
|
||||
+DEFINE_TRIVIAL_CLEANUP_FUNC(idev_context*, idev_context_unref);
|
1189
0083-terminal-add-evdev-elements-to-idev.patch
Normal file
1189
0083-terminal-add-evdev-elements-to-idev.patch
Normal file
File diff suppressed because it is too large
Load Diff
1107
0084-terminal-add-xkb-based-keyboard-devices-to-idev.patch
Normal file
1107
0084-terminal-add-xkb-based-keyboard-devices-to-idev.patch
Normal file
File diff suppressed because it is too large
Load Diff
566
0085-terminal-add-systemd-evcat-input-debugging-tool.patch
Normal file
566
0085-terminal-add-systemd-evcat-input-debugging-tool.patch
Normal file
@ -0,0 +1,566 @@
|
||||
From 8e9371905c743cf997b2e8fa7fe3238f81f741fe Mon Sep 17 00:00:00 2001
|
||||
From: David Herrmann <dh.herrmann@gmail.com>
|
||||
Date: Wed, 27 Aug 2014 18:38:01 +0200
|
||||
Subject: [PATCH] terminal: add systemd-evcat input debugging tool
|
||||
|
||||
Like systemd-subterm, this new systemd-evcat tool should only be used to
|
||||
debug libsystemd-terminal. systemd-evcat attaches to the running session
|
||||
and pushes all evdev devices attached to the current session into an
|
||||
idev-session. All events of the created idev-devices are then printed to
|
||||
stdout for input-event debugging.
|
||||
---
|
||||
.gitignore | 1 +
|
||||
Makefile.am | 14 ++
|
||||
src/libsystemd-terminal/evcat.c | 499 ++++++++++++++++++++++++++++++++++++++++
|
||||
3 files changed, 514 insertions(+)
|
||||
create mode 100644 src/libsystemd-terminal/evcat.c
|
||||
|
||||
diff --git a/.gitignore b/.gitignore
|
||||
index 8aed0b9ba6..f8650870a3 100644
|
||||
--- a/.gitignore
|
||||
+++ b/.gitignore
|
||||
@@ -69,6 +69,7 @@
|
||||
/systemd-detect-virt
|
||||
/systemd-efi-boot-generator
|
||||
/systemd-escape
|
||||
+/systemd-evcat
|
||||
/systemd-firstboot
|
||||
/systemd-fsck
|
||||
/systemd-fstab-generator
|
||||
diff --git a/Makefile.am b/Makefile.am
|
||||
index 35a4c44a9f..e091febc1f 100644
|
||||
--- a/Makefile.am
|
||||
+++ b/Makefile.am
|
||||
@@ -2954,6 +2954,7 @@ noinst_LTLIBRARIES += \
|
||||
libsystemd-terminal.la
|
||||
|
||||
noinst_PROGRAMS += \
|
||||
+ systemd-evcat \
|
||||
systemd-subterm
|
||||
|
||||
unifontdatadir=$(datadir)/unifont
|
||||
@@ -2995,6 +2996,19 @@ libsystemd_terminal_la_LIBADD = \
|
||||
libsystemd-shared.la \
|
||||
$(TERMINAL_LIBS)
|
||||
|
||||
+systemd_evcat_CFLAGS = \
|
||||
+ $(AM_CFLAGS) \
|
||||
+ $(TERMINAL_CFLAGS)
|
||||
+
|
||||
+systemd_evcat_SOURCES = \
|
||||
+ src/libsystemd-terminal/evcat.c
|
||||
+
|
||||
+systemd_evcat_LDADD = \
|
||||
+ libsystemd-terminal.la \
|
||||
+ libsystemd-internal.la \
|
||||
+ libsystemd-shared.la \
|
||||
+ $(TERMINAL_LIBS)
|
||||
+
|
||||
systemd_subterm_SOURCES = \
|
||||
src/libsystemd-terminal/subterm.c
|
||||
|
||||
diff --git a/src/libsystemd-terminal/evcat.c b/src/libsystemd-terminal/evcat.c
|
||||
new file mode 100644
|
||||
index 0000000000..590a30d873
|
||||
--- /dev/null
|
||||
+++ b/src/libsystemd-terminal/evcat.c
|
||||
@@ -0,0 +1,499 @@
|
||||
+/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
|
||||
+
|
||||
+/***
|
||||
+ This file is part of systemd.
|
||||
+
|
||||
+ Copyright (C) 2014 David Herrmann <dh.herrmann@gmail.com>
|
||||
+
|
||||
+ 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
|
||||
+ the Free Software Foundation; either version 2.1 of the License, or
|
||||
+ (at your option) any later version.
|
||||
+
|
||||
+ systemd is distributed in the hope that it will be useful, but
|
||||
+ WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
+ Lesser General Public License for more details.
|
||||
+
|
||||
+ You should have received a copy of the GNU Lesser General Public License
|
||||
+ along with systemd; If not, see <http://www.gnu.org/licenses/>.
|
||||
+***/
|
||||
+
|
||||
+/*
|
||||
+ * Event Catenation
|
||||
+ * The evcat tool catenates input events of all requested devices and prints
|
||||
+ * them to standard-output. It's only meant for debugging of input-related
|
||||
+ * problems.
|
||||
+ */
|
||||
+
|
||||
+#include <assert.h>
|
||||
+#include <errno.h>
|
||||
+#include <getopt.h>
|
||||
+#include <libevdev/libevdev.h>
|
||||
+#include <linux/kd.h>
|
||||
+#include <linux/vt.h>
|
||||
+#include <stdarg.h>
|
||||
+#include <stdbool.h>
|
||||
+#include <stdio.h>
|
||||
+#include <stdlib.h>
|
||||
+#include <string.h>
|
||||
+#include <sys/ioctl.h>
|
||||
+#include <sys/stat.h>
|
||||
+#include <systemd/sd-bus.h>
|
||||
+#include <systemd/sd-event.h>
|
||||
+#include <systemd/sd-login.h>
|
||||
+#include <termios.h>
|
||||
+#include <unistd.h>
|
||||
+#include <xkbcommon/xkbcommon.h>
|
||||
+#include "build.h"
|
||||
+#include "bus-util.h"
|
||||
+#include "event-util.h"
|
||||
+#include "idev.h"
|
||||
+#include "macro.h"
|
||||
+#include "sysview.h"
|
||||
+#include "term-internal.h"
|
||||
+#include "util.h"
|
||||
+
|
||||
+typedef struct Evcat Evcat;
|
||||
+
|
||||
+struct Evcat {
|
||||
+ char *session;
|
||||
+ char *seat;
|
||||
+ sd_event *event;
|
||||
+ sd_bus *bus;
|
||||
+ sysview_context *sysview;
|
||||
+ idev_context *idev;
|
||||
+ idev_session *idev_session;
|
||||
+
|
||||
+ bool managed : 1;
|
||||
+};
|
||||
+
|
||||
+static Evcat *evcat_free(Evcat *e) {
|
||||
+ if (!e)
|
||||
+ return NULL;
|
||||
+
|
||||
+ e->idev_session = idev_session_free(e->idev_session);
|
||||
+ e->idev = idev_context_unref(e->idev);
|
||||
+ e->sysview = sysview_context_free(e->sysview);
|
||||
+ e->bus = sd_bus_unref(e->bus);
|
||||
+ e->event = sd_event_unref(e->event);
|
||||
+ free(e->seat);
|
||||
+ free(e->session);
|
||||
+ free(e);
|
||||
+
|
||||
+ tcflush(0, TCIOFLUSH);
|
||||
+
|
||||
+ return NULL;
|
||||
+}
|
||||
+
|
||||
+DEFINE_TRIVIAL_CLEANUP_FUNC(Evcat*, evcat_free);
|
||||
+
|
||||
+static bool is_managed(const char *session) {
|
||||
+ unsigned int vtnr;
|
||||
+ struct stat st;
|
||||
+ long mode;
|
||||
+ int r;
|
||||
+
|
||||
+ /* Using logind's Controller API is highly fragile if there is already
|
||||
+ * a session controller running. If it is registered as controller
|
||||
+ * itself, TakeControl will simply fail. But if its a legacy controller
|
||||
+ * that does not use logind's controller API, we must never register
|
||||
+ * our own controller. Otherwise, we really mess up the VT. Therefore,
|
||||
+ * only run in managed mode if there's no-one else. */
|
||||
+
|
||||
+ if (geteuid() == 0)
|
||||
+ return false;
|
||||
+
|
||||
+ if (!isatty(1))
|
||||
+ return false;
|
||||
+
|
||||
+ if (!session)
|
||||
+ return false;
|
||||
+
|
||||
+ r = sd_session_get_vt(session, &vtnr);
|
||||
+ if (r < 0 || vtnr < 1 || vtnr > 63)
|
||||
+ return false;
|
||||
+
|
||||
+ mode = 0;
|
||||
+ r = ioctl(1, KDGETMODE, &mode);
|
||||
+ if (r < 0 || mode != KD_TEXT)
|
||||
+ return false;
|
||||
+
|
||||
+ r = fstat(1, &st);
|
||||
+ if (r < 0 || minor(st.st_rdev) != vtnr)
|
||||
+ return false;
|
||||
+
|
||||
+ return true;
|
||||
+}
|
||||
+
|
||||
+static int evcat_new(Evcat **out) {
|
||||
+ _cleanup_(evcat_freep) Evcat *e = NULL;
|
||||
+ int r;
|
||||
+
|
||||
+ assert(out);
|
||||
+
|
||||
+ e = new0(Evcat, 1);
|
||||
+ if (!e)
|
||||
+ return log_oom();
|
||||
+
|
||||
+ r = sd_pid_get_session(getpid(), &e->session);
|
||||
+ if (r < 0) {
|
||||
+ log_error("Cannot retrieve logind session: %s", strerror(-r));
|
||||
+ return r;
|
||||
+ }
|
||||
+
|
||||
+ r = sd_session_get_seat(e->session, &e->seat);
|
||||
+ if (r < 0) {
|
||||
+ log_error("Cannot retrieve seat of logind session: %s", strerror(-r));
|
||||
+ return r;
|
||||
+ }
|
||||
+
|
||||
+ e->managed = is_managed(e->session);
|
||||
+
|
||||
+ r = sd_event_default(&e->event);
|
||||
+ if (r < 0)
|
||||
+ return r;
|
||||
+
|
||||
+ r = sd_bus_open_system(&e->bus);
|
||||
+ if (r < 0)
|
||||
+ return r;
|
||||
+
|
||||
+ r = sd_bus_attach_event(e->bus, e->event, SD_EVENT_PRIORITY_NORMAL);
|
||||
+ if (r < 0)
|
||||
+ return r;
|
||||
+
|
||||
+ r = sigprocmask_many(SIG_BLOCK, SIGTERM, SIGINT, -1);
|
||||
+ if (r < 0)
|
||||
+ return r;
|
||||
+
|
||||
+ r = sd_event_add_signal(e->event, NULL, SIGTERM, NULL, NULL);
|
||||
+ if (r < 0)
|
||||
+ return r;
|
||||
+
|
||||
+ r = sd_event_add_signal(e->event, NULL, SIGINT, NULL, NULL);
|
||||
+ if (r < 0)
|
||||
+ return r;
|
||||
+
|
||||
+ r = sysview_context_new(&e->sysview,
|
||||
+ SYSVIEW_CONTEXT_SCAN_LOGIND |
|
||||
+ SYSVIEW_CONTEXT_SCAN_EVDEV,
|
||||
+ e->event,
|
||||
+ e->bus,
|
||||
+ NULL);
|
||||
+ if (r < 0)
|
||||
+ return r;
|
||||
+
|
||||
+ r = idev_context_new(&e->idev, e->event, e->bus);
|
||||
+ if (r < 0)
|
||||
+ return r;
|
||||
+
|
||||
+ *out = e;
|
||||
+ e = NULL;
|
||||
+ return 0;
|
||||
+}
|
||||
+
|
||||
+static void kdata_print(idev_data *data) {
|
||||
+ idev_data_keyboard *k = &data->keyboard;
|
||||
+ char buf[128];
|
||||
+ uint32_t i, c;
|
||||
+ int cwidth;
|
||||
+
|
||||
+ /* Key-press state: UP/DOWN/REPEAT */
|
||||
+ printf(" %-6s", k->value == 0 ? "UP" :
|
||||
+ k->value == 1 ? "DOWN" :
|
||||
+ "REPEAT");
|
||||
+
|
||||
+ /* Keycode that triggered the event */
|
||||
+ printf(" | %5u", (unsigned)k->keycode);
|
||||
+
|
||||
+ /* Well-known name of the keycode */
|
||||
+ printf(" | %-20s", libevdev_event_code_get_name(EV_KEY, k->keycode) ? : "<unknown>");
|
||||
+
|
||||
+ /* Well-known modifiers */
|
||||
+ printf(" | %-5s", (k->mods & IDEV_KBDMOD_SHIFT) ? "SHIFT" : "");
|
||||
+ printf(" %-4s", (k->mods & IDEV_KBDMOD_CTRL) ? "CTRL" : "");
|
||||
+ printf(" %-3s", (k->mods & IDEV_KBDMOD_ALT) ? "ALT" : "");
|
||||
+ printf(" %-5s", (k->mods & IDEV_KBDMOD_LINUX) ? "LINUX" : "");
|
||||
+ printf(" %-4s", (k->mods & IDEV_KBDMOD_CAPS) ? "CAPS" : "");
|
||||
+
|
||||
+ /* Resolved symbols */
|
||||
+ printf(" |");
|
||||
+ for (i = 0; i < k->n_syms; ++i) {
|
||||
+ buf[0] = 0;
|
||||
+ xkb_keysym_get_name(k->keysyms[i], buf, sizeof(buf));
|
||||
+
|
||||
+ if (is_locale_utf8()) {
|
||||
+ c = k->codepoints[i];
|
||||
+ if (c < 0x110000 && c > 0x20 && (c < 0x7f || c > 0x9f)) {
|
||||
+ /* "%4lc" doesn't work well, so hard-code it */
|
||||
+ cwidth = mk_wcwidth(c);
|
||||
+ while (cwidth++ < 2)
|
||||
+ printf(" ");
|
||||
+
|
||||
+ printf(" '%lc':", (wchar_t)c);
|
||||
+ } else {
|
||||
+ printf(" ");
|
||||
+ }
|
||||
+ }
|
||||
+
|
||||
+ printf(" XKB_KEY_%-30s", buf);
|
||||
+ }
|
||||
+
|
||||
+ printf("\n");
|
||||
+}
|
||||
+
|
||||
+static bool kdata_is_exit(idev_data *data) {
|
||||
+ idev_data_keyboard *k = &data->keyboard;
|
||||
+
|
||||
+ if (k->value != 1)
|
||||
+ return false;
|
||||
+ if (k->n_syms != 1)
|
||||
+ return false;
|
||||
+
|
||||
+ return k->codepoints[0] == 'q';
|
||||
+}
|
||||
+
|
||||
+static int evcat_idev_fn(idev_session *session, void *userdata, idev_event *ev) {
|
||||
+ Evcat *e = userdata;
|
||||
+
|
||||
+ switch (ev->type) {
|
||||
+ case IDEV_EVENT_DEVICE_ADD:
|
||||
+ idev_device_enable(ev->device_add.device);
|
||||
+ break;
|
||||
+ case IDEV_EVENT_DEVICE_REMOVE:
|
||||
+ idev_device_disable(ev->device_remove.device);
|
||||
+ break;
|
||||
+ case IDEV_EVENT_DEVICE_DATA:
|
||||
+ switch (ev->device_data.data.type) {
|
||||
+ case IDEV_DATA_KEYBOARD:
|
||||
+ if (kdata_is_exit(&ev->device_data.data))
|
||||
+ sd_event_exit(e->event, 0);
|
||||
+ else
|
||||
+ kdata_print(&ev->device_data.data);
|
||||
+
|
||||
+ break;
|
||||
+ }
|
||||
+
|
||||
+ break;
|
||||
+ }
|
||||
+
|
||||
+ return 0;
|
||||
+}
|
||||
+
|
||||
+static int evcat_sysview_fn(sysview_context *c, void *userdata, sysview_event *ev) {
|
||||
+ unsigned int flags, type;
|
||||
+ Evcat *e = userdata;
|
||||
+ sysview_device *d;
|
||||
+ const char *name;
|
||||
+ int r;
|
||||
+
|
||||
+ switch (ev->type) {
|
||||
+ case SYSVIEW_EVENT_SESSION_FILTER:
|
||||
+ if (streq_ptr(e->session, ev->session_filter.id))
|
||||
+ return 1;
|
||||
+
|
||||
+ break;
|
||||
+ case SYSVIEW_EVENT_SESSION_ADD:
|
||||
+ assert(!e->idev_session);
|
||||
+
|
||||
+ name = sysview_session_get_name(ev->session_add.session);
|
||||
+ flags = 0;
|
||||
+
|
||||
+ if (e->managed)
|
||||
+ flags |= IDEV_SESSION_MANAGED;
|
||||
+
|
||||
+ r = idev_session_new(&e->idev_session,
|
||||
+ e->idev,
|
||||
+ flags,
|
||||
+ name,
|
||||
+ evcat_idev_fn,
|
||||
+ e);
|
||||
+ if (r < 0) {
|
||||
+ log_error("Cannot create idev session: %s", strerror(-r));
|
||||
+ return r;
|
||||
+ }
|
||||
+
|
||||
+ idev_session_enable(e->idev_session);
|
||||
+
|
||||
+ if (e->managed) {
|
||||
+ r = sysview_session_take_control(ev->session_add.session);
|
||||
+ if (r < 0) {
|
||||
+ log_error("Cannot request session control: %s", strerror(-r));
|
||||
+ return r;
|
||||
+ }
|
||||
+ }
|
||||
+
|
||||
+ break;
|
||||
+ case SYSVIEW_EVENT_SESSION_REMOVE:
|
||||
+ idev_session_disable(e->idev_session);
|
||||
+ e->idev_session = idev_session_free(e->idev_session);
|
||||
+ sd_event_exit(e->event, 0);
|
||||
+ break;
|
||||
+ case SYSVIEW_EVENT_SESSION_ATTACH:
|
||||
+ d = ev->session_attach.device;
|
||||
+ type = sysview_device_get_type(d);
|
||||
+ if (type == SYSVIEW_DEVICE_EVDEV) {
|
||||
+ r = idev_session_add_evdev(e->idev_session, sysview_device_get_ud(d));
|
||||
+ if (r < 0) {
|
||||
+ log_error("Cannot add evdev device to idev: %s", strerror(-r));
|
||||
+ return r;
|
||||
+ }
|
||||
+ }
|
||||
+
|
||||
+ break;
|
||||
+ case SYSVIEW_EVENT_SESSION_DETACH:
|
||||
+ d = ev->session_detach.device;
|
||||
+ type = sysview_device_get_type(d);
|
||||
+ if (type == SYSVIEW_DEVICE_EVDEV) {
|
||||
+ r = idev_session_remove_evdev(e->idev_session, sysview_device_get_ud(d));
|
||||
+ if (r < 0) {
|
||||
+ log_error("Cannot remove evdev device from idev: %s", strerror(-r));
|
||||
+ return r;
|
||||
+ }
|
||||
+ }
|
||||
+
|
||||
+ break;
|
||||
+ case SYSVIEW_EVENT_SESSION_CONTROL:
|
||||
+ r = ev->session_control.error;
|
||||
+ if (r < 0) {
|
||||
+ log_error("Cannot acquire session control: %s", strerror(-r));
|
||||
+ return r;
|
||||
+ }
|
||||
+
|
||||
+ r = ioctl(1, KDSKBMODE, K_UNICODE);
|
||||
+ if (r < 0) {
|
||||
+ log_error("Cannot set K_UNICODE on stdout: %m");
|
||||
+ return -errno;
|
||||
+ }
|
||||
+
|
||||
+ r = ioctl(1, KDSETMODE, KD_TEXT);
|
||||
+ if (r < 0) {
|
||||
+ log_error("Cannot set KD_TEXT on stdout: %m");
|
||||
+ return -errno;
|
||||
+ }
|
||||
+
|
||||
+ printf("\n");
|
||||
+
|
||||
+ break;
|
||||
+ }
|
||||
+
|
||||
+ return 0;
|
||||
+}
|
||||
+
|
||||
+static int evcat_run(Evcat *e) {
|
||||
+ struct termios in_attr, saved_attr;
|
||||
+ int r;
|
||||
+
|
||||
+ assert(e);
|
||||
+
|
||||
+ if (!e->managed && geteuid() > 0)
|
||||
+ log_warning("You run in unmanaged mode without being root. This is likely to produce no output..");
|
||||
+
|
||||
+ printf("evcat - Read and catenate events from selected input devices\n"
|
||||
+ " Running on seat '%s' in user-session '%s'\n"
|
||||
+ " Exit by pressing ^C or 'q'\n\n",
|
||||
+ e->seat ? : "seat0", e->session ? : "<none>");
|
||||
+
|
||||
+ r = sysview_context_start(e->sysview, evcat_sysview_fn, e);
|
||||
+ if (r < 0)
|
||||
+ goto out;
|
||||
+
|
||||
+ r = tcgetattr(0, &in_attr);
|
||||
+ if (r < 0) {
|
||||
+ r = -errno;
|
||||
+ goto out;
|
||||
+ }
|
||||
+
|
||||
+ saved_attr = in_attr;
|
||||
+ in_attr.c_lflag &= ~ECHO;
|
||||
+
|
||||
+ r = tcsetattr(0, TCSANOW, &in_attr);
|
||||
+ if (r < 0) {
|
||||
+ r = -errno;
|
||||
+ goto out;
|
||||
+ }
|
||||
+
|
||||
+ r = sd_event_loop(e->event);
|
||||
+ tcsetattr(0, TCSANOW, &saved_attr);
|
||||
+ printf("exiting..\n");
|
||||
+
|
||||
+out:
|
||||
+ sysview_context_stop(e->sysview);
|
||||
+ return r;
|
||||
+}
|
||||
+
|
||||
+static int help(void) {
|
||||
+ printf("%s [OPTIONS...]\n\n"
|
||||
+ "Read and catenate events from selected input devices.\n\n"
|
||||
+ " -h --help Show this help\n"
|
||||
+ " --version Show package version\n"
|
||||
+ , program_invocation_short_name);
|
||||
+
|
||||
+ return 0;
|
||||
+}
|
||||
+
|
||||
+static int parse_argv(int argc, char *argv[]) {
|
||||
+ enum {
|
||||
+ ARG_VERSION = 0x100,
|
||||
+ };
|
||||
+ static const struct option options[] = {
|
||||
+ { "help", no_argument, NULL, 'h' },
|
||||
+ { "version", no_argument, NULL, ARG_VERSION },
|
||||
+ {},
|
||||
+ };
|
||||
+ int c;
|
||||
+
|
||||
+ assert(argc >= 0);
|
||||
+ assert(argv);
|
||||
+
|
||||
+ while ((c = getopt_long(argc, argv, "h", options, NULL)) >= 0)
|
||||
+ switch (c) {
|
||||
+ case 'h':
|
||||
+ help();
|
||||
+ return 0;
|
||||
+
|
||||
+ case ARG_VERSION:
|
||||
+ puts(PACKAGE_STRING);
|
||||
+ puts(SYSTEMD_FEATURES);
|
||||
+ return 0;
|
||||
+
|
||||
+ case '?':
|
||||
+ return -EINVAL;
|
||||
+
|
||||
+ default:
|
||||
+ assert_not_reached("Unhandled option");
|
||||
+ }
|
||||
+
|
||||
+ if (argc > optind) {
|
||||
+ log_error("Too many arguments");
|
||||
+ return -EINVAL;
|
||||
+ }
|
||||
+
|
||||
+ return 1;
|
||||
+}
|
||||
+
|
||||
+int main(int argc, char *argv[]) {
|
||||
+ _cleanup_(evcat_freep) Evcat *e = NULL;
|
||||
+ int r;
|
||||
+
|
||||
+ log_set_target(LOG_TARGET_AUTO);
|
||||
+ log_parse_environment();
|
||||
+ log_open();
|
||||
+
|
||||
+ setlocale(LC_ALL, "");
|
||||
+ if (!is_locale_utf8())
|
||||
+ log_warning("Locale is not set to UTF-8. Codepoints will not be printed!");
|
||||
+
|
||||
+ r = parse_argv(argc, argv);
|
||||
+ if (r <= 0)
|
||||
+ goto finish;
|
||||
+
|
||||
+ r = evcat_new(&e);
|
||||
+ if (r < 0)
|
||||
+ goto finish;
|
||||
+
|
||||
+ r = evcat_run(e);
|
||||
+
|
||||
+finish:
|
||||
+ return r < 0 ? EXIT_FAILURE : EXIT_SUCCESS;
|
||||
+}
|
93
0086-man-add-sample-glib-sd-event-integration.patch
Normal file
93
0086-man-add-sample-glib-sd-event-integration.patch
Normal file
@ -0,0 +1,93 @@
|
||||
From c609cb9898dc8dec5dcb0b1d111b3f6b6a5e09d4 Mon Sep 17 00:00:00 2001
|
||||
From: Tom Gundersen <teg@jklm.no>
|
||||
Date: Wed, 27 Aug 2014 19:04:29 +0200
|
||||
Subject: [PATCH] man: add sample glib/sd-event integration
|
||||
|
||||
This should be moved to man pages, but for now the C code is included directly.
|
||||
|
||||
Suggested by Zbyszek.
|
||||
---
|
||||
man/glib-event-glue.c | 74 +++++++++++++++++++++++++++++++++++++++++++++++++++
|
||||
1 file changed, 74 insertions(+)
|
||||
create mode 100644 man/glib-event-glue.c
|
||||
|
||||
diff --git a/man/glib-event-glue.c b/man/glib-event-glue.c
|
||||
new file mode 100644
|
||||
index 0000000000..95aaea1e63
|
||||
--- /dev/null
|
||||
+++ b/man/glib-event-glue.c
|
||||
@@ -0,0 +1,74 @@
|
||||
+/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
|
||||
+
|
||||
+/***
|
||||
+ Copyright 2014 Tom Gundersen
|
||||
+
|
||||
+ Permission is hereby granted, free of charge, to any person
|
||||
+ obtaining a copy of this software and associated documentation files
|
||||
+ (the "Software"), to deal in the Software without restriction,
|
||||
+ including without limitation the rights to use, copy, modify, merge,
|
||||
+ publish, distribute, sublicense, and/or sell copies of the Software,
|
||||
+ and to permit persons to whom the Software is furnished to do so,
|
||||
+ subject to the following conditions:
|
||||
+
|
||||
+ The above copyright notice and this permission notice shall be
|
||||
+ included in all copies or substantial portions of the Software.
|
||||
+
|
||||
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
||||
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
||||
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
||||
+ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
|
||||
+ BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
|
||||
+ ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
|
||||
+ CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
+ SOFTWARE.
|
||||
+***/
|
||||
+
|
||||
+#include <assert.h>
|
||||
+#include <errno.h>
|
||||
+#include <stdlib.h>
|
||||
+
|
||||
+#include "glib-event-glue.h"
|
||||
+
|
||||
+typedef struct SDEventSource {
|
||||
+ GSource source;
|
||||
+ GPollFD pollfd;
|
||||
+ sd_event *event;
|
||||
+} SDEventSource;
|
||||
+
|
||||
+static gboolean event_prepare(GSource *source, gint *timeout_) {
|
||||
+ return sd_event_prepare(((SDEventSource *)source)->event) > 0;
|
||||
+}
|
||||
+
|
||||
+static gboolean event_check(GSource *source) {
|
||||
+ return sd_event_wait(((SDEventSource *)source)->event, 0) > 0;
|
||||
+}
|
||||
+
|
||||
+static gboolean event_dispatch(GSource *source, GSourceFunc callback, gpointer user_data) {
|
||||
+ return sd_event_dispatch(((SDEventSource *)source)->event) > 0;
|
||||
+}
|
||||
+
|
||||
+static void event_finalize(GSource *source) {
|
||||
+ sd_event_unref(((SDEventSource *)source)->event);
|
||||
+}
|
||||
+
|
||||
+static GSourceFuncs event_funcs = {
|
||||
+ .prepare = event_prepare,
|
||||
+ .check = event_check,
|
||||
+ .dispatch = event_dispatch,
|
||||
+ .finalize = event_finalize,
|
||||
+};
|
||||
+
|
||||
+GSource *g_sd_event_create_source(sd_event *event) {
|
||||
+ SDEventSource *source;
|
||||
+
|
||||
+ source = (SDEventSource *)g_source_new(&event_funcs, sizeof(SDEventSource));
|
||||
+
|
||||
+ source->event = sd_event_ref(event);
|
||||
+ source->pollfd.fd = sd_event_get_fd(event);
|
||||
+ source->pollfd.events = G_IO_IN | G_IO_HUP | G_IO_ERR;
|
||||
+
|
||||
+ g_source_add_poll((GSource *)source, &source->pollfd);
|
||||
+
|
||||
+ return (GSource *)source;
|
||||
+}
|
@ -0,0 +1,91 @@
|
||||
From 8a7c93d858c342744adf481565d8bb03b9713dcf Mon Sep 17 00:00:00 2001
|
||||
From: Lennart Poettering <lennart@poettering.net>
|
||||
Date: Wed, 27 Aug 2014 21:42:20 +0200
|
||||
Subject: [PATCH] util: fix minimal race where we might miss SIGTERMs when
|
||||
forking off an agent
|
||||
|
||||
Before forking, block all signals, and unblock them afterwards. This way
|
||||
the child will have them blocked, and we won't lose them.
|
||||
---
|
||||
src/shared/util.c | 35 +++++++++++++++++++++++------------
|
||||
1 file changed, 23 insertions(+), 12 deletions(-)
|
||||
|
||||
diff --git a/src/shared/util.c b/src/shared/util.c
|
||||
index 9e4ff85ffb..cf9d487b82 100644
|
||||
--- a/src/shared/util.c
|
||||
+++ b/src/shared/util.c
|
||||
@@ -5102,9 +5102,9 @@ int fd_inc_rcvbuf(int fd, size_t n) {
|
||||
}
|
||||
|
||||
int fork_agent(pid_t *pid, const int except[], unsigned n_except, const char *path, ...) {
|
||||
- pid_t parent_pid, agent_pid;
|
||||
- int fd;
|
||||
bool stdout_is_tty, stderr_is_tty;
|
||||
+ pid_t parent_pid, agent_pid;
|
||||
+ sigset_t ss, saved_ss;
|
||||
unsigned n, i;
|
||||
va_list ap;
|
||||
char **l;
|
||||
@@ -5112,16 +5112,25 @@ int fork_agent(pid_t *pid, const int except[], unsigned n_except, const char *pa
|
||||
assert(pid);
|
||||
assert(path);
|
||||
|
||||
- parent_pid = getpid();
|
||||
-
|
||||
/* Spawns a temporary TTY agent, making sure it goes away when
|
||||
* we go away */
|
||||
|
||||
+ parent_pid = getpid();
|
||||
+
|
||||
+ /* First we temporarily block all signals, so that the new
|
||||
+ * child has them blocked initially. This way, we can be sure
|
||||
+ * that SIGTERMs are not lost we might send to the agent. */
|
||||
+ assert_se(sigfillset(&ss) >= 0);
|
||||
+ assert_se(sigprocmask(SIG_SETMASK, &ss, &saved_ss) >= 0);
|
||||
+
|
||||
agent_pid = fork();
|
||||
- if (agent_pid < 0)
|
||||
+ if (agent_pid < 0) {
|
||||
+ assert_se(sigprocmask(SIG_SETMASK, &saved_ss, NULL) >= 0);
|
||||
return -errno;
|
||||
+ }
|
||||
|
||||
if (agent_pid != 0) {
|
||||
+ assert_se(sigprocmask(SIG_SETMASK, &saved_ss, NULL) >= 0);
|
||||
*pid = agent_pid;
|
||||
return 0;
|
||||
}
|
||||
@@ -5132,24 +5141,26 @@ int fork_agent(pid_t *pid, const int except[], unsigned n_except, const char *pa
|
||||
if (prctl(PR_SET_PDEATHSIG, SIGTERM) < 0)
|
||||
_exit(EXIT_FAILURE);
|
||||
|
||||
+ /* Make sure we actually can kill the agent, if we need to, in
|
||||
+ * case somebody invoked us from a shell script that trapped
|
||||
+ * SIGTERM or so... */
|
||||
+ reset_all_signal_handlers();
|
||||
+ reset_signal_mask();
|
||||
+
|
||||
/* Check whether our parent died before we were able
|
||||
- * to set the death signal */
|
||||
+ * to set the death signal and unblock the signals */
|
||||
if (getppid() != parent_pid)
|
||||
_exit(EXIT_SUCCESS);
|
||||
|
||||
/* Don't leak fds to the agent */
|
||||
close_all_fds(except, n_except);
|
||||
|
||||
- /* Make sure we actually can kill the agent, if we need to, in
|
||||
- * case somebody invoked us from a shell script that trapped
|
||||
- * SIGTERM or so... */
|
||||
- reset_all_signal_handlers();
|
||||
- reset_signal_mask();
|
||||
-
|
||||
stdout_is_tty = isatty(STDOUT_FILENO);
|
||||
stderr_is_tty = isatty(STDERR_FILENO);
|
||||
|
||||
if (!stdout_is_tty || !stderr_is_tty) {
|
||||
+ int fd;
|
||||
+
|
||||
/* Detach from stdout/stderr. and reopen
|
||||
* /dev/tty for them. This is important to
|
||||
* ensure that when systemctl is started via
|
22
0088-update-TODO.patch
Normal file
22
0088-update-TODO.patch
Normal file
@ -0,0 +1,22 @@
|
||||
From eff3f4f9e92b56d9dfb90d5094e48cc743c776cc Mon Sep 17 00:00:00 2001
|
||||
From: Lennart Poettering <lennart@poettering.net>
|
||||
Date: Wed, 27 Aug 2014 21:43:33 +0200
|
||||
Subject: [PATCH] update TODO
|
||||
|
||||
---
|
||||
TODO | 2 ++
|
||||
1 file changed, 2 insertions(+)
|
||||
|
||||
diff --git a/TODO b/TODO
|
||||
index a00c13dab2..bc81a70eb1 100644
|
||||
--- a/TODO
|
||||
+++ b/TODO
|
||||
@@ -24,6 +24,8 @@ External:
|
||||
|
||||
Features:
|
||||
|
||||
+* nspawn --network-interface= doesn't work...
|
||||
+
|
||||
* dbus: add new message hdr field for allowing interactive auth, write spec for it. update dbus spec to mandate that unknown flags *must* be ignored...
|
||||
|
||||
* maybe introduce AssertXYZ= similar to ConditionXYZ= that causes a unit to fail (instead of skipping it) if some condition is not true...
|
21
0089-terminal-remove-unused-variable.patch
Normal file
21
0089-terminal-remove-unused-variable.patch
Normal file
@ -0,0 +1,21 @@
|
||||
From 00b333bb1039809a42ba4c7f25ba85f68766477d Mon Sep 17 00:00:00 2001
|
||||
From: Thomas Hindoe Paaboel Andersen <phomes@gmail.com>
|
||||
Date: Wed, 27 Aug 2014 23:23:10 +0200
|
||||
Subject: [PATCH] terminal: remove unused variable
|
||||
|
||||
---
|
||||
src/libsystemd-terminal/idev-keyboard.c | 1 -
|
||||
1 file changed, 1 deletion(-)
|
||||
|
||||
diff --git a/src/libsystemd-terminal/idev-keyboard.c b/src/libsystemd-terminal/idev-keyboard.c
|
||||
index 647aade932..7ab4db2cf7 100644
|
||||
--- a/src/libsystemd-terminal/idev-keyboard.c
|
||||
+++ b/src/libsystemd-terminal/idev-keyboard.c
|
||||
@@ -312,7 +312,6 @@ static int kbdctx_locale_props_changed_fn(sd_bus *bus,
|
||||
sd_bus_message *signal,
|
||||
void *userdata,
|
||||
sd_bus_error *ret_err) {
|
||||
- _cleanup_bus_message_unref_ sd_bus_message *m = NULL;
|
||||
kbdctx *kc = userdata;
|
||||
int r;
|
||||
|
@ -0,0 +1,36 @@
|
||||
From 57cd09acf2c63a414aa2131c00a2b3f600eb0133 Mon Sep 17 00:00:00 2001
|
||||
From: =?UTF-8?q?Zbigniew=20J=C4=99drzejewski-Szmek?= <zbyszek@in.waw.pl>
|
||||
Date: Sat, 23 Aug 2014 22:35:03 -0400
|
||||
Subject: [PATCH] sd-journal: properly convert object->size on big endian
|
||||
|
||||
mmap code crashes when attempting to map an object of zero size.
|
||||
|
||||
https://bugs.debian.org/cgi-bin/bugreport.cgi?bug=758392
|
||||
https://bugs.freedesktop.org/show_bug.cgi?id=82894
|
||||
---
|
||||
src/journal/journal-file.h | 7 ++++---
|
||||
1 file changed, 4 insertions(+), 3 deletions(-)
|
||||
|
||||
diff --git a/src/journal/journal-file.h b/src/journal/journal-file.h
|
||||
index 3d416820b0..da2ef3b795 100644
|
||||
--- a/src/journal/journal-file.h
|
||||
+++ b/src/journal/journal-file.h
|
||||
@@ -214,14 +214,15 @@ static unsigned type_to_context(int type) {
|
||||
|
||||
static inline int journal_file_object_keep(JournalFile *f, Object *o, uint64_t offset) {
|
||||
unsigned context = type_to_context(o->object.type);
|
||||
+ uint64_t s = le64toh(o->object.size);
|
||||
|
||||
return mmap_cache_get(f->mmap, f->fd, f->prot, context, true,
|
||||
- offset, o->object.size, &f->last_stat, NULL);
|
||||
+ offset, s, &f->last_stat, NULL);
|
||||
}
|
||||
|
||||
static inline int journal_file_object_release(JournalFile *f, Object *o, uint64_t offset) {
|
||||
unsigned context = type_to_context(o->object.type);
|
||||
+ uint64_t s = le64toh(o->object.size);
|
||||
|
||||
- return mmap_cache_release(f->mmap, f->fd, f->prot, context,
|
||||
- offset, o->object.size);
|
||||
+ return mmap_cache_release(f->mmap, f->fd, f->prot, context, offset, s);
|
||||
}
|
@ -0,0 +1,51 @@
|
||||
From 0f99f74a14ef193c1ebde687c5cc76e1d67b85ef Mon Sep 17 00:00:00 2001
|
||||
From: =?UTF-8?q?Zbigniew=20J=C4=99drzejewski-Szmek?= <zbyszek@in.waw.pl>
|
||||
Date: Tue, 26 Aug 2014 23:54:31 -0400
|
||||
Subject: [PATCH] sd-journal: verify that object start with the field name
|
||||
|
||||
If the journal is corrupted, we might return an object that does
|
||||
not start with the expected field name and/or is shorter than it
|
||||
should.
|
||||
---
|
||||
src/journal/journal-file.c | 1 -
|
||||
src/journal/sd-journal.c | 15 +++++++++++++++
|
||||
2 files changed, 15 insertions(+), 1 deletion(-)
|
||||
|
||||
diff --git a/src/journal/journal-file.c b/src/journal/journal-file.c
|
||||
index 986e94de39..7286e14ddb 100644
|
||||
--- a/src/journal/journal-file.c
|
||||
+++ b/src/journal/journal-file.c
|
||||
@@ -425,7 +425,6 @@ int journal_file_move_to_object(JournalFile *f, int type, uint64_t offset, Objec
|
||||
if (!VALID64(offset))
|
||||
return -EFAULT;
|
||||
|
||||
-
|
||||
r = journal_file_move_to(f, type_to_context(type), false, offset, sizeof(ObjectHeader), &t);
|
||||
if (r < 0)
|
||||
return r;
|
||||
diff --git a/src/journal/sd-journal.c b/src/journal/sd-journal.c
|
||||
index 80ff8fef57..693707cb34 100644
|
||||
--- a/src/journal/sd-journal.c
|
||||
+++ b/src/journal/sd-journal.c
|
||||
@@ -2571,6 +2571,21 @@ _public_ int sd_journal_enumerate_unique(sd_journal *j, const void **data, size_
|
||||
if (r < 0)
|
||||
return r;
|
||||
|
||||
+ /* Check if we have at least the field name and "=". */
|
||||
+ if (ol <= k) {
|
||||
+ log_debug("%s:offset " OFSfmt ": object has size %zu, expected at least %zu",
|
||||
+ j->unique_file->path, j->unique_offset,
|
||||
+ ol, k + 1);
|
||||
+ return -EBADMSG;
|
||||
+ }
|
||||
+
|
||||
+ if (memcmp(odata, j->unique_field, k) || ((const char*) odata)[k] != '=') {
|
||||
+ log_debug("%s:offset " OFSfmt ": object does not start with \"%s=\"",
|
||||
+ j->unique_file->path, j->unique_offset,
|
||||
+ j->unique_field);
|
||||
+ return -EBADMSG;
|
||||
+ }
|
||||
+
|
||||
/* OK, now let's see if we already returned this data
|
||||
* object by checking if it exists in the earlier
|
||||
* traversed files. */
|
@ -0,0 +1,26 @@
|
||||
From 371ad55d460559b4262e25d0f9b64dc37c3f7565 Mon Sep 17 00:00:00 2001
|
||||
From: David Herrmann <dh.herrmann@gmail.com>
|
||||
Date: Thu, 28 Aug 2014 11:01:31 +0200
|
||||
Subject: [PATCH] terminal: sysview: don't return uninitialized error codes
|
||||
|
||||
In case 'scan_evdev' and 'scan_drm' are both false, we never set 'r' to
|
||||
anyhting, thus return an uninitialized error code. Fix this by always
|
||||
returning 0 as we catch negative codes earlier, anyway. Thanks to Thomas
|
||||
H.P. Anderson for the report.
|
||||
---
|
||||
src/libsystemd-terminal/sysview.c | 2 +-
|
||||
1 file changed, 1 insertion(+), 1 deletion(-)
|
||||
|
||||
diff --git a/src/libsystemd-terminal/sysview.c b/src/libsystemd-terminal/sysview.c
|
||||
index d885cb4d4a..f5363dedf4 100644
|
||||
--- a/src/libsystemd-terminal/sysview.c
|
||||
+++ b/src/libsystemd-terminal/sysview.c
|
||||
@@ -821,7 +821,7 @@ static int context_ud_prepare_monitor(sysview_context *c, struct udev_monitor *m
|
||||
return r;
|
||||
}
|
||||
|
||||
- return r;
|
||||
+ return 0;
|
||||
}
|
||||
|
||||
static int context_ud_prepare_scan(sysview_context *c, struct udev_enumerate *e) {
|
37
0093-nspawn-fix-network-interface.patch
Normal file
37
0093-nspawn-fix-network-interface.patch
Normal file
@ -0,0 +1,37 @@
|
||||
From 3125b3ef5db70d45882c7d6f617705802c5f939e Mon Sep 17 00:00:00 2001
|
||||
From: Tom Gundersen <teg@jklm.no>
|
||||
Date: Thu, 28 Aug 2014 12:15:51 +0200
|
||||
Subject: [PATCH] nspawn: fix --network-interface
|
||||
|
||||
Use SETLINK when modifying an existing link.
|
||||
---
|
||||
TODO | 2 --
|
||||
src/nspawn/nspawn.c | 2 +-
|
||||
2 files changed, 1 insertion(+), 3 deletions(-)
|
||||
|
||||
diff --git a/TODO b/TODO
|
||||
index bc81a70eb1..a00c13dab2 100644
|
||||
--- a/TODO
|
||||
+++ b/TODO
|
||||
@@ -24,8 +24,6 @@ External:
|
||||
|
||||
Features:
|
||||
|
||||
-* nspawn --network-interface= doesn't work...
|
||||
-
|
||||
* dbus: add new message hdr field for allowing interactive auth, write spec for it. update dbus spec to mandate that unknown flags *must* be ignored...
|
||||
|
||||
* maybe introduce AssertXYZ= similar to ConditionXYZ= that causes a unit to fail (instead of skipping it) if some condition is not true...
|
||||
diff --git a/src/nspawn/nspawn.c b/src/nspawn/nspawn.c
|
||||
index 56d9cc68c6..5af89c9b32 100644
|
||||
--- a/src/nspawn/nspawn.c
|
||||
+++ b/src/nspawn/nspawn.c
|
||||
@@ -1886,7 +1886,7 @@ static int move_network_interfaces(pid_t pid) {
|
||||
if (ifi < 0)
|
||||
return ifi;
|
||||
|
||||
- r = sd_rtnl_message_new_link(rtnl, &m, RTM_NEWLINK, ifi);
|
||||
+ r = sd_rtnl_message_new_link(rtnl, &m, RTM_SETLINK, ifi);
|
||||
if (r < 0) {
|
||||
log_error("Failed to allocate netlink message: %s", strerror(-r));
|
||||
return r;
|
23
0094-terminal-free-xkb-state-on-keyboard-destruction.patch
Normal file
23
0094-terminal-free-xkb-state-on-keyboard-destruction.patch
Normal file
@ -0,0 +1,23 @@
|
||||
From 200716a628b70fe723e7d4e09bb2ece10c10bdc0 Mon Sep 17 00:00:00 2001
|
||||
From: David Herrmann <dh.herrmann@gmail.com>
|
||||
Date: Thu, 28 Aug 2014 12:21:33 +0200
|
||||
Subject: [PATCH] terminal: free xkb state on keyboard destruction
|
||||
|
||||
Fix leaking the xkb-state during keyboard destruction, leaking lots of xkb
|
||||
references into the wild.
|
||||
---
|
||||
src/libsystemd-terminal/idev-keyboard.c | 1 +
|
||||
1 file changed, 1 insertion(+)
|
||||
|
||||
diff --git a/src/libsystemd-terminal/idev-keyboard.c b/src/libsystemd-terminal/idev-keyboard.c
|
||||
index 7ab4db2cf7..03f54bb74f 100644
|
||||
--- a/src/libsystemd-terminal/idev-keyboard.c
|
||||
+++ b/src/libsystemd-terminal/idev-keyboard.c
|
||||
@@ -550,6 +550,7 @@ int idev_keyboard_new(idev_device **out, idev_session *s, const char *name) {
|
||||
static void keyboard_free(idev_device *d) {
|
||||
idev_keyboard *k = keyboard_from_device(d);
|
||||
|
||||
+ xkb_state_unref(k->xkb_state);
|
||||
free(k->repdata.keyboard.codepoints);
|
||||
free(k->repdata.keyboard.keysyms);
|
||||
free(k->evdata.keyboard.codepoints);
|
38
0095-terminal-free-sysview-device-names-on-destruction.patch
Normal file
38
0095-terminal-free-sysview-device-names-on-destruction.patch
Normal file
@ -0,0 +1,38 @@
|
||||
From fa9838ddd62ea31f8aea99757916a16d76b31cbc Mon Sep 17 00:00:00 2001
|
||||
From: David Herrmann <dh.herrmann@gmail.com>
|
||||
Date: Thu, 28 Aug 2014 12:25:58 +0200
|
||||
Subject: [PATCH] terminal: free sysview-device names on destruction
|
||||
|
||||
Don't leak the device-names during device destruction in sysview. Somehow,
|
||||
the device-name is "const char*", so make it "char*" first to avoid
|
||||
warnings when calling free() on it.
|
||||
---
|
||||
src/libsystemd-terminal/sysview-internal.h | 2 +-
|
||||
src/libsystemd-terminal/sysview.c | 1 +
|
||||
2 files changed, 2 insertions(+), 1 deletion(-)
|
||||
|
||||
diff --git a/src/libsystemd-terminal/sysview-internal.h b/src/libsystemd-terminal/sysview-internal.h
|
||||
index 5aee9f67d8..9299fabb82 100644
|
||||
--- a/src/libsystemd-terminal/sysview-internal.h
|
||||
+++ b/src/libsystemd-terminal/sysview-internal.h
|
||||
@@ -39,7 +39,7 @@
|
||||
|
||||
struct sysview_device {
|
||||
sysview_seat *seat;
|
||||
- const char *name;
|
||||
+ char *name;
|
||||
unsigned int type;
|
||||
|
||||
union {
|
||||
diff --git a/src/libsystemd-terminal/sysview.c b/src/libsystemd-terminal/sysview.c
|
||||
index f5363dedf4..bd345fa22e 100644
|
||||
--- a/src/libsystemd-terminal/sysview.c
|
||||
+++ b/src/libsystemd-terminal/sysview.c
|
||||
@@ -98,6 +98,7 @@ sysview_device *sysview_device_free(sysview_device *device) {
|
||||
break;
|
||||
}
|
||||
|
||||
+ free(device->name);
|
||||
free(device);
|
||||
|
||||
return NULL;
|
70
0096-bus-fix-use-after-free-in-slot-release.patch
Normal file
70
0096-bus-fix-use-after-free-in-slot-release.patch
Normal file
@ -0,0 +1,70 @@
|
||||
From d974ad0524942882f489914013d08ab16d147170 Mon Sep 17 00:00:00 2001
|
||||
From: David Herrmann <dh.herrmann@gmail.com>
|
||||
Date: Thu, 28 Aug 2014 12:42:03 +0200
|
||||
Subject: [PATCH] bus: fix use-after-free in slot-release
|
||||
|
||||
We must not access slot->floating after we possible dropped the last
|
||||
reference to it. Fix all callback-invocations to first check
|
||||
slot->floating and possible disconnect the slot, then release the last
|
||||
reference.
|
||||
---
|
||||
src/libsystemd/sd-bus/sd-bus.c | 12 +++++++++---
|
||||
1 file changed, 9 insertions(+), 3 deletions(-)
|
||||
|
||||
diff --git a/src/libsystemd/sd-bus/sd-bus.c b/src/libsystemd/sd-bus/sd-bus.c
|
||||
index a204d67590..8caa404227 100644
|
||||
--- a/src/libsystemd/sd-bus/sd-bus.c
|
||||
+++ b/src/libsystemd/sd-bus/sd-bus.c
|
||||
@@ -2107,7 +2107,7 @@ static int process_timeout(sd_bus *bus) {
|
||||
r = c->callback(bus, m, slot->userdata, &error_buffer);
|
||||
bus->current_userdata = NULL;
|
||||
bus->current_handler = NULL;
|
||||
- bus->current_slot = sd_bus_slot_unref(slot);
|
||||
+ bus->current_slot = NULL;
|
||||
bus->current_message = NULL;
|
||||
|
||||
if (slot->floating) {
|
||||
@@ -2115,6 +2115,8 @@ static int process_timeout(sd_bus *bus) {
|
||||
sd_bus_slot_unref(slot);
|
||||
}
|
||||
|
||||
+ sd_bus_slot_unref(slot);
|
||||
+
|
||||
return bus_maybe_reply_error(m, r, &error_buffer);
|
||||
}
|
||||
|
||||
@@ -2203,13 +2205,15 @@ static int process_reply(sd_bus *bus, sd_bus_message *m) {
|
||||
r = c->callback(bus, m, slot->userdata, &error_buffer);
|
||||
bus->current_userdata = NULL;
|
||||
bus->current_handler = NULL;
|
||||
- bus->current_slot = sd_bus_slot_unref(slot);
|
||||
+ bus->current_slot = NULL;
|
||||
|
||||
if (slot->floating) {
|
||||
bus_slot_disconnect(slot);
|
||||
sd_bus_slot_unref(slot);
|
||||
}
|
||||
|
||||
+ sd_bus_slot_unref(slot);
|
||||
+
|
||||
return bus_maybe_reply_error(m, r, &error_buffer);
|
||||
}
|
||||
|
||||
@@ -2529,7 +2533,7 @@ static int process_closing(sd_bus *bus, sd_bus_message **ret) {
|
||||
r = c->callback(bus, m, slot->userdata, &error_buffer);
|
||||
bus->current_userdata = NULL;
|
||||
bus->current_handler = NULL;
|
||||
- bus->current_slot = sd_bus_slot_unref(slot);
|
||||
+ bus->current_slot = NULL;
|
||||
bus->current_message = NULL;
|
||||
|
||||
if (slot->floating) {
|
||||
@@ -2537,6 +2541,8 @@ static int process_closing(sd_bus *bus, sd_bus_message **ret) {
|
||||
sd_bus_slot_unref(slot);
|
||||
}
|
||||
|
||||
+ sd_bus_slot_unref(slot);
|
||||
+
|
||||
return bus_maybe_reply_error(m, r, &error_buffer);
|
||||
}
|
||||
|
131
0097-macro-use-unique-variable-names-for-math-macros.patch
Normal file
131
0097-macro-use-unique-variable-names-for-math-macros.patch
Normal file
@ -0,0 +1,131 @@
|
||||
From 667a0377fb25ddb0c3efbc43d186ffd4c097ce41 Mon Sep 17 00:00:00 2001
|
||||
From: David Herrmann <dh.herrmann@gmail.com>
|
||||
Date: Thu, 28 Aug 2014 14:45:38 +0200
|
||||
Subject: [PATCH] macro: use unique variable names for math-macros
|
||||
|
||||
Similar to container_of(), we now use unique variable names for the bascic
|
||||
math macros MAX, MIN, CLAMP, LESS_BY. Furthermore, unit tests are added to
|
||||
verify they work as expected.
|
||||
|
||||
For a rationale, see:
|
||||
commit fb835651aff79a1e7fc5795086c9b26e59a8e6ca
|
||||
Author: David Herrmann <dh.herrmann@gmail.com>
|
||||
Date: Fri Aug 22 14:41:37 2014 +0200
|
||||
|
||||
shared: make container_of() use unique variable names
|
||||
---
|
||||
src/shared/macro.h | 53 +++++++++++++++++++++++++++++-----------------------
|
||||
src/test/test-util.c | 17 +++++++++++++++++
|
||||
2 files changed, 47 insertions(+), 23 deletions(-)
|
||||
|
||||
diff --git a/src/shared/macro.h b/src/shared/macro.h
|
||||
index e6734804bd..9ee332c8df 100644
|
||||
--- a/src/shared/macro.h
|
||||
+++ b/src/shared/macro.h
|
||||
@@ -134,12 +134,13 @@ static inline unsigned long ALIGN_POWER2(unsigned long u) {
|
||||
})
|
||||
|
||||
#undef MAX
|
||||
-#define MAX(a,b) \
|
||||
+#define MAX(a, b) __MAX(UNIQ, (a), UNIQ, (b))
|
||||
+#define __MAX(aq, a, bq, b) \
|
||||
__extension__ ({ \
|
||||
- const typeof(a) _a = (a); \
|
||||
- const typeof(b) _b = (b); \
|
||||
- _a > _b ? _a : _b; \
|
||||
- })
|
||||
+ const typeof(a) UNIQ_T(A, aq) = (a); \
|
||||
+ const typeof(b) UNIQ_T(B, bq) = (b); \
|
||||
+ UNIQ_T(A,aq) > UNIQ_T(B,bq) ? UNIQ_T(A,aq) : UNIQ_T(B,bq); \
|
||||
+ })
|
||||
|
||||
/* evaluates to (void) if _A or _B are not constant or of different types */
|
||||
#define CONST_MAX(_A, _B) \
|
||||
@@ -160,12 +161,13 @@ static inline unsigned long ALIGN_POWER2(unsigned long u) {
|
||||
})
|
||||
|
||||
#undef MIN
|
||||
-#define MIN(a,b) \
|
||||
+#define MIN(a, b) __MIN(UNIQ, (a), UNIQ, (b))
|
||||
+#define __MIN(aq, a, bq, b) \
|
||||
__extension__ ({ \
|
||||
- const typeof(a) _a = (a); \
|
||||
- const typeof(b) _b = (b); \
|
||||
- _a < _b ? _a : _b; \
|
||||
- })
|
||||
+ const typeof(a) UNIQ_T(A, aq) = (a); \
|
||||
+ const typeof(b) UNIQ_T(B, bq) = (b); \
|
||||
+ UNIQ_T(A,aq) < UNIQ_T(B,bq) ? UNIQ_T(A,aq) : UNIQ_T(B,bq); \
|
||||
+ })
|
||||
|
||||
#define MIN3(x,y,z) \
|
||||
__extension__ ({ \
|
||||
@@ -173,22 +175,27 @@ static inline unsigned long ALIGN_POWER2(unsigned long u) {
|
||||
MIN(_c, z); \
|
||||
})
|
||||
|
||||
-#define LESS_BY(A,B) \
|
||||
+#define LESS_BY(a, b) __LESS_BY(UNIQ, (a), UNIQ, (b))
|
||||
+#define __LESS_BY(aq, a, bq, b) \
|
||||
__extension__ ({ \
|
||||
- const typeof(A) _A = (A); \
|
||||
- const typeof(B) _B = (B); \
|
||||
- _A > _B ? _A - _B : 0; \
|
||||
- })
|
||||
+ const typeof(a) UNIQ_T(A, aq) = (a); \
|
||||
+ const typeof(b) UNIQ_T(B, bq) = (b); \
|
||||
+ UNIQ_T(A,aq) > UNIQ_T(B,bq) ? UNIQ_T(A,aq) - UNIQ_T(B,bq) : 0; \
|
||||
+ })
|
||||
|
||||
-#ifndef CLAMP
|
||||
-#define CLAMP(x, low, high) \
|
||||
+#undef CLAMP
|
||||
+#define CLAMP(x, low, high) __CLAMP(UNIQ, (x), UNIQ, (low), UNIQ, (high))
|
||||
+#define __CLAMP(xq, x, lowq, low, highq, high) \
|
||||
__extension__ ({ \
|
||||
- const typeof(x) _x = (x); \
|
||||
- const typeof(low) _low = (low); \
|
||||
- const typeof(high) _high = (high); \
|
||||
- ((_x > _high) ? _high : ((_x < _low) ? _low : _x)); \
|
||||
- })
|
||||
-#endif
|
||||
+ const typeof(x) UNIQ_T(X,xq) = (x); \
|
||||
+ const typeof(low) UNIQ_T(LOW,lowq) = (low); \
|
||||
+ const typeof(high) UNIQ_T(HIGH,highq) = (high); \
|
||||
+ UNIQ_T(X,xq) > UNIQ_T(HIGH,highq) ? \
|
||||
+ UNIQ_T(HIGH,highq) : \
|
||||
+ UNIQ_T(X,xq) < UNIQ_T(LOW,lowq) ? \
|
||||
+ UNIQ_T(LOW,lowq) : \
|
||||
+ UNIQ_T(X,xq); \
|
||||
+ })
|
||||
|
||||
#define assert_se(expr) \
|
||||
do { \
|
||||
diff --git a/src/test/test-util.c b/src/test/test-util.c
|
||||
index 795f3a1b3d..72a8a6b130 100644
|
||||
--- a/src/test/test-util.c
|
||||
+++ b/src/test/test-util.c
|
||||
@@ -94,6 +94,23 @@ static void test_max(void) {
|
||||
assert_cc(MAXSIZE(char[3], uint16_t) == 3);
|
||||
assert_cc(MAXSIZE(char[3], uint32_t) == 4);
|
||||
assert_cc(MAXSIZE(char, long) == sizeof(long));
|
||||
+
|
||||
+ assert_se(MAX(-5, 5) == 5);
|
||||
+ assert_se(MAX(5, 5) == 5);
|
||||
+ assert_se(MAX(MAX(1, MAX(2, MAX(3, 4))), 5) == 5);
|
||||
+ assert_se(MAX(MAX(1, MAX(2, MAX(3, 2))), 1) == 3);
|
||||
+ assert_se(MAX(MIN(1, MIN(2, MIN(3, 4))), 5) == 5);
|
||||
+ assert_se(MAX(MAX(1, MIN(2, MIN(3, 2))), 1) == 2);
|
||||
+ assert_se(LESS_BY(8, 4) == 4);
|
||||
+ assert_se(LESS_BY(8, 8) == 0);
|
||||
+ assert_se(LESS_BY(4, 8) == 0);
|
||||
+ assert_se(LESS_BY(16, LESS_BY(8, 4)) == 12);
|
||||
+ assert_se(LESS_BY(4, LESS_BY(8, 4)) == 0);
|
||||
+ assert_se(CLAMP(-5, 0, 1) == 0);
|
||||
+ assert_se(CLAMP(5, 0, 1) == 1);
|
||||
+ assert_se(CLAMP(5, -10, 1) == 1);
|
||||
+ assert_se(CLAMP(5, -10, 10) == 5);
|
||||
+ assert_se(CLAMP(CLAMP(0, -10, 10), CLAMP(-5, 10, 20), CLAMP(100, -5, 20)) == 10);
|
||||
}
|
||||
|
||||
static void test_container_of(void) {
|
275
0098-use-the-switch_root-function-in-shutdown.patch
Normal file
275
0098-use-the-switch_root-function-in-shutdown.patch
Normal file
@ -0,0 +1,275 @@
|
||||
From 5a4bf02ff57e4dd3453f2b868c72fe45f60033a3 Mon Sep 17 00:00:00 2001
|
||||
From: Harald Hoyer <harald@redhat.com>
|
||||
Date: Thu, 21 Aug 2014 16:21:26 +0200
|
||||
Subject: [PATCH] use the switch_root function in shutdown
|
||||
|
||||
removes code duplication
|
||||
|
||||
also move switch-root to shared
|
||||
---
|
||||
Makefile.am | 4 +-
|
||||
src/core/main.c | 4 +-
|
||||
src/core/shutdown.c | 90 +++++++-------------------------------
|
||||
src/{core => shared}/switch-root.c | 35 +++++++--------
|
||||
src/{core => shared}/switch-root.h | 2 +-
|
||||
5 files changed, 39 insertions(+), 96 deletions(-)
|
||||
rename src/{core => shared}/switch-root.c (81%)
|
||||
rename src/{core => shared}/switch-root.h (88%)
|
||||
|
||||
diff --git a/Makefile.am b/Makefile.am
|
||||
index e091febc1f..1facb8da43 100644
|
||||
--- a/Makefile.am
|
||||
+++ b/Makefile.am
|
||||
@@ -868,6 +868,8 @@ libsystemd_shared_la_SOURCES = \
|
||||
src/shared/memfd.h \
|
||||
src/shared/uid-range.c \
|
||||
src/shared/uid-range.h \
|
||||
+ src/shared/switch-root.h \
|
||||
+ src/shared/switch-root.c \
|
||||
src/shared/nss-util.h
|
||||
|
||||
nodist_libsystemd_shared_la_SOURCES = \
|
||||
@@ -1109,8 +1111,6 @@ libsystemd_core_la_SOURCES = \
|
||||
src/core/namespace.h \
|
||||
src/core/build.h \
|
||||
src/core/sysfs-show.h \
|
||||
- src/core/switch-root.h \
|
||||
- src/core/switch-root.c \
|
||||
src/core/killall.h \
|
||||
src/core/killall.c \
|
||||
src/core/audit-fd.c \
|
||||
diff --git a/src/core/main.c b/src/core/main.c
|
||||
index 95ab40fffc..64c2b3f3a1 100644
|
||||
--- a/src/core/main.c
|
||||
+++ b/src/core/main.c
|
||||
@@ -1853,8 +1853,8 @@ finish:
|
||||
* deserializing. */
|
||||
broadcast_signal(SIGTERM, false, true);
|
||||
|
||||
- /* And switch root */
|
||||
- r = switch_root(switch_root_dir);
|
||||
+ /* And switch root with MS_MOVE, because we remove the old directory afterwards and detach it. */
|
||||
+ r = switch_root(switch_root_dir, "/mnt", true, MS_MOVE);
|
||||
if (r < 0)
|
||||
log_error("Failed to switch root, ignoring: %s", strerror(-r));
|
||||
}
|
||||
diff --git a/src/core/shutdown.c b/src/core/shutdown.c
|
||||
index 0e2ea5754f..1e88b05790 100644
|
||||
--- a/src/core/shutdown.c
|
||||
+++ b/src/core/shutdown.c
|
||||
@@ -48,6 +48,7 @@
|
||||
#include "killall.h"
|
||||
#include "cgroup-util.h"
|
||||
#include "def.h"
|
||||
+#include "switch-root.h"
|
||||
|
||||
#define FINALIZE_ATTEMPTS 50
|
||||
|
||||
@@ -131,16 +132,7 @@ static int parse_argv(int argc, char *argv[]) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
-static int prepare_new_root(void) {
|
||||
- static const char dirs[] =
|
||||
- "/run/initramfs/oldroot\0"
|
||||
- "/run/initramfs/proc\0"
|
||||
- "/run/initramfs/sys\0"
|
||||
- "/run/initramfs/dev\0"
|
||||
- "/run/initramfs/run\0";
|
||||
-
|
||||
- const char *dir;
|
||||
-
|
||||
+static int switch_root_initramfs(void) {
|
||||
if (mount("/run/initramfs", "/run/initramfs", NULL, MS_BIND, NULL) < 0) {
|
||||
log_error("Failed to mount bind /run/initramfs on /run/initramfs: %m");
|
||||
return -errno;
|
||||
@@ -151,66 +143,13 @@ static int prepare_new_root(void) {
|
||||
return -errno;
|
||||
}
|
||||
|
||||
- NULSTR_FOREACH(dir, dirs)
|
||||
- if (mkdir_p_label(dir, 0755) < 0 && errno != EEXIST) {
|
||||
- log_error("Failed to mkdir %s: %m", dir);
|
||||
- return -errno;
|
||||
- }
|
||||
-
|
||||
- if (mount("/sys", "/run/initramfs/sys", NULL, MS_BIND, NULL) < 0) {
|
||||
- log_error("Failed to mount bind /sys on /run/initramfs/sys: %m");
|
||||
- return -errno;
|
||||
- }
|
||||
-
|
||||
- if (mount("/proc", "/run/initramfs/proc", NULL, MS_BIND, NULL) < 0) {
|
||||
- log_error("Failed to mount bind /proc on /run/initramfs/proc: %m");
|
||||
- return -errno;
|
||||
- }
|
||||
-
|
||||
- if (mount("/dev", "/run/initramfs/dev", NULL, MS_BIND, NULL) < 0) {
|
||||
- log_error("Failed to mount bind /dev on /run/initramfs/dev: %m");
|
||||
- return -errno;
|
||||
- }
|
||||
-
|
||||
- if (mount("/run", "/run/initramfs/run", NULL, MS_BIND, NULL) < 0) {
|
||||
- log_error("Failed to mount bind /run on /run/initramfs/run: %m");
|
||||
- return -errno;
|
||||
- }
|
||||
-
|
||||
- return 0;
|
||||
+ /* switch_root with MS_BIND, because there might still be processes lurking around, which have open file desriptors.
|
||||
+ * /run/initramfs/shutdown will take care of these.
|
||||
+ * Also do not detach the old root, because /run/initramfs/shutdown needs to access it.
|
||||
+ */
|
||||
+ return switch_root("/run/initramfs", "/oldroot", false, MS_BIND);
|
||||
}
|
||||
|
||||
-static int pivot_to_new_root(void) {
|
||||
-
|
||||
- if (chdir("/run/initramfs") < 0) {
|
||||
- log_error("Failed to change directory to /run/initramfs: %m");
|
||||
- return -errno;
|
||||
- }
|
||||
-
|
||||
- /* Work-around for a kernel bug: for some reason the kernel
|
||||
- * refuses switching root if any file systems are mounted
|
||||
- * MS_SHARED. Hence remount them MS_PRIVATE here as a
|
||||
- * work-around.
|
||||
- *
|
||||
- * https://bugzilla.redhat.com/show_bug.cgi?id=847418 */
|
||||
- if (mount(NULL, "/", NULL, MS_REC|MS_PRIVATE, NULL) < 0)
|
||||
- log_warning("Failed to make \"/\" private mount: %m");
|
||||
-
|
||||
- if (pivot_root(".", "oldroot") < 0) {
|
||||
- log_error("pivot failed: %m");
|
||||
- /* only chroot if pivot root succeeded */
|
||||
- return -errno;
|
||||
- }
|
||||
-
|
||||
- chroot(".");
|
||||
-
|
||||
- setsid();
|
||||
- make_console_stdio();
|
||||
-
|
||||
- log_info("Successfully changed into root pivot.");
|
||||
-
|
||||
- return 0;
|
||||
-}
|
||||
|
||||
int main(int argc, char *argv[]) {
|
||||
bool need_umount, need_swapoff, need_loop_detach, need_dm_detach;
|
||||
@@ -372,16 +311,21 @@ int main(int argc, char *argv[]) {
|
||||
|
||||
if (!in_container && !in_initrd() &&
|
||||
access("/run/initramfs/shutdown", X_OK) == 0) {
|
||||
-
|
||||
- if (prepare_new_root() >= 0 &&
|
||||
- pivot_to_new_root() >= 0) {
|
||||
+ r = switch_root_initramfs();
|
||||
+ if (r >= 0) {
|
||||
arguments[0] = (char*) "/shutdown";
|
||||
|
||||
- log_info("Returning to initrd...");
|
||||
+ setsid();
|
||||
+ make_console_stdio();
|
||||
+
|
||||
+ log_info("Successfully changed into root pivot.\n"
|
||||
+ "Returning to initrd...");
|
||||
|
||||
execv("/shutdown", arguments);
|
||||
log_error("Failed to execute shutdown binary: %m");
|
||||
- }
|
||||
+ } else
|
||||
+ log_error("Failed to switch root to \"/run/initramfs\": %s", strerror(-r));
|
||||
+
|
||||
}
|
||||
|
||||
if (need_umount || need_swapoff || need_loop_detach || need_dm_detach)
|
||||
diff --git a/src/core/switch-root.c b/src/shared/switch-root.c
|
||||
similarity index 81%
|
||||
rename from src/core/switch-root.c
|
||||
rename to src/shared/switch-root.c
|
||||
index 0ea61dbb29..5f075e6003 100644
|
||||
--- a/src/core/switch-root.c
|
||||
+++ b/src/shared/switch-root.c
|
||||
@@ -34,7 +34,7 @@
|
||||
#include "base-filesystem.h"
|
||||
#include "missing.h"
|
||||
|
||||
-int switch_root(const char *new_root) {
|
||||
+int switch_root(const char *new_root, const char *oldroot, bool detach_oldroot, unsigned long mountflags) {
|
||||
|
||||
/* Don't try to unmount/move the old "/", there's no way to do it. */
|
||||
static const char move_mounts[] =
|
||||
@@ -52,14 +52,8 @@ int switch_root(const char *new_root) {
|
||||
if (path_equal(new_root, "/"))
|
||||
return 0;
|
||||
|
||||
- /* When using pivot_root() we assume that /mnt exists as place
|
||||
- * we can temporarily move the old root to. As we immediately
|
||||
- * unmount it from there it doesn't matter much which
|
||||
- * directory we choose for this, but it should be more likely
|
||||
- * than not that /mnt exists and is suitable as mount point
|
||||
- * and is on the same fs as the old root dir */
|
||||
- temporary_old_root = strappenda(new_root, "/mnt");
|
||||
- mkdir_p(temporary_old_root, 0755);
|
||||
+ temporary_old_root = strappenda(new_root, oldroot);
|
||||
+ mkdir_p_label(temporary_old_root, 0755);
|
||||
|
||||
old_root_remove = in_initrd();
|
||||
|
||||
@@ -84,7 +78,7 @@ int switch_root(const char *new_root) {
|
||||
snprintf(new_mount, sizeof(new_mount), "%s%s", new_root, i);
|
||||
char_array_0(new_mount);
|
||||
|
||||
- mkdir_p(new_mount, 0755);
|
||||
+ mkdir_p_label(new_mount, 0755);
|
||||
|
||||
if ((stat(new_mount, &sb) < 0) ||
|
||||
sb.st_dev != new_root_stat.st_dev) {
|
||||
@@ -97,11 +91,16 @@ int switch_root(const char *new_root) {
|
||||
continue;
|
||||
}
|
||||
|
||||
- if (mount(i, new_mount, NULL, MS_MOVE, NULL) < 0) {
|
||||
- log_error("Failed to move mount %s to %s, forcing unmount: %m", i, new_mount);
|
||||
+ if (mount(i, new_mount, NULL, mountflags, NULL) < 0) {
|
||||
+ if (mountflags & MS_MOVE) {
|
||||
+ log_error("Failed to move mount %s to %s, forcing unmount: %m", i, new_mount);
|
||||
+
|
||||
+ if (umount2(i, MNT_FORCE) < 0)
|
||||
+ log_warning("Failed to unmount %s: %m", i);
|
||||
+ }
|
||||
+ if (mountflags & MS_BIND)
|
||||
+ log_error("Failed to bind mount %s to %s: %m", i, new_mount);
|
||||
|
||||
- if (umount2(i, MNT_FORCE) < 0)
|
||||
- log_warning("Failed to unmount %s: %m", i);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -127,10 +126,10 @@ int switch_root(const char *new_root) {
|
||||
* not possible however, and hence we simply overmount root */
|
||||
if (pivot_root(new_root, temporary_old_root) >= 0) {
|
||||
|
||||
- /* Immediately get rid of the old root. Since we are
|
||||
- * running off it we need to do this lazily. */
|
||||
- if (umount2("/mnt", MNT_DETACH) < 0) {
|
||||
- log_error("Failed to umount old root dir /mnt: %m");
|
||||
+ /* Immediately get rid of the old root, if detach_oldroot is set.
|
||||
+ * Since we are running off it we need to do this lazily. */
|
||||
+ if (detach_oldroot && umount2(oldroot, MNT_DETACH) < 0) {
|
||||
+ log_error("Failed to umount old root dir %s: %m", oldroot);
|
||||
return -errno;
|
||||
}
|
||||
|
||||
diff --git a/src/core/switch-root.h b/src/shared/switch-root.h
|
||||
similarity index 88%
|
||||
rename from src/core/switch-root.h
|
||||
rename to src/shared/switch-root.h
|
||||
index ab493b5fb1..adf893a922 100644
|
||||
--- a/src/core/switch-root.h
|
||||
+++ b/src/shared/switch-root.h
|
||||
@@ -21,4 +21,4 @@
|
||||
along with systemd; If not, see <http://www.gnu.org/licenses/>.
|
||||
***/
|
||||
|
||||
-int switch_root(const char *switch_root);
|
||||
+int switch_root(const char *new_root, const char *oldroot, bool detach_oldroot, unsigned long mountflags);
|
@ -0,0 +1,25 @@
|
||||
From c168eb6785bacc2042687bf879259dfc27d5a523 Mon Sep 17 00:00:00 2001
|
||||
From: David Herrmann <dh.herrmann@gmail.com>
|
||||
Date: Thu, 28 Aug 2014 15:22:26 +0200
|
||||
Subject: [PATCH] locale: fix sending PropertiesChanged for x11 keymap changed
|
||||
|
||||
The sd_bus_emit_properties_changed() call for x11 keymap changes lacks
|
||||
commas.. whoops. Fix it! Now localed emits PropertiesChanged signals
|
||||
again.
|
||||
---
|
||||
src/locale/localed.c | 2 +-
|
||||
1 file changed, 1 insertion(+), 1 deletion(-)
|
||||
|
||||
diff --git a/src/locale/localed.c b/src/locale/localed.c
|
||||
index 508a00079e..4d22568787 100644
|
||||
--- a/src/locale/localed.c
|
||||
+++ b/src/locale/localed.c
|
||||
@@ -1046,7 +1046,7 @@ static int method_set_x11_keyboard(sd_bus *bus, sd_bus_message *m, void *userdat
|
||||
sd_bus_emit_properties_changed(bus,
|
||||
"/org/freedesktop/locale1",
|
||||
"org.freedesktop.locale1",
|
||||
- "X11Layout" "X11Model" "X11Variant" "X11Options", NULL);
|
||||
+ "X11Layout", "X11Model", "X11Variant", "X11Options", NULL);
|
||||
|
||||
if (convert) {
|
||||
r = x11_convert_to_vconsole(c, bus);
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue
Block a user