forked from pool/systemd
Accepting request 155884 from Base:System
- Ensure journal is flushed on disk when systemd-logger is installed for the first time. - Add improve-journal-perf.patch: improve journal performance on query. - Add support-hybrid-suspend.patch: add support for hybrid suspend. - Add forward-to-pmutils.patch: forward suspend/hibernation calls to pm-utils, if installed (bnc#790157). (forwarded request 155834 from fcrozat) OBS-URL: https://build.opensuse.org/request/show/155884 OBS-URL: https://build.opensuse.org/package/show/openSUSE:Factory/systemd?expand=0&rev=132
This commit is contained in:
parent
262bc65aad
commit
96aa32bb59
93
forward-to-pmutils.patch
Normal file
93
forward-to-pmutils.patch
Normal file
@ -0,0 +1,93 @@
|
|||||||
|
Index: systemd-195/src/sleep/sleep.c
|
||||||
|
===================================================================
|
||||||
|
--- systemd-195.orig/src/sleep/sleep.c
|
||||||
|
+++ systemd-195/src/sleep/sleep.c
|
||||||
|
@@ -22,6 +22,7 @@
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <errno.h>
|
||||||
|
#include <string.h>
|
||||||
|
+#include <stdlib.h>
|
||||||
|
|
||||||
|
#include "log.h"
|
||||||
|
#include "util.h"
|
||||||
|
@@ -31,6 +32,9 @@
|
||||||
|
int main(int argc, char *argv[]) {
|
||||||
|
const char *verb;
|
||||||
|
char* arguments[4];
|
||||||
|
+ const char *pmtools;
|
||||||
|
+ bool delegate_to_pmutils = false;
|
||||||
|
+ struct stat buf;
|
||||||
|
int r;
|
||||||
|
FILE *f;
|
||||||
|
|
||||||
|
@@ -44,17 +48,27 @@ int main(int argc, char *argv[]) {
|
||||||
|
goto finish;
|
||||||
|
}
|
||||||
|
|
||||||
|
- if (streq(argv[1], "suspend"))
|
||||||
|
+ if (streq(argv[1], "suspend")) {
|
||||||
|
verb = "mem";
|
||||||
|
- else if (streq(argv[1], "hibernate") || streq(argv[1], "hybrid-sleep"))
|
||||||
|
+ pmtools = "/usr/sbin/pm-suspend";
|
||||||
|
+ }
|
||||||
|
+ else if (streq(argv[1], "hibernate") || streq(argv[1], "hybrid-sleep")) {
|
||||||
|
verb = "disk";
|
||||||
|
+ if (streq(argv[1], "hibernate"))
|
||||||
|
+ pmtools = "/usr/sbin/pm-hibernate";
|
||||||
|
+ else
|
||||||
|
+ pmtools = "/usr/sbin/pm-suspend-hybrid";
|
||||||
|
+ }
|
||||||
|
else {
|
||||||
|
log_error("Unknown action '%s'.", argv[1]);
|
||||||
|
r = -EINVAL;
|
||||||
|
goto finish;
|
||||||
|
}
|
||||||
|
|
||||||
|
+ delegate_to_pmutils = (stat(pmtools, &buf) >= 0 && S_ISREG(buf.st_mode) && (buf.st_mode & 0111));
|
||||||
|
+
|
||||||
|
/* Configure the hibernation mode */
|
||||||
|
+ if (!delegate_to_pmutils) {
|
||||||
|
if (streq(argv[1], "hibernate")) {
|
||||||
|
if (write_one_line_file("/sys/power/disk", "platform") < 0)
|
||||||
|
write_one_line_file("/sys/power/disk", "shutdown");
|
||||||
|
@@ -64,13 +78,14 @@ int main(int argc, char *argv[]) {
|
||||||
|
write_one_line_file("/sys/power/disk", "shutdown");
|
||||||
|
}
|
||||||
|
|
||||||
|
+
|
||||||
|
f = fopen("/sys/power/state", "we");
|
||||||
|
if (!f) {
|
||||||
|
log_error("Failed to open /sys/power/state: %m");
|
||||||
|
r = -errno;
|
||||||
|
goto finish;
|
||||||
|
}
|
||||||
|
-
|
||||||
|
+ }
|
||||||
|
arguments[0] = NULL;
|
||||||
|
arguments[1] = (char*) "pre";
|
||||||
|
arguments[2] = argv[1];
|
||||||
|
@@ -96,11 +111,16 @@ int main(int argc, char *argv[]) {
|
||||||
|
"SLEEP=hybrid-sleep",
|
||||||
|
NULL);
|
||||||
|
|
||||||
|
+ if (delegate_to_pmutils) {
|
||||||
|
+ r = -system(pmtools);
|
||||||
|
+ }
|
||||||
|
+ else {
|
||||||
|
fputs(verb, f);
|
||||||
|
fputc('\n', f);
|
||||||
|
fflush(f);
|
||||||
|
|
||||||
|
r = ferror(f) ? -errno : 0;
|
||||||
|
+ }
|
||||||
|
|
||||||
|
if (streq(argv[1], "suspend"))
|
||||||
|
log_struct(LOG_INFO,
|
||||||
|
@@ -118,6 +138,7 @@ int main(int argc, char *argv[]) {
|
||||||
|
arguments[1] = (char*) "post";
|
||||||
|
execute_directory(SYSTEM_SLEEP_PATH, NULL, arguments);
|
||||||
|
|
||||||
|
+ if (!delegate_to_pmutils)
|
||||||
|
fclose(f);
|
||||||
|
|
||||||
|
finish:
|
@ -8,7 +8,7 @@ Index: systemd-195/bash-completion/systemd-bash-completion.sh
|
|||||||
[STANDALONE]='daemon-reexec daemon-reload default dot dump
|
[STANDALONE]='daemon-reexec daemon-reload default dot dump
|
||||||
- emergency exit halt kexec list-jobs list-units
|
- emergency exit halt kexec list-jobs list-units
|
||||||
- list-unit-files poweroff reboot rescue show-environment'
|
- list-unit-files poweroff reboot rescue show-environment'
|
||||||
+ emergency exit halt hibernate kexec list-jobs list-units
|
+ emergency exit halt hybrid-sleep hibernate kexec list-jobs list-units
|
||||||
+ list-unit-files poweroff reboot rescue show-environment suspend'
|
+ list-unit-files poweroff reboot rescue show-environment suspend'
|
||||||
[NAME]='snapshot load'
|
[NAME]='snapshot load'
|
||||||
[FILE]='link'
|
[FILE]='link'
|
||||||
|
304
improve-journal-perf.patch
Normal file
304
improve-journal-perf.patch
Normal file
@ -0,0 +1,304 @@
|
|||||||
|
From a4bcff5ba36115495994e9f9ba66074471de76ab Mon Sep 17 00:00:00 2001
|
||||||
|
From: Lennart Poettering <lennart@poettering.net>
|
||||||
|
Date: Fri, 26 Oct 2012 03:24:03 +0200
|
||||||
|
Subject: [PATCH] journal: introduce entry array chain cache
|
||||||
|
|
||||||
|
When traversing entry array chains for a bisection or for retrieving an
|
||||||
|
item by index we previously always started at the beginning of the
|
||||||
|
chain. Since we tend to look at the same chains repeatedly, let's cache
|
||||||
|
where we have been the last time, and maybe we can skip ahead with this
|
||||||
|
the next time.
|
||||||
|
|
||||||
|
This turns most bisections and index lookups from O(log(n)*log(n)) into
|
||||||
|
O(log(n)). More importantly however, we seek around on disk much less,
|
||||||
|
which is good to reduce buffer cache and seek times on rotational disks.
|
||||||
|
---
|
||||||
|
.gitignore | 1 +
|
||||||
|
Makefile.am | 9 ++++
|
||||||
|
src/journal/journal-file.c | 109 +++++++++++++++++++++++++++++++++++++---
|
||||||
|
src/journal/journal-file.h | 3 ++
|
||||||
|
src/journal/test-journal-enum.c | 53 +++++++++++++++++++
|
||||||
|
src/shared/hashmap.c | 19 +++++++
|
||||||
|
src/shared/hashmap.h | 3 ++
|
||||||
|
7 files changed, 189 insertions(+), 8 deletions(-)
|
||||||
|
create mode 100644 src/journal/test-journal-enum.c
|
||||||
|
|
||||||
|
diff --git a/src/journal/journal-file.c b/src/journal/journal-file.c
|
||||||
|
index edf8e7d..6c9deac 100644
|
||||||
|
--- a/src/journal/journal-file.c
|
||||||
|
+++ b/src/journal/journal-file.c
|
||||||
|
@@ -65,6 +65,9 @@
|
||||||
|
/* n_data was the first entry we added after the initial file format design */
|
||||||
|
#define HEADER_SIZE_MIN ALIGN64(offsetof(Header, n_data))
|
||||||
|
|
||||||
|
+/* How many entries to keep in the entry array chain cache at max */
|
||||||
|
+#define CHAIN_CACHE_MAX 20
|
||||||
|
+
|
||||||
|
void journal_file_close(JournalFile *f) {
|
||||||
|
assert(f);
|
||||||
|
|
||||||
|
@@ -97,6 +100,8 @@ void journal_file_close(JournalFile *f) {
|
||||||
|
if (f->mmap)
|
||||||
|
mmap_cache_unref(f->mmap);
|
||||||
|
|
||||||
|
+ hashmap_free_free(f->chain_cache);
|
||||||
|
+
|
||||||
|
#ifdef HAVE_XZ
|
||||||
|
free(f->compress_buffer);
|
||||||
|
#endif
|
||||||
|
@@ -1307,37 +1312,89 @@ int journal_file_append_entry(JournalFile *f, const dual_timestamp *ts, const st
|
||||||
|
return r;
|
||||||
|
}
|
||||||
|
|
||||||
|
+typedef struct ChainCacheItem {
|
||||||
|
+ uint64_t first; /* the array at the begin of the chain */
|
||||||
|
+ uint64_t array; /* the cached array */
|
||||||
|
+ uint64_t begin; /* the first item in the cached array */
|
||||||
|
+ uint64_t total; /* the total number of items in all arrays before this one in the chain */
|
||||||
|
+} ChainCacheItem;
|
||||||
|
+
|
||||||
|
+static void chain_cache_put(
|
||||||
|
+ Hashmap *h,
|
||||||
|
+ ChainCacheItem *ci,
|
||||||
|
+ uint64_t first,
|
||||||
|
+ uint64_t array,
|
||||||
|
+ uint64_t begin,
|
||||||
|
+ uint64_t total) {
|
||||||
|
+
|
||||||
|
+ if (!ci) {
|
||||||
|
+ if (hashmap_size(h) >= CHAIN_CACHE_MAX)
|
||||||
|
+ ci = hashmap_steal_first(h);
|
||||||
|
+ else {
|
||||||
|
+ ci = new(ChainCacheItem, 1);
|
||||||
|
+ if (!ci)
|
||||||
|
+ return;
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ ci->first = first;
|
||||||
|
+
|
||||||
|
+ if (hashmap_put(h, &ci->first, ci) < 0) {
|
||||||
|
+ free(ci);
|
||||||
|
+ return;
|
||||||
|
+ }
|
||||||
|
+ } else
|
||||||
|
+ assert(ci->first == first);
|
||||||
|
+
|
||||||
|
+ ci->array = array;
|
||||||
|
+ ci->begin = begin;
|
||||||
|
+ ci->total = total;
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
static int generic_array_get(JournalFile *f,
|
||||||
|
uint64_t first,
|
||||||
|
uint64_t i,
|
||||||
|
Object **ret, uint64_t *offset) {
|
||||||
|
|
||||||
|
Object *o;
|
||||||
|
- uint64_t p = 0, a;
|
||||||
|
+ uint64_t p = 0, a, t = 0;
|
||||||
|
int r;
|
||||||
|
+ ChainCacheItem *ci;
|
||||||
|
|
||||||
|
assert(f);
|
||||||
|
|
||||||
|
a = first;
|
||||||
|
+
|
||||||
|
+ /* Try the chain cache first */
|
||||||
|
+ ci = hashmap_get(f->chain_cache, &first);
|
||||||
|
+ if (ci && i > ci->total) {
|
||||||
|
+ a = ci->array;
|
||||||
|
+ i -= ci->total;
|
||||||
|
+ t = ci->total;
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
while (a > 0) {
|
||||||
|
- uint64_t n;
|
||||||
|
+ uint64_t k;
|
||||||
|
|
||||||
|
r = journal_file_move_to_object(f, OBJECT_ENTRY_ARRAY, a, &o);
|
||||||
|
if (r < 0)
|
||||||
|
return r;
|
||||||
|
|
||||||
|
- n = journal_file_entry_array_n_items(o);
|
||||||
|
- if (i < n) {
|
||||||
|
+ k = journal_file_entry_array_n_items(o);
|
||||||
|
+ if (i < k) {
|
||||||
|
p = le64toh(o->entry_array.items[i]);
|
||||||
|
- break;
|
||||||
|
+ goto found;
|
||||||
|
}
|
||||||
|
|
||||||
|
- i -= n;
|
||||||
|
+ i -= k;
|
||||||
|
+ t += k;
|
||||||
|
a = le64toh(o->entry_array.next_entry_array_offset);
|
||||||
|
}
|
||||||
|
|
||||||
|
- if (a <= 0 || p <= 0)
|
||||||
|
- return 0;
|
||||||
|
+ return 0;
|
||||||
|
+
|
||||||
|
+found:
|
||||||
|
+ /* Let's cache this item for the next invocation */
|
||||||
|
+ chain_cache_put(f->chain_cache, ci, first, a, o->entry_array.items[0], t);
|
||||||
|
|
||||||
|
r = journal_file_move_to_object(f, OBJECT_ENTRY, p, &o);
|
||||||
|
if (r < 0)
|
||||||
|
@@ -1401,11 +1458,38 @@ static int generic_array_bisect(JournalFile *f,
|
||||||
|
bool subtract_one = false;
|
||||||
|
Object *o, *array = NULL;
|
||||||
|
int r;
|
||||||
|
+ ChainCacheItem *ci;
|
||||||
|
|
||||||
|
assert(f);
|
||||||
|
assert(test_object);
|
||||||
|
|
||||||
|
+ /* Start with the first array in the chain */
|
||||||
|
a = first;
|
||||||
|
+
|
||||||
|
+ ci = hashmap_get(f->chain_cache, &first);
|
||||||
|
+ if (ci && n > ci->total) {
|
||||||
|
+ /* Ah, we have iterated this bisection array chain
|
||||||
|
+ * previously! Let's see if we can skip ahead in the
|
||||||
|
+ * chain, as far as the last time. But we can't jump
|
||||||
|
+ * backwards in the chain, so let's check that
|
||||||
|
+ * first. */
|
||||||
|
+
|
||||||
|
+ r = test_object(f, ci->begin, needle);
|
||||||
|
+ if (r < 0)
|
||||||
|
+ return r;
|
||||||
|
+
|
||||||
|
+ if (r == TEST_LEFT) {
|
||||||
|
+ /* OK, what we are looking for is right of th
|
||||||
|
+ * begin of this EntryArray, so let's jump
|
||||||
|
+ * straight to previously cached array in the
|
||||||
|
+ * chain */
|
||||||
|
+
|
||||||
|
+ a = ci->array;
|
||||||
|
+ n -= ci->total;
|
||||||
|
+ t = ci->total;
|
||||||
|
+ }
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
while (a > 0) {
|
||||||
|
uint64_t left, right, k, lp;
|
||||||
|
|
||||||
|
@@ -1486,6 +1570,9 @@ found:
|
||||||
|
if (subtract_one && t == 0 && i == 0)
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
+ /* Let's cache this item for the next invocation */
|
||||||
|
+ chain_cache_put(f->chain_cache, ci, first, a, array->entry_array.items[0], t);
|
||||||
|
+
|
||||||
|
if (subtract_one && i == 0)
|
||||||
|
p = last_p;
|
||||||
|
else if (subtract_one)
|
||||||
|
@@ -2265,6 +2352,12 @@ int journal_file_open(
|
||||||
|
goto fail;
|
||||||
|
}
|
||||||
|
|
||||||
|
+ f->chain_cache = hashmap_new(uint64_hash_func, uint64_compare_func);
|
||||||
|
+ if (!f->chain_cache) {
|
||||||
|
+ r = -ENOMEM;
|
||||||
|
+ goto fail;
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
f->fd = open(f->path, f->flags|O_CLOEXEC, f->mode);
|
||||||
|
if (f->fd < 0) {
|
||||||
|
r = -errno;
|
||||||
|
diff --git a/src/journal/journal-file.h b/src/journal/journal-file.h
|
||||||
|
index d87cbe4..cdbc8e4 100644
|
||||||
|
--- a/src/journal/journal-file.h
|
||||||
|
+++ b/src/journal/journal-file.h
|
||||||
|
@@ -33,6 +33,7 @@
|
||||||
|
#include "journal-def.h"
|
||||||
|
#include "util.h"
|
||||||
|
#include "mmap-cache.h"
|
||||||
|
+#include "hashmap.h"
|
||||||
|
|
||||||
|
typedef struct JournalMetrics {
|
||||||
|
uint64_t max_use;
|
||||||
|
@@ -64,6 +65,8 @@ typedef struct JournalFile {
|
||||||
|
JournalMetrics metrics;
|
||||||
|
MMapCache *mmap;
|
||||||
|
|
||||||
|
+ Hashmap *chain_cache;
|
||||||
|
+
|
||||||
|
#ifdef HAVE_XZ
|
||||||
|
void *compress_buffer;
|
||||||
|
uint64_t compress_buffer_size;
|
||||||
|
diff --git a/src/shared/hashmap.c b/src/shared/hashmap.c
|
||||||
|
index ef78070..dcfbb67 100644
|
||||||
|
--- a/src/shared/hashmap.c
|
||||||
|
+++ b/src/shared/hashmap.c
|
||||||
|
@@ -147,6 +147,25 @@ int trivial_compare_func(const void *a, const void *b) {
|
||||||
|
return a < b ? -1 : (a > b ? 1 : 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
+unsigned uint64_hash_func(const void *p) {
|
||||||
|
+ uint64_t u;
|
||||||
|
+
|
||||||
|
+ assert_cc(sizeof(uint64_t) == 2*sizeof(unsigned));
|
||||||
|
+
|
||||||
|
+ u = *(const uint64_t*) p;
|
||||||
|
+
|
||||||
|
+ return (unsigned) ((u >> 32) ^ u);
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
+int uint64_compare_func(const void *_a, const void *_b) {
|
||||||
|
+ uint64_t a, b;
|
||||||
|
+
|
||||||
|
+ a = *(const uint64_t*) _a;
|
||||||
|
+ b = *(const uint64_t*) _b;
|
||||||
|
+
|
||||||
|
+ return a < b ? -1 : (a > b ? 1 : 0);
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
Hashmap *hashmap_new(hash_func_t hash_func, compare_func_t compare_func) {
|
||||||
|
bool b;
|
||||||
|
Hashmap *h;
|
||||||
|
diff --git a/src/shared/hashmap.h b/src/shared/hashmap.h
|
||||||
|
index 55dea0a..6fd71cf 100644
|
||||||
|
--- a/src/shared/hashmap.h
|
||||||
|
+++ b/src/shared/hashmap.h
|
||||||
|
@@ -44,6 +44,9 @@ int string_compare_func(const void *a, const void *b);
|
||||||
|
unsigned trivial_hash_func(const void *p);
|
||||||
|
int trivial_compare_func(const void *a, const void *b);
|
||||||
|
|
||||||
|
+unsigned uint64_hash_func(const void *p);
|
||||||
|
+int uint64_compare_func(const void *a, const void *b);
|
||||||
|
+
|
||||||
|
Hashmap *hashmap_new(hash_func_t hash_func, compare_func_t compare_func);
|
||||||
|
void hashmap_free(Hashmap *h);
|
||||||
|
void hashmap_free_free(Hashmap *h);
|
||||||
|
--
|
||||||
|
1.8.1.1
|
||||||
|
|
||||||
|
From 34741aa3e2ee1e67a4cc735b7492aec13f0d822c Mon Sep 17 00:00:00 2001
|
||||||
|
From: Lennart Poettering <lennart@poettering.net>
|
||||||
|
Date: Fri, 26 Oct 2012 20:25:36 +0200
|
||||||
|
Subject: [PATCH] journal: special case the trivial cache chain cache entry
|
||||||
|
|
||||||
|
---
|
||||||
|
src/journal/journal-file.c | 5 +++++
|
||||||
|
1 file changed, 5 insertions(+)
|
||||||
|
|
||||||
|
diff --git a/src/journal/journal-file.c b/src/journal/journal-file.c
|
||||||
|
index 6c9deac..3df099d 100644
|
||||||
|
--- a/src/journal/journal-file.c
|
||||||
|
+++ b/src/journal/journal-file.c
|
||||||
|
@@ -1328,6 +1328,11 @@ static void chain_cache_put(
|
||||||
|
uint64_t total) {
|
||||||
|
|
||||||
|
if (!ci) {
|
||||||
|
+ /* If the chain item to cache for this chain is the
|
||||||
|
+ * first one it's not worth caching anything */
|
||||||
|
+ if (array == first)
|
||||||
|
+ return;
|
||||||
|
+
|
||||||
|
if (hashmap_size(h) >= CHAIN_CACHE_MAX)
|
||||||
|
ci = hashmap_steal_first(h);
|
||||||
|
else {
|
||||||
|
--
|
||||||
|
1.8.1.1
|
||||||
|
|
680
support-hybrid-suspend.patch
Normal file
680
support-hybrid-suspend.patch
Normal file
@ -0,0 +1,680 @@
|
|||||||
|
From 6524990fdc98370ecba5d9f73e67161e8798c010 Mon Sep 17 00:00:00 2001
|
||||||
|
From: Lennart Poettering <lennart@poettering.net>
|
||||||
|
Date: Sun, 28 Oct 2012 00:49:04 +0200
|
||||||
|
Subject: [PATCH] logind: support for hybrid sleep (i.e. suspend+hibernate at
|
||||||
|
the same time)
|
||||||
|
|
||||||
|
---
|
||||||
|
.gitignore | 1 +
|
||||||
|
Makefile.am | 17 ++++++++-
|
||||||
|
man/logind.conf.xml | 5 ++-
|
||||||
|
man/systemctl.xml | 5 +++
|
||||||
|
man/systemd-suspend.service.xml | 42 +++++++++++++--------
|
||||||
|
man/systemd.special.xml | 15 ++++++--
|
||||||
|
src/core/special.h | 1 +
|
||||||
|
src/login/logind-button.c | 21 ++++++-----
|
||||||
|
src/login/logind-button.h | 1 +
|
||||||
|
src/login/logind-dbus.c | 69 +++++++++++++++++++++++++++++++----
|
||||||
|
src/shared/util.c | 24 ++++++++++++
|
||||||
|
src/shared/util.h | 1 +
|
||||||
|
src/sleep/sleep.c | 20 +++++++++-
|
||||||
|
src/systemctl/systemctl.c | 17 +++++++--
|
||||||
|
src/test/test-sleep.c | 39 ++++++++++++++++++++
|
||||||
|
units/.gitignore | 1 +
|
||||||
|
units/hybrid-sleep.target | 13 +++++++
|
||||||
|
units/systemd-hybrid-sleep.service.in | 17 +++++++++
|
||||||
|
18 files changed, 264 insertions(+), 45 deletions(-)
|
||||||
|
create mode 100644 src/test/test-sleep.c
|
||||||
|
create mode 100644 units/hybrid-sleep.target
|
||||||
|
create mode 100644 units/systemd-hybrid-sleep.service.in
|
||||||
|
|
||||||
|
Index: systemd-195/Makefile.am
|
||||||
|
===================================================================
|
||||||
|
--- systemd-195.orig/Makefile.am
|
||||||
|
+++ systemd-195/Makefile.am
|
||||||
|
@@ -272,6 +272,7 @@ dist_systemunit_DATA = \
|
||||||
|
units/nss-user-lookup.target \
|
||||||
|
units/mail-transfer-agent.target \
|
||||||
|
units/hibernate.target \
|
||||||
|
+ units/hybrid-sleep.target \
|
||||||
|
units/http-daemon.target \
|
||||||
|
units/poweroff.target \
|
||||||
|
units/reboot.target \
|
||||||
|
@@ -334,6 +335,7 @@ nodist_systemunit_DATA = \
|
||||||
|
units/rescue.service \
|
||||||
|
units/user@.service \
|
||||||
|
units/systemd-hibernate.service \
|
||||||
|
+ units/systemd-hybrid-sleep.service \
|
||||||
|
units/systemd-suspend.service \
|
||||||
|
units/systemd-halt.service \
|
||||||
|
units/systemd-poweroff.service \
|
||||||
|
@@ -384,6 +386,7 @@ EXTRA_DIST += \
|
||||||
|
units/systemd-udev-settle.service \
|
||||||
|
units/debug-shell.service.in \
|
||||||
|
units/systemd-hibernate.service.in \
|
||||||
|
+ units/systemd-hybrid-sleep.service.in \
|
||||||
|
units/systemd-suspend.service.in \
|
||||||
|
units/quotaon.service.in \
|
||||||
|
introspect.awk \
|
||||||
|
@@ -539,6 +542,7 @@ MANPAGES_ALIAS = \
|
||||||
|
man/systemd-shutdownd.socket.8 \
|
||||||
|
man/systemd-shutdownd.8 \
|
||||||
|
man/systemd-hibernate.service.8 \
|
||||||
|
+ man/systemd-hybrid-sleep.service.8 \
|
||||||
|
man/systemd-sleep.8 \
|
||||||
|
man/systemd-shutdown.8 \
|
||||||
|
man/systemd-poweroff.service.8 \
|
||||||
|
@@ -612,6 +616,7 @@ man/systemd-initctl.8: man/systemd-initc
|
||||||
|
man/systemd-shutdownd.socket.8: man/systemd-shutdownd.service.8
|
||||||
|
man/systemd-shutdownd.8: man/systemd-shutdownd.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-sleep.8: man/systemd-suspend.service.8
|
||||||
|
man/systemd-shutdown.8: man/systemd-halt.service.8
|
||||||
|
man/systemd-poweroff.service.8: man/systemd-halt.service.8
|
||||||
|
Index: systemd-195/man/logind.conf.xml
|
||||||
|
===================================================================
|
||||||
|
--- systemd-195.orig/man/logind.conf.xml
|
||||||
|
+++ systemd-195/man/logind.conf.xml
|
||||||
|
@@ -211,8 +211,10 @@
|
||||||
|
<literal>poweroff</literal>,
|
||||||
|
<literal>reboot</literal>,
|
||||||
|
<literal>halt</literal>,
|
||||||
|
- <literal>kexec</literal> and
|
||||||
|
- <literal>hibernate</literal>. If
|
||||||
|
+ <literal>kexec</literal>,
|
||||||
|
+ <literal>suspend</literal>,
|
||||||
|
+ <literal>hibernate</literal>, and
|
||||||
|
+ <literal>hybrid-sleep</literal>. If
|
||||||
|
<literal>ignore</literal> logind will
|
||||||
|
never handle these keys. Otherwise the
|
||||||
|
specified action will be taken in the
|
||||||
|
Index: systemd-195/man/systemctl.xml
|
||||||
|
===================================================================
|
||||||
|
--- systemd-195.orig/man/systemctl.xml
|
||||||
|
+++ systemd-195/man/systemctl.xml
|
||||||
|
@@ -1181,6 +1181,11 @@
|
||||||
|
<listitem><para>Hibernate the system.</para></listitem>
|
||||||
|
</varlistentry>
|
||||||
|
<varlistentry>
|
||||||
|
+ <term><command>hybrid-sleep</command></term>
|
||||||
|
+
|
||||||
|
+ <listitem><para>Hibernate and suspend the system.</para></listitem>
|
||||||
|
+ </varlistentry>
|
||||||
|
+ <varlistentry>
|
||||||
|
<term><command>switch-root [ROOT] [INIT]</command></term>
|
||||||
|
|
||||||
|
<listitem><para>Switches to a
|
||||||
|
Index: systemd-195/man/systemd-suspend.service.xml
|
||||||
|
===================================================================
|
||||||
|
--- systemd-195.orig/man/systemd-suspend.service.xml
|
||||||
|
+++ systemd-195/man/systemd-suspend.service.xml
|
||||||
|
@@ -45,6 +45,7 @@
|
||||||
|
<refnamediv>
|
||||||
|
<refname>systemd-suspend.service</refname>
|
||||||
|
<refname>systemd-hibernate.service</refname>
|
||||||
|
+ <refname>systemd-hybrid-sleep.service</refname>
|
||||||
|
<refname>systemd-sleep</refname>
|
||||||
|
<refpurpose>System sleep state logic</refpurpose>
|
||||||
|
</refnamediv>
|
||||||
|
@@ -52,6 +53,7 @@
|
||||||
|
<refsynopsisdiv>
|
||||||
|
<para><filename>systemd-suspend.service</filename></para>
|
||||||
|
<para><filename>systemd-hibernate.service</filename></para>
|
||||||
|
+ <para><filename>systemd-hybrid-sleep.service</filename></para>
|
||||||
|
<para><filename>/usr/lib/systemd/systemd-sleep</filename></para>
|
||||||
|
</refsynopsisdiv>
|
||||||
|
|
||||||
|
@@ -63,20 +65,26 @@
|
||||||
|
<filename>suspend.target</filename> and is responsible
|
||||||
|
for the actual system suspend. Similar,
|
||||||
|
<filename>systemd-hibernate.service</filename> is
|
||||||
|
- pulled in by <filename>hibernate.target</filename> to
|
||||||
|
- executed the actual hibernation.</para>
|
||||||
|
-
|
||||||
|
- <para>Immediately before entering system suspend and
|
||||||
|
- hibernation
|
||||||
|
- <filename>systemd-suspend.service</filename> will run
|
||||||
|
- all executables in
|
||||||
|
+ pulled in by <filename>hibernate.target</filename> to
|
||||||
|
+ execute the actual hibernation. Finally,
|
||||||
|
+ <filename>systemd-hybrid-sleep.service</filename> is
|
||||||
|
+ pulled in by <filename>hybrid-sleep.target</filename>
|
||||||
|
+ to execute hybrid hibernation with system
|
||||||
|
+ suspend.</para>
|
||||||
|
+
|
||||||
|
+ <para>Immediately before entering system suspend
|
||||||
|
+ and/or hibernation
|
||||||
|
+ <filename>systemd-suspend.service</filename> (and the
|
||||||
|
+ other mentioned units, respectively) will run all
|
||||||
|
+ executables in
|
||||||
|
<filename>/usr/lib/systemd/system-sleep/</filename>
|
||||||
|
and pass two arguments to them. The first argument
|
||||||
|
will be "<literal>pre</literal>", the second either
|
||||||
|
- "<literal>suspend</literal>" or
|
||||||
|
- "<literal>hibernate</literal>", depending on the
|
||||||
|
+ "<literal>suspend</literal>",
|
||||||
|
+ "<literal>hibernate</literal>", or
|
||||||
|
+ "<literal>hybrid-sleep</literal>" depending on the
|
||||||
|
chosen action. Immediately after leaving system
|
||||||
|
- suspend and hibernation the same executables are run,
|
||||||
|
+ suspend and/or hibernation the same executables are run,
|
||||||
|
but the first argument is now
|
||||||
|
"<literal>post</literal>". All executables in this
|
||||||
|
directory are executed in parallel, and execution of
|
||||||
|
@@ -87,15 +95,17 @@
|
||||||
|
<filename>/usr/lib/systemd/system-sleep/</filename>
|
||||||
|
are intended for local use only and should be
|
||||||
|
considered hacks. If applications want to be notified
|
||||||
|
- of system suspend and resume there are much nicer
|
||||||
|
- interfaces available.</para>
|
||||||
|
+ of system suspend/hibernation and resume there are
|
||||||
|
+ much nicer interfaces available.</para>
|
||||||
|
|
||||||
|
<para>Note that
|
||||||
|
- <filename>systemd-suspend.service</filename> and
|
||||||
|
- <filename>systemd-hibernate.service</filename> should
|
||||||
|
- never be executed directly. Instead, trigger system
|
||||||
|
- sleep states with a command such as "<literal>systemctl
|
||||||
|
- suspend</literal>" or suchlike.</para>
|
||||||
|
+ <filename>systemd-suspend.service</filename>,
|
||||||
|
+ <filename>systemd-hibernate.service</filename> and
|
||||||
|
+ <filename>systemd-hybrid-sleep.service</filename>
|
||||||
|
+ should never be executed directly. Instead, trigger
|
||||||
|
+ system sleep states with a command such as
|
||||||
|
+ "<literal>systemctl suspend</literal>" or
|
||||||
|
+ similar.</para>
|
||||||
|
</refsect1>
|
||||||
|
|
||||||
|
<refsect1>
|
||||||
|
Index: systemd-195/man/systemd.special.xml
|
||||||
|
===================================================================
|
||||||
|
--- systemd-195.orig/man/systemd.special.xml
|
||||||
|
+++ systemd-195/man/systemd.special.xml
|
||||||
|
@@ -63,6 +63,7 @@
|
||||||
|
<filename>graphical.target</filename>,
|
||||||
|
<filename>hibernate.target</filename>,
|
||||||
|
<filename>http-daemon.target</filename>,
|
||||||
|
+ <filename>hybrid-sleep.target</filename>,
|
||||||
|
<filename>halt.target</filename>,
|
||||||
|
<filename>kbrequest.target</filename>,
|
||||||
|
<filename>kexec.target</filename>,
|
||||||
|
@@ -303,6 +304,15 @@
|
||||||
|
</listitem>
|
||||||
|
</varlistentry>
|
||||||
|
<varlistentry>
|
||||||
|
+ <term><filename>hybrid-sleep.target</filename></term>
|
||||||
|
+ <listitem>
|
||||||
|
+ <para>A special target unit
|
||||||
|
+ for hibernating and suspending the
|
||||||
|
+ system at the same time. This pulls in
|
||||||
|
+ <filename>sleep.target</filename>.</para>
|
||||||
|
+ </listitem>
|
||||||
|
+ </varlistentry>
|
||||||
|
+ <varlistentry>
|
||||||
|
<term><filename>halt.target</filename></term>
|
||||||
|
<listitem>
|
||||||
|
<para>A special target unit
|
||||||
|
@@ -652,9 +662,8 @@
|
||||||
|
<listitem>
|
||||||
|
<para>A special target unit
|
||||||
|
that is pulled in by
|
||||||
|
- <filename>suspend.target</filename>
|
||||||
|
- and
|
||||||
|
- <filename>hibernate.target</filename>
|
||||||
|
+ <filename>suspend.target</filename>,
|
||||||
|
+ <filename>hibernate.target</filename> and <filename>hybrid-sleep.target</filename>
|
||||||
|
and may be used to hook units
|
||||||
|
into the sleep state
|
||||||
|
logic.</para>
|
||||||
|
Index: systemd-195/src/core/special.h
|
||||||
|
===================================================================
|
||||||
|
--- systemd-195.orig/src/core/special.h
|
||||||
|
+++ systemd-195/src/core/special.h
|
||||||
|
@@ -37,6 +37,7 @@
|
||||||
|
#define SPECIAL_EXIT_TARGET "exit.target"
|
||||||
|
#define SPECIAL_SUSPEND_TARGET "suspend.target"
|
||||||
|
#define SPECIAL_HIBERNATE_TARGET "hibernate.target"
|
||||||
|
+#define SPECIAL_HYBRID_SLEEP_TARGET "hybrid-sleep.target"
|
||||||
|
|
||||||
|
/* Special boot targets */
|
||||||
|
#define SPECIAL_RESCUE_TARGET "rescue.target"
|
||||||
|
Index: systemd-195/src/login/logind-button.c
|
||||||
|
===================================================================
|
||||||
|
--- systemd-195.orig/src/login/logind-button.c
|
||||||
|
+++ systemd-195/src/login/logind-button.c
|
||||||
|
@@ -163,16 +163,18 @@ static int button_handle(
|
||||||
|
[HANDLE_HALT] = "Halting...",
|
||||||
|
[HANDLE_KEXEC] = "Rebooting via kexec...",
|
||||||
|
[HANDLE_SUSPEND] = "Suspending...",
|
||||||
|
- [HANDLE_HIBERNATE] = "Hibernating..."
|
||||||
|
+ [HANDLE_HIBERNATE] = "Hibernating...",
|
||||||
|
+ [HANDLE_HYBRID_SLEEP] = "Hibernating and suspend...",
|
||||||
|
};
|
||||||
|
|
||||||
|
static const char * const target_table[_HANDLE_BUTTON_MAX] = {
|
||||||
|
- [HANDLE_POWEROFF] = "poweroff.target",
|
||||||
|
- [HANDLE_REBOOT] = "reboot.target",
|
||||||
|
- [HANDLE_HALT] = "halt.target",
|
||||||
|
- [HANDLE_KEXEC] = "kexec.target",
|
||||||
|
- [HANDLE_SUSPEND] = "suspend.target",
|
||||||
|
- [HANDLE_HIBERNATE] = "hibernate.target"
|
||||||
|
+ [HANDLE_POWEROFF] = SPECIAL_POWEROFF_TARGET,
|
||||||
|
+ [HANDLE_REBOOT] = SPECIAL_REBOOT_TARGET,
|
||||||
|
+ [HANDLE_HALT] = SPECIAL_HALT_TARGET,
|
||||||
|
+ [HANDLE_KEXEC] = SPECIAL_KEXEC_TARGET,
|
||||||
|
+ [HANDLE_SUSPEND] = SPECIAL_SUSPEND_TARGET,
|
||||||
|
+ [HANDLE_HIBERNATE] = SPECIAL_HIBERNATE_TARGET,
|
||||||
|
+ [HANDLE_HYBRID_SLEEP] = SPECIAL_HYBRID_SLEEP_TARGET
|
||||||
|
};
|
||||||
|
|
||||||
|
DBusError error;
|
||||||
|
@@ -193,7 +195,7 @@ static int button_handle(
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
- inhibit_operation = handle == HANDLE_SUSPEND || handle == HANDLE_HIBERNATE ? INHIBIT_SLEEP : INHIBIT_SHUTDOWN;
|
||||||
|
+ inhibit_operation = handle == HANDLE_SUSPEND || handle == HANDLE_HIBERNATE || handle == HANDLE_HYBRID_SLEEP ? INHIBIT_SLEEP : INHIBIT_SHUTDOWN;
|
||||||
|
|
||||||
|
/* If the actual operation is inhibited, warn and fail */
|
||||||
|
if (!ignore_inhibited &&
|
||||||
|
@@ -305,7 +307,8 @@ static const char* const handle_button_t
|
||||||
|
[HANDLE_HALT] = "halt",
|
||||||
|
[HANDLE_KEXEC] = "kexec",
|
||||||
|
[HANDLE_SUSPEND] = "suspend",
|
||||||
|
- [HANDLE_HIBERNATE] = "hibernate"
|
||||||
|
+ [HANDLE_HIBERNATE] = "hibernate",
|
||||||
|
+ [HANDLE_HYBRID_SLEEP] = "hybrid-sleep",
|
||||||
|
};
|
||||||
|
DEFINE_STRING_TABLE_LOOKUP(handle_button, HandleButton);
|
||||||
|
DEFINE_CONFIG_PARSE_ENUM(config_parse_handle_button, handle_button, HandleButton, "Failed to parse handle button setting");
|
||||||
|
Index: systemd-195/src/login/logind-button.h
|
||||||
|
===================================================================
|
||||||
|
--- systemd-195.orig/src/login/logind-button.h
|
||||||
|
+++ systemd-195/src/login/logind-button.h
|
||||||
|
@@ -32,6 +32,7 @@ typedef enum HandleButton {
|
||||||
|
HANDLE_KEXEC,
|
||||||
|
HANDLE_SUSPEND,
|
||||||
|
HANDLE_HIBERNATE,
|
||||||
|
+ HANDLE_HYBRID_SLEEP,
|
||||||
|
_HANDLE_BUTTON_MAX,
|
||||||
|
_HANDLE_BUTTON_INVALID = -1
|
||||||
|
} HandleButton;
|
||||||
|
Index: systemd-195/src/login/logind-dbus.c
|
||||||
|
===================================================================
|
||||||
|
--- systemd-195.orig/src/login/logind-dbus.c
|
||||||
|
+++ systemd-195/src/login/logind-dbus.c
|
||||||
|
@@ -145,6 +145,9 @@
|
||||||
|
" <method name=\"Hibernate\">\n" \
|
||||||
|
" <arg name=\"interactive\" type=\"b\" direction=\"in\"/>\n" \
|
||||||
|
" </method>\n" \
|
||||||
|
+ " <method name=\"HybridSleep\">\n" \
|
||||||
|
+ " <arg name=\"interactive\" type=\"b\" direction=\"in\"/>\n" \
|
||||||
|
+ " </method>\n" \
|
||||||
|
" <method name=\"CanPowerOff\">\n" \
|
||||||
|
" <arg name=\"result\" type=\"s\" direction=\"out\"/>\n" \
|
||||||
|
" </method>\n" \
|
||||||
|
@@ -157,6 +160,9 @@
|
||||||
|
" <method name=\"CanHibernate\">\n" \
|
||||||
|
" <arg name=\"result\" type=\"s\" direction=\"out\"/>\n" \
|
||||||
|
" </method>\n" \
|
||||||
|
+ " <method name=\"CanHybridSleep\">\n" \
|
||||||
|
+ " <arg name=\"result\" type=\"s\" direction=\"out\"/>\n" \
|
||||||
|
+ " </method>\n" \
|
||||||
|
" <method name=\"Inhibit\">\n" \
|
||||||
|
" <arg name=\"what\" type=\"s\" direction=\"in\"/>\n" \
|
||||||
|
" <arg name=\"who\" type=\"s\" direction=\"in\"/>\n" \
|
||||||
|
@@ -1056,6 +1062,7 @@ static int bus_manager_can_shutdown_or_s
|
||||||
|
const char *action_multiple_sessions,
|
||||||
|
const char *action_ignore_inhibit,
|
||||||
|
const char *sleep_type,
|
||||||
|
+ const char *sleep_disk_type,
|
||||||
|
DBusError *error,
|
||||||
|
DBusMessage **_reply) {
|
||||||
|
|
||||||
|
@@ -1087,6 +1094,17 @@ static int bus_manager_can_shutdown_or_s
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
+ if (sleep_disk_type) {
|
||||||
|
+ r = can_sleep_disk(sleep_disk_type);
|
||||||
|
+ if (r < 0)
|
||||||
|
+ return r;
|
||||||
|
+
|
||||||
|
+ if (r == 0) {
|
||||||
|
+ result = "na";
|
||||||
|
+ goto finish;
|
||||||
|
+ }
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
ul = dbus_bus_get_unix_user(connection, dbus_message_get_sender(message), error);
|
||||||
|
if (ul == (unsigned long) -1)
|
||||||
|
return -EIO;
|
||||||
|
@@ -1236,6 +1254,7 @@ static int bus_manager_do_shutdown_or_sl
|
||||||
|
const char *action_multiple_sessions,
|
||||||
|
const char *action_ignore_inhibit,
|
||||||
|
const char *sleep_type,
|
||||||
|
+ const char *sleep_disk_type,
|
||||||
|
DBusError *error,
|
||||||
|
DBusMessage **_reply) {
|
||||||
|
|
||||||
|
@@ -1273,6 +1292,15 @@ static int bus_manager_do_shutdown_or_sl
|
||||||
|
return -ENOTSUP;
|
||||||
|
}
|
||||||
|
|
||||||
|
+ if (sleep_disk_type) {
|
||||||
|
+ r = can_sleep_disk(sleep_disk_type);
|
||||||
|
+ if (r < 0)
|
||||||
|
+ return r;
|
||||||
|
+
|
||||||
|
+ if (r == 0)
|
||||||
|
+ return -ENOTSUP;
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
ul = dbus_bus_get_unix_user(connection, dbus_message_get_sender(message), error);
|
||||||
|
if (ul == (unsigned long) -1)
|
||||||
|
return -EIO;
|
||||||
|
@@ -2067,7 +2095,7 @@ static DBusHandlerResult manager_message
|
||||||
|
"org.freedesktop.login1.power-off",
|
||||||
|
"org.freedesktop.login1.power-off-multiple-sessions",
|
||||||
|
"org.freedesktop.login1.power-off-ignore-inhibit",
|
||||||
|
- NULL,
|
||||||
|
+ NULL, NULL,
|
||||||
|
&error, &reply);
|
||||||
|
if (r < 0)
|
||||||
|
return bus_send_error_reply(connection, message, &error, r);
|
||||||
|
@@ -2079,7 +2107,7 @@ static DBusHandlerResult manager_message
|
||||||
|
"org.freedesktop.login1.reboot",
|
||||||
|
"org.freedesktop.login1.reboot-multiple-sessions",
|
||||||
|
"org.freedesktop.login1.reboot-ignore-inhibit",
|
||||||
|
- NULL,
|
||||||
|
+ NULL, NULL,
|
||||||
|
&error, &reply);
|
||||||
|
if (r < 0)
|
||||||
|
return bus_send_error_reply(connection, message, &error, r);
|
||||||
|
@@ -2092,7 +2120,7 @@ static DBusHandlerResult manager_message
|
||||||
|
"org.freedesktop.login1.suspend",
|
||||||
|
"org.freedesktop.login1.suspend-multiple-sessions",
|
||||||
|
"org.freedesktop.login1.suspend-ignore-inhibit",
|
||||||
|
- "mem",
|
||||||
|
+ "mem", NULL,
|
||||||
|
&error, &reply);
|
||||||
|
if (r < 0)
|
||||||
|
return bus_send_error_reply(connection, message, &error, r);
|
||||||
|
@@ -2104,7 +2132,20 @@ static DBusHandlerResult manager_message
|
||||||
|
"org.freedesktop.login1.hibernate",
|
||||||
|
"org.freedesktop.login1.hibernate-multiple-sessions",
|
||||||
|
"org.freedesktop.login1.hibernate-ignore-inhibit",
|
||||||
|
- "disk",
|
||||||
|
+ "disk", NULL,
|
||||||
|
+ &error, &reply);
|
||||||
|
+ if (r < 0)
|
||||||
|
+ return bus_send_error_reply(connection, message, &error, r);
|
||||||
|
+
|
||||||
|
+ } else if (dbus_message_is_method_call(message, "org.freedesktop.login1.Manager", "HybridSleep")) {
|
||||||
|
+ r = bus_manager_do_shutdown_or_sleep(
|
||||||
|
+ m, connection, message,
|
||||||
|
+ SPECIAL_HYBRID_SLEEP_TARGET,
|
||||||
|
+ INHIBIT_SLEEP,
|
||||||
|
+ "org.freedesktop.login1.hibernate",
|
||||||
|
+ "org.freedesktop.login1.hibernate-multiple-sessions",
|
||||||
|
+ "org.freedesktop.login1.hibernate-ignore-inhibit",
|
||||||
|
+ "disk", "suspend",
|
||||||
|
&error, &reply);
|
||||||
|
if (r < 0)
|
||||||
|
return bus_send_error_reply(connection, message, &error, r);
|
||||||
|
@@ -2117,7 +2158,7 @@ static DBusHandlerResult manager_message
|
||||||
|
"org.freedesktop.login1.power-off",
|
||||||
|
"org.freedesktop.login1.power-off-multiple-sessions",
|
||||||
|
"org.freedesktop.login1.power-off-ignore-inhibit",
|
||||||
|
- NULL,
|
||||||
|
+ NULL, NULL,
|
||||||
|
&error, &reply);
|
||||||
|
if (r < 0)
|
||||||
|
return bus_send_error_reply(connection, message, &error, r);
|
||||||
|
@@ -2128,7 +2169,7 @@ static DBusHandlerResult manager_message
|
||||||
|
"org.freedesktop.login1.reboot",
|
||||||
|
"org.freedesktop.login1.reboot-multiple-sessions",
|
||||||
|
"org.freedesktop.login1.reboot-ignore-inhibit",
|
||||||
|
- NULL,
|
||||||
|
+ NULL, NULL,
|
||||||
|
&error, &reply);
|
||||||
|
if (r < 0)
|
||||||
|
return bus_send_error_reply(connection, message, &error, r);
|
||||||
|
@@ -2140,7 +2181,7 @@ static DBusHandlerResult manager_message
|
||||||
|
"org.freedesktop.login1.suspend",
|
||||||
|
"org.freedesktop.login1.suspend-multiple-sessions",
|
||||||
|
"org.freedesktop.login1.suspend-ignore-inhibit",
|
||||||
|
- "mem",
|
||||||
|
+ "mem", NULL,
|
||||||
|
&error, &reply);
|
||||||
|
if (r < 0)
|
||||||
|
return bus_send_error_reply(connection, message, &error, r);
|
||||||
|
@@ -2152,7 +2193,19 @@ static DBusHandlerResult manager_message
|
||||||
|
"org.freedesktop.login1.hibernate",
|
||||||
|
"org.freedesktop.login1.hibernate-multiple-sessions",
|
||||||
|
"org.freedesktop.login1.hibernate-ignore-inhibit",
|
||||||
|
- "disk",
|
||||||
|
+ "disk", NULL,
|
||||||
|
+ &error, &reply);
|
||||||
|
+ if (r < 0)
|
||||||
|
+ return bus_send_error_reply(connection, message, &error, r);
|
||||||
|
+
|
||||||
|
+ } else if (dbus_message_is_method_call(message, "org.freedesktop.login1.Manager", "CanHybridSleep")) {
|
||||||
|
+ r = bus_manager_can_shutdown_or_sleep(
|
||||||
|
+ m, connection, message,
|
||||||
|
+ INHIBIT_SLEEP,
|
||||||
|
+ "org.freedesktop.login1.hibernate",
|
||||||
|
+ "org.freedesktop.login1.hibernate-multiple-sessions",
|
||||||
|
+ "org.freedesktop.login1.hibernate-ignore-inhibit",
|
||||||
|
+ "disk", "suspend",
|
||||||
|
&error, &reply);
|
||||||
|
if (r < 0)
|
||||||
|
return bus_send_error_reply(connection, message, &error, r);
|
||||||
|
Index: systemd-195/src/shared/util.c
|
||||||
|
===================================================================
|
||||||
|
--- systemd-195.orig/src/shared/util.c
|
||||||
|
+++ systemd-195/src/shared/util.c
|
||||||
|
@@ -5726,6 +5726,30 @@ int can_sleep(const char *type) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
+int can_sleep_disk(const char *type) {
|
||||||
|
+ char *w, *state;
|
||||||
|
+ size_t l, k;
|
||||||
|
+ int r;
|
||||||
|
+ _cleanup_free_ char *p = NULL;
|
||||||
|
+
|
||||||
|
+ assert(type);
|
||||||
|
+
|
||||||
|
+ r = read_one_line_file("/sys/power/disk", &p);
|
||||||
|
+ if (r < 0)
|
||||||
|
+ return r == -ENOENT ? 0 : r;
|
||||||
|
+
|
||||||
|
+ k = strlen(type);
|
||||||
|
+ FOREACH_WORD_SEPARATOR(w, l, p, WHITESPACE, state) {
|
||||||
|
+ if (l == k && memcmp(w, type, l) == 0)
|
||||||
|
+ return true;
|
||||||
|
+
|
||||||
|
+ if (l == k + 2 && w[0] == '[' && memcmp(w + 1, type, l - 2) == 0 && w[l-1] == ']')
|
||||||
|
+ return true;
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ return false;
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
bool is_valid_documentation_url(const char *url) {
|
||||||
|
assert(url);
|
||||||
|
|
||||||
|
Index: systemd-195/src/shared/util.h
|
||||||
|
===================================================================
|
||||||
|
--- systemd-195.orig/src/shared/util.h
|
||||||
|
+++ systemd-195/src/shared/util.h
|
||||||
|
@@ -531,6 +531,7 @@ int setrlimit_closest(int resource, cons
|
||||||
|
int getenv_for_pid(pid_t pid, const char *field, char **_value);
|
||||||
|
|
||||||
|
int can_sleep(const char *type);
|
||||||
|
+int can_sleep_disk(const char *type);
|
||||||
|
|
||||||
|
bool is_valid_documentation_url(const char *url);
|
||||||
|
|
||||||
|
Index: systemd-195/src/sleep/sleep.c
|
||||||
|
===================================================================
|
||||||
|
--- systemd-195.orig/src/sleep/sleep.c
|
||||||
|
+++ systemd-195/src/sleep/sleep.c
|
||||||
|
@@ -46,7 +46,7 @@ int main(int argc, char *argv[]) {
|
||||||
|
|
||||||
|
if (streq(argv[1], "suspend"))
|
||||||
|
verb = "mem";
|
||||||
|
- else if (streq(argv[1], "hibernate"))
|
||||||
|
+ else if (streq(argv[1], "hibernate") || streq(argv[1], "hybrid-sleep"))
|
||||||
|
verb = "disk";
|
||||||
|
else {
|
||||||
|
log_error("Unknown action '%s'.", argv[1]);
|
||||||
|
@@ -54,6 +54,16 @@ int main(int argc, char *argv[]) {
|
||||||
|
goto finish;
|
||||||
|
}
|
||||||
|
|
||||||
|
+ /* Configure the hibernation mode */
|
||||||
|
+ if (streq(argv[1], "hibernate")) {
|
||||||
|
+ if (write_one_line_file("/sys/power/disk", "platform") < 0)
|
||||||
|
+ write_one_line_file("/sys/power/disk", "shutdown");
|
||||||
|
+ } else if (streq(argv[1], "hybrid-sleep")) {
|
||||||
|
+ if (write_one_line_file("/sys/power/disk", "suspend") < 0)
|
||||||
|
+ if (write_one_line_file("/sys/power/disk", "platform") < 0)
|
||||||
|
+ write_one_line_file("/sys/power/disk", "shutdown");
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
f = fopen("/sys/power/state", "we");
|
||||||
|
if (!f) {
|
||||||
|
log_error("Failed to open /sys/power/state: %m");
|
||||||
|
@@ -73,12 +83,18 @@ int main(int argc, char *argv[]) {
|
||||||
|
"MESSAGE=Suspending system...",
|
||||||
|
"SLEEP=suspend",
|
||||||
|
NULL);
|
||||||
|
- else
|
||||||
|
+ else if (streq(argv[1], "hibernate"))
|
||||||
|
log_struct(LOG_INFO,
|
||||||
|
MESSAGE_ID(SD_MESSAGE_SLEEP_START),
|
||||||
|
"MESSAGE=Hibernating system...",
|
||||||
|
"SLEEP=hibernate",
|
||||||
|
NULL);
|
||||||
|
+ else
|
||||||
|
+ log_struct(LOG_INFO,
|
||||||
|
+ MESSAGE_ID(SD_MESSAGE_SLEEP_START),
|
||||||
|
+ "MESSAGE=Hibernating and suspending system...",
|
||||||
|
+ "SLEEP=hybrid-sleep",
|
||||||
|
+ NULL);
|
||||||
|
|
||||||
|
fputs(verb, f);
|
||||||
|
fputc('\n', f);
|
||||||
|
Index: systemd-195/src/systemctl/systemctl.c
|
||||||
|
===================================================================
|
||||||
|
--- systemd-195.orig/src/systemctl/systemctl.c
|
||||||
|
+++ systemd-195/src/systemctl/systemctl.c
|
||||||
|
@@ -99,6 +99,7 @@ static enum action {
|
||||||
|
ACTION_EXIT,
|
||||||
|
ACTION_SUSPEND,
|
||||||
|
ACTION_HIBERNATE,
|
||||||
|
+ ACTION_HYBRID_SLEEP,
|
||||||
|
ACTION_RUNLEVEL2,
|
||||||
|
ACTION_RUNLEVEL3,
|
||||||
|
ACTION_RUNLEVEL4,
|
||||||
|
@@ -1608,6 +1609,8 @@ static enum action verb_to_action(const
|
||||||
|
return ACTION_SUSPEND;
|
||||||
|
else if (streq(verb, "hibernate"))
|
||||||
|
return ACTION_HIBERNATE;
|
||||||
|
+ else if (streq(verb, "hybrid-sleep"))
|
||||||
|
+ return ACTION_HYBRID_SLEEP;
|
||||||
|
else
|
||||||
|
return ACTION_INVALID;
|
||||||
|
}
|
||||||
|
@@ -1628,7 +1631,8 @@ static int start_unit(DBusConnection *bu
|
||||||
|
[ACTION_DEFAULT] = SPECIAL_DEFAULT_TARGET,
|
||||||
|
[ACTION_EXIT] = SPECIAL_EXIT_TARGET,
|
||||||
|
[ACTION_SUSPEND] = SPECIAL_SUSPEND_TARGET,
|
||||||
|
- [ACTION_HIBERNATE] = SPECIAL_HIBERNATE_TARGET
|
||||||
|
+ [ACTION_HIBERNATE] = SPECIAL_HIBERNATE_TARGET,
|
||||||
|
+ [ACTION_HYBRID_SLEEP] = SPECIAL_HYBRID_SLEEP_TARGET
|
||||||
|
};
|
||||||
|
|
||||||
|
int r, ret = 0;
|
||||||
|
@@ -1767,6 +1771,10 @@ static int reboot_with_logind(DBusConnec
|
||||||
|
method = "Hibernate";
|
||||||
|
break;
|
||||||
|
|
||||||
|
+ case ACTION_HYBRID_SLEEP:
|
||||||
|
+ method = "HybridSleep";
|
||||||
|
+ break;
|
||||||
|
+
|
||||||
|
default:
|
||||||
|
return -EINVAL;
|
||||||
|
}
|
||||||
|
@@ -1818,7 +1826,8 @@ static int start_special(DBusConnection
|
||||||
|
(a == ACTION_POWEROFF ||
|
||||||
|
a == ACTION_REBOOT ||
|
||||||
|
a == ACTION_SUSPEND ||
|
||||||
|
- a == ACTION_HIBERNATE)) {
|
||||||
|
+ a == ACTION_HIBERNATE ||
|
||||||
|
+ a == ACTION_HYBRID_SLEEP)) {
|
||||||
|
r = reboot_with_logind(bus, a);
|
||||||
|
if (r >= 0)
|
||||||
|
return r;
|
||||||
|
@@ -3999,7 +4008,8 @@ static int systemctl_help(void) {
|
||||||
|
" exit Request user instance exit\n"
|
||||||
|
" switch-root [ROOT] [INIT] Change to a different root file system\n"
|
||||||
|
" suspend Suspend the system\n"
|
||||||
|
- " hibernate Hibernate the system\n",
|
||||||
|
+ " hibernate Hibernate the system\n"
|
||||||
|
+ " hybrid-sleep Hibernate and suspend the system\n",
|
||||||
|
program_invocation_short_name);
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
@@ -4931,6 +4941,7 @@ static int systemctl_main(DBusConnection
|
||||||
|
{ "kexec", EQUAL, 1, start_special },
|
||||||
|
{ "suspend", EQUAL, 1, start_special },
|
||||||
|
{ "hibernate", EQUAL, 1, start_special },
|
||||||
|
+ { "hybrid-sleep", EQUAL, 1, start_special },
|
||||||
|
{ "default", EQUAL, 1, start_special },
|
||||||
|
{ "rescue", EQUAL, 1, start_special },
|
||||||
|
{ "emergency", EQUAL, 1, start_special },
|
||||||
|
Index: systemd-195/units/hybrid-sleep.target
|
||||||
|
===================================================================
|
||||||
|
--- /dev/null
|
||||||
|
+++ systemd-195/units/hybrid-sleep.target
|
||||||
|
@@ -0,0 +1,13 @@
|
||||||
|
+# 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=Hybrid Suspend+Hibernate
|
||||||
|
+Documentation=man:systemd.special(7)
|
||||||
|
+DefaultDependencies=no
|
||||||
|
+BindsTo=systemd-hybrid-sleep.service
|
||||||
|
+After=systemd-hybrid-sleep.service
|
||||||
|
Index: systemd-195/units/systemd-hybrid-sleep.service.in
|
||||||
|
===================================================================
|
||||||
|
--- /dev/null
|
||||||
|
+++ systemd-195/units/systemd-hybrid-sleep.service.in
|
||||||
|
@@ -0,0 +1,17 @@
|
||||||
|
+# 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=Hybrid Suspend+Hibernate
|
||||||
|
+Documentation=man:systemd-suspend.service(8)
|
||||||
|
+DefaultDependencies=no
|
||||||
|
+Requires=sleep.target
|
||||||
|
+After=sleep.target
|
||||||
|
+
|
||||||
|
+[Service]
|
||||||
|
+Type=oneshot
|
||||||
|
+ExecStart=@rootlibexecdir@/systemd-sleep hybrid-sleep
|
@ -1,3 +1,14 @@
|
|||||||
|
-------------------------------------------------------------------
|
||||||
|
Tue Feb 19 11:20:31 CET 2013 - fcrozat@suse.com
|
||||||
|
|
||||||
|
- Ensure journal is flushed on disk when systemd-logger is
|
||||||
|
installed for the first time.
|
||||||
|
- Add improve-journal-perf.patch: improve journal performance on
|
||||||
|
query.
|
||||||
|
- Add support-hybrid-suspend.patch: add support for hybrid suspend.
|
||||||
|
- Add forward-to-pmutils.patch: forward suspend/hibernation calls
|
||||||
|
to pm-utils, if installed (bnc#790157).
|
||||||
|
|
||||||
-------------------------------------------------------------------
|
-------------------------------------------------------------------
|
||||||
Tue Feb 19 09:51:18 UTC 2013 - rmilasan@suse.com
|
Tue Feb 19 09:51:18 UTC 2013 - rmilasan@suse.com
|
||||||
|
|
||||||
|
@ -274,6 +274,12 @@ Patch129: handle-HOSTNAME.patch
|
|||||||
Patch130: systemctl-print-wall-on-if-successful.patch
|
Patch130: systemctl-print-wall-on-if-successful.patch
|
||||||
# PATCH-FIX-UPSTREAM improve-bash-completion.patch fcrozat@suse.com -- improve bash completion
|
# PATCH-FIX-UPSTREAM improve-bash-completion.patch fcrozat@suse.com -- improve bash completion
|
||||||
Patch131: improve-bash-completion.patch
|
Patch131: improve-bash-completion.patch
|
||||||
|
# PATCH-FIX-UPSTREAM improve-journal-perf.patch fcrozat@suse.com -- improve journal performance
|
||||||
|
Patch132: improve-journal-perf.patch
|
||||||
|
# PATCH-FIX-UPSTREAM support-hybrid-suspend.patch fcrozat@suse.com -- support hybrid suspend
|
||||||
|
Patch133: support-hybrid-suspend.patch
|
||||||
|
# PATCH-FIX-OPENSUSE forward-to-pmutils.patch fcrozat@suse.com bnc#790157 -- forward to pm-utils
|
||||||
|
Patch134: forward-to-pmutils.patch
|
||||||
|
|
||||||
# udev patches
|
# udev patches
|
||||||
# PATCH-FIX-OPENSUSE 1001-Reinstate-TIMEOUT-handling.patch
|
# PATCH-FIX-OPENSUSE 1001-Reinstate-TIMEOUT-handling.patch
|
||||||
@ -606,9 +612,15 @@ cp %{SOURCE7} m4/
|
|||||||
%patch129 -p1
|
%patch129 -p1
|
||||||
%patch130 -p1
|
%patch130 -p1
|
||||||
%patch131 -p1
|
%patch131 -p1
|
||||||
|
%patch132 -p1
|
||||||
|
%patch133 -p1
|
||||||
|
%patch134 -p1
|
||||||
|
|
||||||
%build
|
%build
|
||||||
autoreconf -fiv
|
autoreconf -fiv
|
||||||
|
# to remove after upgrading to systemd 196+
|
||||||
|
rm -f man/{systemd.exec.5,logind.conf.5,systemctl.1,systemd-suspend.service.8,systemd.special.7,tmpfiles.d.5}
|
||||||
|
|
||||||
# prevent pre-generated and distributed files from re-building
|
# prevent pre-generated and distributed files from re-building
|
||||||
find . -name "*.[1-8]" -exec touch '{}' '+';
|
find . -name "*.[1-8]" -exec touch '{}' '+';
|
||||||
export V=1
|
export V=1
|
||||||
@ -878,6 +890,13 @@ fi
|
|||||||
%post -n libgudev-1_0-0 -p /sbin/ldconfig
|
%post -n libgudev-1_0-0 -p /sbin/ldconfig
|
||||||
|
|
||||||
%postun -n libgudev-1_0-0 -p /sbin/ldconfig
|
%postun -n libgudev-1_0-0 -p /sbin/ldconfig
|
||||||
|
|
||||||
|
%post logger
|
||||||
|
if [ "$1" -eq 1 ]; then
|
||||||
|
# tell journal to start logging on disk if directory didn't exist before
|
||||||
|
systemctl --no-block restart systemd-journal-flush.service >/dev/null 2>&1 || :
|
||||||
|
fi
|
||||||
|
|
||||||
%endif
|
%endif
|
||||||
|
|
||||||
%clean
|
%clean
|
||||||
|
@ -1,3 +1,14 @@
|
|||||||
|
-------------------------------------------------------------------
|
||||||
|
Tue Feb 19 11:20:31 CET 2013 - fcrozat@suse.com
|
||||||
|
|
||||||
|
- Ensure journal is flushed on disk when systemd-logger is
|
||||||
|
installed for the first time.
|
||||||
|
- Add improve-journal-perf.patch: improve journal performance on
|
||||||
|
query.
|
||||||
|
- Add support-hybrid-suspend.patch: add support for hybrid suspend.
|
||||||
|
- Add forward-to-pmutils.patch: forward suspend/hibernation calls
|
||||||
|
to pm-utils, if installed (bnc#790157).
|
||||||
|
|
||||||
-------------------------------------------------------------------
|
-------------------------------------------------------------------
|
||||||
Tue Feb 19 09:51:18 UTC 2013 - rmilasan@suse.com
|
Tue Feb 19 09:51:18 UTC 2013 - rmilasan@suse.com
|
||||||
|
|
||||||
|
19
systemd.spec
19
systemd.spec
@ -269,6 +269,12 @@ Patch129: handle-HOSTNAME.patch
|
|||||||
Patch130: systemctl-print-wall-on-if-successful.patch
|
Patch130: systemctl-print-wall-on-if-successful.patch
|
||||||
# PATCH-FIX-UPSTREAM improve-bash-completion.patch fcrozat@suse.com -- improve bash completion
|
# PATCH-FIX-UPSTREAM improve-bash-completion.patch fcrozat@suse.com -- improve bash completion
|
||||||
Patch131: improve-bash-completion.patch
|
Patch131: improve-bash-completion.patch
|
||||||
|
# PATCH-FIX-UPSTREAM improve-journal-perf.patch fcrozat@suse.com -- improve journal performance
|
||||||
|
Patch132: improve-journal-perf.patch
|
||||||
|
# PATCH-FIX-UPSTREAM support-hybrid-suspend.patch fcrozat@suse.com -- support hybrid suspend
|
||||||
|
Patch133: support-hybrid-suspend.patch
|
||||||
|
# PATCH-FIX-OPENSUSE forward-to-pmutils.patch fcrozat@suse.com bnc#790157 -- forward to pm-utils
|
||||||
|
Patch134: forward-to-pmutils.patch
|
||||||
|
|
||||||
# udev patches
|
# udev patches
|
||||||
# PATCH-FIX-OPENSUSE 1001-Reinstate-TIMEOUT-handling.patch
|
# PATCH-FIX-OPENSUSE 1001-Reinstate-TIMEOUT-handling.patch
|
||||||
@ -601,9 +607,15 @@ cp %{SOURCE7} m4/
|
|||||||
%patch129 -p1
|
%patch129 -p1
|
||||||
%patch130 -p1
|
%patch130 -p1
|
||||||
%patch131 -p1
|
%patch131 -p1
|
||||||
|
%patch132 -p1
|
||||||
|
%patch133 -p1
|
||||||
|
%patch134 -p1
|
||||||
|
|
||||||
%build
|
%build
|
||||||
autoreconf -fiv
|
autoreconf -fiv
|
||||||
|
# to remove after upgrading to systemd 196+
|
||||||
|
rm -f man/{systemd.exec.5,logind.conf.5,systemctl.1,systemd-suspend.service.8,systemd.special.7,tmpfiles.d.5}
|
||||||
|
|
||||||
# prevent pre-generated and distributed files from re-building
|
# prevent pre-generated and distributed files from re-building
|
||||||
find . -name "*.[1-8]" -exec touch '{}' '+';
|
find . -name "*.[1-8]" -exec touch '{}' '+';
|
||||||
export V=1
|
export V=1
|
||||||
@ -873,6 +885,13 @@ fi
|
|||||||
%post -n libgudev-1_0-0 -p /sbin/ldconfig
|
%post -n libgudev-1_0-0 -p /sbin/ldconfig
|
||||||
|
|
||||||
%postun -n libgudev-1_0-0 -p /sbin/ldconfig
|
%postun -n libgudev-1_0-0 -p /sbin/ldconfig
|
||||||
|
|
||||||
|
%post logger
|
||||||
|
if [ "$1" -eq 1 ]; then
|
||||||
|
# tell journal to start logging on disk if directory didn't exist before
|
||||||
|
systemctl --no-block restart systemd-journal-flush.service >/dev/null 2>&1 || :
|
||||||
|
fi
|
||||||
|
|
||||||
%endif
|
%endif
|
||||||
|
|
||||||
%clean
|
%clean
|
||||||
|
Loading…
Reference in New Issue
Block a user