/* SPDX-License-Identifier: LGPL-2.1+ */
/***
- This file is part of systemd.
-
Copyright 2013 Zbigniew Jędrzejewski-Szmek
Copyright 2018 Dell Inc.
-
- elogind 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.
-
- elogind 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 elogind; If not, see <http://www.gnu.org/licenses/>.
***/
//#include <errno.h>
**suspend_mode = NULL, **suspend_state = NULL,
**hibernate_mode = NULL, **hibernate_state = NULL,
**hybrid_mode = NULL, **hybrid_state = NULL;
- char **modes, **states;
+ _cleanup_strv_free_ char **modes, **states; /* always initialized below */
usec_t delay = 180 * USEC_PER_MINUTE;
const ConfigTableItem items[] = {
assert_not_reached("what verb");
if ((!modes && STR_IN_SET(verb, "hibernate", "hybrid-sleep")) ||
- (!states && !streq(verb, "suspend-then-hibernate"))) {
- strv_free(modes);
- strv_free(states);
+ (!states && !streq(verb, "suspend-then-hibernate")))
return log_oom();
- }
if (_modes)
- *_modes = modes;
+ *_modes = TAKE_PTR(modes);
if (_states)
- *_states = states;
+ *_states = TAKE_PTR(states);
if (_delay)
*_delay = delay;
return -ENOSYS;
}
-static bool enough_memory_for_hibernation(void) {
+static bool enough_swap_for_hibernation(void) {
_cleanup_free_ char *active = NULL;
unsigned long long act = 0;
size_t size = 0, used = 0;
#if 0 /// elogind has to do, or better, *can* do it differently
static bool can_s2h(void) {
+ const char *p;
int r;
r = access("/sys/class/rtc/rtc0/wakealarm", W_OK);
return false;
}
- r = can_sleep("suspend");
- if (r < 0) {
- log_debug_errno(r, "Unable to suspend system.");
- return false;
- }
-
- r = can_sleep("hibernate");
- if (r < 0) {
- log_debug_errno(r, "Unable to hibernate system.");
- return false;
+ FOREACH_STRING(p, "suspend", "hibernate") {
+ r = can_sleep(p);
+ if (IN_SET(r, 0, -ENOSPC)) {
+ log_debug("Unable to %s system.", p);
+ return false;
+ }
+ if (r < 0)
+ return log_debug_errno(r, "Failed to check if %s is possible: %m", p);
}
return true;
return false;
return streq(verb, "suspend") || enough_memory_for_hibernation();
+ if (streq(verb, "suspend"))
+ return true;
+
+ if (!enough_memory_for_hibernation())
+ if (!enough_swap_for_hibernation())
+ return -ENOSPC;
+
+ return true;
}
#endif // 0