.
OBS-URL: https://build.opensuse.org/package/show/Base:System/systemd?expand=0&rev=497
This commit is contained in:
parent
8fcacb0a40
commit
0534e50b68
537
0001-add-hdflush-for-reboot-or-hddown-for-poweroff.patch
Normal file
537
0001-add-hdflush-for-reboot-or-hddown-for-poweroff.patch
Normal file
@ -0,0 +1,537 @@
|
|||||||
|
This seems to be a SUSE specific patch. Here we add the check for unmaintained
|
||||||
|
disk like devices to be able to flush and maybe shut them down. Also we add the
|
||||||
|
missing sync() system call for the direct halt/reboot systemctl command. Then we
|
||||||
|
use the system halt as gfallback if poweroff fails for both the direct poweroff
|
||||||
|
systemctl command as well as for the systemd-shutdown utility.
|
||||||
|
|
||||||
|
---
|
||||||
|
Makefile.am | 2
|
||||||
|
Makefile.in | 7
|
||||||
|
src/core/shutdown.c | 8 -
|
||||||
|
src/shared/hdflush.c | 365 ++++++++++++++++++++++++++++++++++++++++++++++
|
||||||
|
src/shared/hdflush.h | 25 +++
|
||||||
|
src/systemctl/systemctl.c | 17 +-
|
||||||
|
6 files changed, 416 insertions(+), 8 deletions(-)
|
||||||
|
|
||||||
|
--- systemd-208/Makefile.am
|
||||||
|
+++ systemd-208/Makefile.am 2014-01-28 11:06:55.638238060 +0000
|
||||||
|
@@ -680,6 +680,8 @@ libsystemd_shared_la_SOURCES = \
|
||||||
|
src/shared/strbuf.h \
|
||||||
|
src/shared/strxcpyx.c \
|
||||||
|
src/shared/strxcpyx.h \
|
||||||
|
+ src/shared/hdflush.c \
|
||||||
|
+ src/shared/hdflush.h \
|
||||||
|
src/shared/conf-parser.c \
|
||||||
|
src/shared/conf-parser.h \
|
||||||
|
src/shared/log.c \
|
||||||
|
--- systemd-208/Makefile.in
|
||||||
|
+++ systemd-208/Makefile.in 2014-01-28 11:06:33.942246196 +0000
|
||||||
|
@@ -1509,7 +1509,7 @@ am_libsystemd_shared_la_OBJECTS = src/sh
|
||||||
|
src/shared/hashmap.lo src/shared/set.lo src/shared/fdset.lo \
|
||||||
|
src/shared/prioq.lo src/shared/sleep-config.lo \
|
||||||
|
src/shared/strv.lo src/shared/env-util.lo src/shared/strbuf.lo \
|
||||||
|
- src/shared/strxcpyx.lo src/shared/conf-parser.lo \
|
||||||
|
+ src/shared/strxcpyx.lo src/shared/hdflush.lo src/shared/conf-parser.lo \
|
||||||
|
src/shared/log.lo src/shared/ratelimit.lo \
|
||||||
|
src/shared/exit-status.lo src/shared/utf8.lo \
|
||||||
|
src/shared/pager.lo src/shared/socket-util.lo \
|
||||||
|
@@ -4137,6 +4137,8 @@ libsystemd_shared_la_SOURCES = \
|
||||||
|
src/shared/strbuf.h \
|
||||||
|
src/shared/strxcpyx.c \
|
||||||
|
src/shared/strxcpyx.h \
|
||||||
|
+ src/shared/hdflush.c \
|
||||||
|
+ src/shared/hdflush.h \
|
||||||
|
src/shared/conf-parser.c \
|
||||||
|
src/shared/conf-parser.h \
|
||||||
|
src/shared/log.c \
|
||||||
|
@@ -7073,6 +7075,8 @@ src/shared/strbuf.lo: src/shared/$(am__d
|
||||||
|
src/shared/$(DEPDIR)/$(am__dirstamp)
|
||||||
|
src/shared/strxcpyx.lo: src/shared/$(am__dirstamp) \
|
||||||
|
src/shared/$(DEPDIR)/$(am__dirstamp)
|
||||||
|
+src/shared/hdflush.lo: src/shared/$(am__dirstamp) \
|
||||||
|
+ src/shared/$(DEPDIR)/$(am__dirstamp)
|
||||||
|
src/shared/conf-parser.lo: src/shared/$(am__dirstamp) \
|
||||||
|
src/shared/$(DEPDIR)/$(am__dirstamp)
|
||||||
|
src/shared/log.lo: src/shared/$(am__dirstamp) \
|
||||||
|
@@ -9236,6 +9240,7 @@ distclean-compile:
|
||||||
|
@AMDEP_TRUE@@am__include@ @am__quote@src/shared/$(DEPDIR)/strbuf.Plo@am__quote@
|
||||||
|
@AMDEP_TRUE@@am__include@ @am__quote@src/shared/$(DEPDIR)/strv.Plo@am__quote@
|
||||||
|
@AMDEP_TRUE@@am__include@ @am__quote@src/shared/$(DEPDIR)/strxcpyx.Plo@am__quote@
|
||||||
|
+@AMDEP_TRUE@@am__include@ @am__quote@src/shared/$(DEPDIR)/hdflush.Plo@am__quote@
|
||||||
|
@AMDEP_TRUE@@am__include@ @am__quote@src/shared/$(DEPDIR)/time-dst.Plo@am__quote@
|
||||||
|
@AMDEP_TRUE@@am__include@ @am__quote@src/shared/$(DEPDIR)/time-util.Plo@am__quote@
|
||||||
|
@AMDEP_TRUE@@am__include@ @am__quote@src/shared/$(DEPDIR)/unit-name.Plo@am__quote@
|
||||||
|
--- systemd-208/src/shared/hdflush.c
|
||||||
|
+++ systemd-208/src/shared/hdflush.c 2014-01-28 10:58:56.490735704 +0000
|
||||||
|
@@ -0,0 +1,365 @@
|
||||||
|
+/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
|
||||||
|
+
|
||||||
|
+/***
|
||||||
|
+ This file is part of systemd.
|
||||||
|
+
|
||||||
|
+ Copyright 2014 Werner Fink
|
||||||
|
+
|
||||||
|
+ 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/>.
|
||||||
|
+***/
|
||||||
|
+
|
||||||
|
+/*
|
||||||
|
+ * Find all disks on the system, list out IDE, unmanaged ATA disks, and
|
||||||
|
+ * USB sticks flush the cache of those and optional shut them down.
|
||||||
|
+ */
|
||||||
|
+
|
||||||
|
+#include <libudev.h>
|
||||||
|
+#include <limits.h>
|
||||||
|
+#ifdef LIST_DEBUG
|
||||||
|
+# include <stdio.h>
|
||||||
|
+#endif
|
||||||
|
+#include <stdlib.h>
|
||||||
|
+#include <string.h>
|
||||||
|
+#include <unistd.h>
|
||||||
|
+
|
||||||
|
+#include <sys/types.h>
|
||||||
|
+#include <sys/stat.h>
|
||||||
|
+#include <fcntl.h>
|
||||||
|
+#include <errno.h>
|
||||||
|
+
|
||||||
|
+#include <sys/ioctl.h>
|
||||||
|
+#include <linux/hdreg.h>
|
||||||
|
+#include <linux/fs.h>
|
||||||
|
+#ifdef WORDS_BIGENDIAN
|
||||||
|
+# include <byteswap.h>
|
||||||
|
+#endif
|
||||||
|
+
|
||||||
|
+/* Used in flush_cache_ext(), compare with <linux/hdreg.h> */
|
||||||
|
+#define IDBYTES 512
|
||||||
|
+#define MASK_EXT 0xE000 /* Bit 15 shall be zero, bit 14 shall be one, bit 13 flush cache ext */
|
||||||
|
+#define TEST_EXT 0x6000
|
||||||
|
+
|
||||||
|
+/* Maybe set in list_disks() and used in do_standby_disk() */
|
||||||
|
+#define DISK_IS_IDE 0x00000001
|
||||||
|
+#define DISK_IS_SATA 0x00000002
|
||||||
|
+#define DISK_EXTFLUSH 0x00000004
|
||||||
|
+#define DISK_REMOVABLE 0x00000008
|
||||||
|
+#define DISK_MANAGED 0x00000010
|
||||||
|
+#define DISK_FLUSHONLY 0x00000020
|
||||||
|
+
|
||||||
|
+struct sysfs {
|
||||||
|
+ struct udev *udev;
|
||||||
|
+ struct udev_enumerate *num;
|
||||||
|
+ struct udev_list_entry *item;
|
||||||
|
+ char *devnode;
|
||||||
|
+ size_t size;
|
||||||
|
+};
|
||||||
|
+
|
||||||
|
+static int flush_cache_ext(const struct sysfs *sysfs);
|
||||||
|
+
|
||||||
|
+static struct sysfs * open_sysfs(void)
|
||||||
|
+{
|
||||||
|
+ static struct sysfs sysfs;
|
||||||
|
+ sysfs.udev = udev_new();
|
||||||
|
+ if (!sysfs.udev)
|
||||||
|
+ goto err;
|
||||||
|
+ sysfs.num = udev_enumerate_new(sysfs.udev);
|
||||||
|
+ if (!sysfs.num)
|
||||||
|
+ goto err;
|
||||||
|
+ if (udev_enumerate_add_match_subsystem(sysfs.num, "block") < 0)
|
||||||
|
+ goto err;
|
||||||
|
+ if (udev_enumerate_add_match_sysname(sysfs.num, "sd?") < 0)
|
||||||
|
+ goto err;
|
||||||
|
+ if (udev_enumerate_add_match_sysname(sysfs.num, "hd?") < 0)
|
||||||
|
+ goto err;
|
||||||
|
+ if (udev_enumerate_scan_devices(sysfs.num) < 0)
|
||||||
|
+ goto err;
|
||||||
|
+ sysfs.item = udev_enumerate_get_list_entry(sysfs.num);
|
||||||
|
+ sysfs.devnode = NULL;
|
||||||
|
+ sysfs.size = 0;
|
||||||
|
+ return &sysfs;
|
||||||
|
+err:
|
||||||
|
+ if (sysfs.num)
|
||||||
|
+ udev_unref(sysfs.udev);
|
||||||
|
+ if (sysfs.udev)
|
||||||
|
+ udev_unref(sysfs.udev);
|
||||||
|
+ return NULL;
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
+static void close_sysfs(struct sysfs *sysfs)
|
||||||
|
+{
|
||||||
|
+ if (sysfs->num)
|
||||||
|
+ udev_enumerate_unref(sysfs->num);
|
||||||
|
+ if (sysfs->udev)
|
||||||
|
+ udev_unref(sysfs->udev);
|
||||||
|
+ if (sysfs->devnode)
|
||||||
|
+ free(sysfs->devnode);
|
||||||
|
+ sysfs->devnode = NULL;
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
+
|
||||||
|
+static char *list_disks(struct sysfs *sysfs, unsigned int* flags)
|
||||||
|
+{
|
||||||
|
+ struct udev_device *device, *parent;
|
||||||
|
+ struct udev_list_entry *item;
|
||||||
|
+ const char *devnode;
|
||||||
|
+ char path[PATH_MAX];
|
||||||
|
+
|
||||||
|
+ device = NULL;
|
||||||
|
+next:
|
||||||
|
+ if (device)
|
||||||
|
+ udev_device_unref(device);
|
||||||
|
+ if (sysfs->devnode)
|
||||||
|
+ free(sysfs->devnode);
|
||||||
|
+ sysfs->devnode = NULL;
|
||||||
|
+ sysfs->size = 0;
|
||||||
|
+ *flags = 0;
|
||||||
|
+
|
||||||
|
+ if (!sysfs->item)
|
||||||
|
+ goto empty;
|
||||||
|
+ item = sysfs->item;
|
||||||
|
+ sysfs->item = udev_list_entry_get_next(sysfs->item);
|
||||||
|
+
|
||||||
|
+ if (!(device = udev_device_new_from_syspath(sysfs->udev, udev_list_entry_get_name(item))))
|
||||||
|
+ goto out;
|
||||||
|
+ if (!(devnode = udev_device_get_devnode(device)))
|
||||||
|
+ goto out;
|
||||||
|
+ if (!(sysfs->devnode = strdup(devnode)))
|
||||||
|
+ goto out;
|
||||||
|
+
|
||||||
|
+ path[0] = '\0';
|
||||||
|
+ parent = udev_device_get_parent(device);
|
||||||
|
+ if (parent) {
|
||||||
|
+ const char *sysname, *devpath;
|
||||||
|
+ struct udev_device *disk;
|
||||||
|
+ const char *value;
|
||||||
|
+ int ret;
|
||||||
|
+
|
||||||
|
+ sysname = udev_device_get_sysname(parent);
|
||||||
|
+ devpath = udev_device_get_devpath(parent);
|
||||||
|
+
|
||||||
|
+ strcpy(path, "/sys");
|
||||||
|
+ strcat(path, devpath);
|
||||||
|
+ strcat(path, "/scsi_disk/");
|
||||||
|
+ strcat(path, sysname);
|
||||||
|
+
|
||||||
|
+ disk = udev_device_new_from_syspath(sysfs->udev, path);
|
||||||
|
+ if (disk) {
|
||||||
|
+ value = udev_device_get_sysattr_value(disk, "manage_start_stop");
|
||||||
|
+ udev_device_unref(disk);
|
||||||
|
+
|
||||||
|
+ if (value && *value != '0') {
|
||||||
|
+ *flags = DISK_MANAGED;
|
||||||
|
+#ifdef LIST_DEBUG
|
||||||
|
+ goto next; /* Device managed by the kernel */
|
||||||
|
+#endif
|
||||||
|
+ }
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ value = udev_device_get_sysattr_value(device, "size");
|
||||||
|
+ if (value && *value)
|
||||||
|
+ sysfs->size = (size_t)atoll(value);
|
||||||
|
+
|
||||||
|
+ value = udev_device_get_sysattr_value(device, "removable");
|
||||||
|
+ if (value && *value != '0') {
|
||||||
|
+ *flags |= DISK_REMOVABLE;
|
||||||
|
+
|
||||||
|
+ if ((ret = flush_cache_ext(sysfs))) {
|
||||||
|
+ if (ret < 0)
|
||||||
|
+ goto next;
|
||||||
|
+ *flags |= DISK_EXTFLUSH;
|
||||||
|
+ }
|
||||||
|
+ goto out; /* Removable disk like USB stick */
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ value = udev_device_get_sysname(device);
|
||||||
|
+ if (value && *value == 'h') {
|
||||||
|
+ *flags |= DISK_IS_IDE;
|
||||||
|
+
|
||||||
|
+ if ((ret = flush_cache_ext(sysfs))) {
|
||||||
|
+ if (ret < 0)
|
||||||
|
+ goto next;
|
||||||
|
+ *flags |= DISK_EXTFLUSH;
|
||||||
|
+ }
|
||||||
|
+ goto out; /* IDE disk found */
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ value = udev_device_get_sysattr_value(parent, "vendor");
|
||||||
|
+ if (value && strncmp(value, "ATA", 3) == 0) {
|
||||||
|
+ *flags |= (DISK_IS_IDE|DISK_IS_SATA);
|
||||||
|
+
|
||||||
|
+ if ((ret = flush_cache_ext(sysfs))) {
|
||||||
|
+ if (ret < 0)
|
||||||
|
+ goto next;
|
||||||
|
+ *flags |= DISK_EXTFLUSH;
|
||||||
|
+ }
|
||||||
|
+ goto out; /* SATA disk to shutdown */
|
||||||
|
+ }
|
||||||
|
+ goto next;
|
||||||
|
+ }
|
||||||
|
+out:
|
||||||
|
+ udev_device_unref(device);
|
||||||
|
+empty:
|
||||||
|
+ return sysfs->devnode;
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
+/*
|
||||||
|
+ * Check IDE/(S)ATA hard disk identity for
|
||||||
|
+ * the FLUSH CACHE EXT bit set.
|
||||||
|
+ */
|
||||||
|
+static int flush_cache_ext(const struct sysfs *sysfs)
|
||||||
|
+{
|
||||||
|
+#ifndef WIN_IDENTIFY
|
||||||
|
+#define WIN_IDENTIFY 0xEC
|
||||||
|
+#endif
|
||||||
|
+ unsigned char args[4+IDBYTES];
|
||||||
|
+ unsigned short *id = (unsigned short*)(&args[4]);
|
||||||
|
+ int fd = -1, ret = 0;
|
||||||
|
+
|
||||||
|
+ if (sysfs->size < (1<<28))
|
||||||
|
+ goto out; /* small disk */
|
||||||
|
+
|
||||||
|
+ if ((fd = open(sysfs->devnode, O_RDONLY|O_NONBLOCK|O_CLOEXEC)) < 0)
|
||||||
|
+ goto out;
|
||||||
|
+
|
||||||
|
+ memset(&args[0], 0, sizeof(args));
|
||||||
|
+ args[0] = WIN_IDENTIFY;
|
||||||
|
+ args[3] = 1;
|
||||||
|
+ if (ioctl(fd, HDIO_DRIVE_CMD, &args))
|
||||||
|
+ goto out;
|
||||||
|
+#ifdef WORDS_BIGENDIAN
|
||||||
|
+# if 0
|
||||||
|
+ {
|
||||||
|
+ const unsigned short *end = id + IDBYTES/2;
|
||||||
|
+ const unsigned short *from = id;
|
||||||
|
+ unsigned short *to = id;
|
||||||
|
+
|
||||||
|
+ while (from < end)
|
||||||
|
+ *to++ = bswap_16(*from++);
|
||||||
|
+ }
|
||||||
|
+# else
|
||||||
|
+ id[83] = bswap_16(id[83]);
|
||||||
|
+# endif
|
||||||
|
+#endif
|
||||||
|
+ if ((id[83] & MASK_EXT) == TEST_EXT)
|
||||||
|
+ ret = 1;
|
||||||
|
+out:
|
||||||
|
+ if (fd >= 0)
|
||||||
|
+ close(fd);
|
||||||
|
+ return ret;
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
+/*
|
||||||
|
+ * Put an IDE/SCSI/SATA disk in standby mode.
|
||||||
|
+ * Code stolen from hdparm.c
|
||||||
|
+ */
|
||||||
|
+static int do_standby_disk(struct sysfs *sysfs, unsigned int flags)
|
||||||
|
+{
|
||||||
|
+#ifndef WIN_STANDBYNOW1
|
||||||
|
+#define WIN_STANDBYNOW1 0xE0
|
||||||
|
+#endif
|
||||||
|
+#ifndef WIN_STANDBYNOW2
|
||||||
|
+#define WIN_STANDBYNOW2 0x94
|
||||||
|
+#endif
|
||||||
|
+#ifndef WIN_FLUSH_CACHE_EXT
|
||||||
|
+#define WIN_FLUSH_CACHE_EXT 0xEA
|
||||||
|
+#endif
|
||||||
|
+#ifndef WIN_FLUSH_CACHE
|
||||||
|
+#define WIN_FLUSH_CACHE 0xE7
|
||||||
|
+#endif
|
||||||
|
+ unsigned char flush1[4] = {WIN_FLUSH_CACHE_EXT,0,0,0};
|
||||||
|
+ unsigned char flush2[4] = {WIN_FLUSH_CACHE,0,0,0};
|
||||||
|
+ unsigned char stdby1[4] = {WIN_STANDBYNOW1,0,0,0};
|
||||||
|
+ unsigned char stdby2[4] = {WIN_STANDBYNOW2,0,0,0};
|
||||||
|
+ int fd, ret;
|
||||||
|
+
|
||||||
|
+ if ((fd = open(sysfs->devnode, O_RDWR|O_NONBLOCK|O_CLOEXEC)) < 0)
|
||||||
|
+ return -1;
|
||||||
|
+
|
||||||
|
+ switch (flags & DISK_EXTFLUSH) {
|
||||||
|
+ case DISK_EXTFLUSH:
|
||||||
|
+ if ((ret = ioctl(fd, HDIO_DRIVE_CMD, &flush1)) == 0)
|
||||||
|
+ break;
|
||||||
|
+ /* Extend flush rejected, try standard flush */
|
||||||
|
+ default:
|
||||||
|
+ ret = ioctl(fd, HDIO_DRIVE_CMD, &flush2) &&
|
||||||
|
+ ioctl(fd, BLKFLSBUF);
|
||||||
|
+ break;
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ if ((flags & DISK_FLUSHONLY) == 0x0) {
|
||||||
|
+ ret = ioctl(fd, HDIO_DRIVE_CMD, &stdby1) &&
|
||||||
|
+ ioctl(fd, HDIO_DRIVE_CMD, &stdby2);
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ close(fd);
|
||||||
|
+
|
||||||
|
+ if (ret)
|
||||||
|
+ return -1;
|
||||||
|
+ return 0;
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
+#ifdef LIST_DEBUG
|
||||||
|
+int main()
|
||||||
|
+{
|
||||||
|
+ char *disk;
|
||||||
|
+ unsigned int flags;
|
||||||
|
+ struct sysfs *sysfs = open_sysfs();
|
||||||
|
+ if (!sysfs)
|
||||||
|
+ goto err;
|
||||||
|
+ while ((disk = list_disks(sysfs, &flags)))
|
||||||
|
+ fprintf(stdout, "%s\n", sysfs->devnode);
|
||||||
|
+ close_sysfs(sysfs);
|
||||||
|
+err:
|
||||||
|
+ return 0;
|
||||||
|
+}
|
||||||
|
+#else
|
||||||
|
+/*
|
||||||
|
+ * List all disks and put them in standby mode.
|
||||||
|
+ * This has the side-effect of flushing the writecache,
|
||||||
|
+ * which is exactly what we want on poweroff.
|
||||||
|
+ */
|
||||||
|
+void hddown(void)
|
||||||
|
+{
|
||||||
|
+ struct sysfs *sysfs;
|
||||||
|
+ unsigned int flags;
|
||||||
|
+ char *disk;
|
||||||
|
+
|
||||||
|
+ if (!(sysfs = open_sysfs()))
|
||||||
|
+ return;
|
||||||
|
+
|
||||||
|
+ while ((disk = list_disks(sysfs, &flags)))
|
||||||
|
+ do_standby_disk(sysfs, flags);
|
||||||
|
+
|
||||||
|
+ close_sysfs(sysfs);
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
+/*
|
||||||
|
+ * List all disks and cause them to flush their buffers.
|
||||||
|
+ */
|
||||||
|
+void hdflush(void)
|
||||||
|
+{
|
||||||
|
+ struct sysfs *sysfs;
|
||||||
|
+ unsigned int flags;
|
||||||
|
+ char *disk;
|
||||||
|
+
|
||||||
|
+ if (!(sysfs = open_sysfs()))
|
||||||
|
+ return;
|
||||||
|
+
|
||||||
|
+ while ((disk = list_disks(sysfs, &flags)))
|
||||||
|
+ do_standby_disk(sysfs, (flags|DISK_FLUSHONLY));
|
||||||
|
+
|
||||||
|
+ close_sysfs(sysfs);
|
||||||
|
+}
|
||||||
|
+#endif
|
||||||
|
--- systemd-208/src/shared/hdflush.h
|
||||||
|
+++ systemd-208/src/shared/hdflush.h 2014-01-28 11:00:08.286235696 +0000
|
||||||
|
@@ -0,0 +1,25 @@
|
||||||
|
+/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
|
||||||
|
+
|
||||||
|
+#pragma once
|
||||||
|
+
|
||||||
|
+/***
|
||||||
|
+ This file is part of systemd.
|
||||||
|
+
|
||||||
|
+ Copyright 2014 Werner Fink
|
||||||
|
+
|
||||||
|
+ 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/>.
|
||||||
|
+***/
|
||||||
|
+
|
||||||
|
+void hdflush(void);
|
||||||
|
+void hddown(void);
|
||||||
|
--- systemd-208/src/core/shutdown.c
|
||||||
|
+++ systemd-208/src/core/shutdown.c 2014-01-28 11:14:15.722235591 +0000
|
||||||
|
@@ -40,6 +40,7 @@
|
||||||
|
#include "missing.h"
|
||||||
|
#include "log.h"
|
||||||
|
#include "fileio.h"
|
||||||
|
+#include "hdflush.h"
|
||||||
|
#include "umount.h"
|
||||||
|
#include "util.h"
|
||||||
|
#include "mkdir.h"
|
||||||
|
@@ -302,8 +303,13 @@ int main(int argc, char *argv[]) {
|
||||||
|
* on reboot(), but the file systems need to be synce'd
|
||||||
|
* explicitly in advance. So let's do this here, but not
|
||||||
|
* needlessly slow down containers. */
|
||||||
|
- if (!in_container)
|
||||||
|
+ if (!in_container) {
|
||||||
|
sync();
|
||||||
|
+ if (cmd == RB_POWER_OFF || cmd == RB_HALT_SYSTEM)
|
||||||
|
+ hddown();
|
||||||
|
+ else
|
||||||
|
+ hdflush();
|
||||||
|
+ }
|
||||||
|
|
||||||
|
if (cmd == LINUX_REBOOT_CMD_KEXEC) {
|
||||||
|
|
||||||
|
--- systemd-208/src/systemctl/systemctl.c
|
||||||
|
+++ systemd-208/src/systemctl/systemctl.c 2014-01-28 11:31:27.150735613 +0000
|
||||||
|
@@ -87,6 +87,7 @@ static bool arg_no_pager = false;
|
||||||
|
static bool arg_no_wtmp = false;
|
||||||
|
static bool arg_no_wall = false;
|
||||||
|
static bool arg_no_reload = false;
|
||||||
|
+static bool arg_no_sync = false;
|
||||||
|
static bool arg_show_types = false;
|
||||||
|
static bool arg_ignore_inhibitors = false;
|
||||||
|
static bool arg_dry = false;
|
||||||
|
@@ -5272,6 +5273,7 @@ static int halt_parse_argv(int argc, cha
|
||||||
|
{ "reboot", no_argument, NULL, ARG_REBOOT },
|
||||||
|
{ "force", no_argument, NULL, 'f' },
|
||||||
|
{ "wtmp-only", no_argument, NULL, 'w' },
|
||||||
|
+ { "no-sync", no_argument, NULL, 'n' },
|
||||||
|
{ "no-wtmp", no_argument, NULL, 'd' },
|
||||||
|
{ "no-wall", no_argument, NULL, ARG_NO_WALL },
|
||||||
|
{ NULL, 0, NULL, 0 }
|
||||||
|
@@ -5324,10 +5326,13 @@ static int halt_parse_argv(int argc, cha
|
||||||
|
|
||||||
|
case 'i':
|
||||||
|
case 'h':
|
||||||
|
- case 'n':
|
||||||
|
/* Compatibility nops */
|
||||||
|
break;
|
||||||
|
|
||||||
|
+ case 'n':
|
||||||
|
+ arg_no_sync = true;
|
||||||
|
+ break;
|
||||||
|
+
|
||||||
|
case '?':
|
||||||
|
return -EINVAL;
|
||||||
|
|
||||||
|
@@ -5981,14 +5986,14 @@ static int halt_now(enum action a) {
|
||||||
|
|
||||||
|
switch (a) {
|
||||||
|
|
||||||
|
- case ACTION_HALT:
|
||||||
|
- log_info("Halting.");
|
||||||
|
- reboot(RB_HALT_SYSTEM);
|
||||||
|
- return -errno;
|
||||||
|
-
|
||||||
|
case ACTION_POWEROFF:
|
||||||
|
log_info("Powering off.");
|
||||||
|
reboot(RB_POWER_OFF);
|
||||||
|
+ /* Fall through */
|
||||||
|
+
|
||||||
|
+ case ACTION_HALT:
|
||||||
|
+ log_info("Halting.");
|
||||||
|
+ reboot(RB_HALT_SYSTEM);
|
||||||
|
return -errno;
|
||||||
|
|
||||||
|
case ACTION_REBOOT:
|
85
0001-upstream-systemctl-halt-reboot-error-handling.patch
Normal file
85
0001-upstream-systemctl-halt-reboot-error-handling.patch
Normal file
@ -0,0 +1,85 @@
|
|||||||
|
--- systemd-208/src/core/shutdown.c
|
||||||
|
+++ systemd-208/src/core/shutdown.c 2014-01-27 11:31:38.486235816 +0000
|
||||||
|
@@ -329,6 +329,9 @@ int main(int argc, char *argv[]) {
|
||||||
|
|
||||||
|
reboot(cmd);
|
||||||
|
|
||||||
|
+ if (cmd == RB_POWER_OFF)
|
||||||
|
+ reboot(RB_HALT_SYSTEM);
|
||||||
|
+
|
||||||
|
if (errno == EPERM && in_container) {
|
||||||
|
/* If we are in a container, and we lacked
|
||||||
|
* CAP_SYS_BOOT just exit, this will kill our
|
||||||
|
|
||||||
|
--- systemd-208/src/systemctl/systemctl.c
|
||||||
|
+++ systemd-208/src/systemctl/systemctl.c 2014-01-27 11:05:18.298236035 +0000
|
||||||
|
@@ -138,7 +138,7 @@ static bool arg_plain = false;
|
||||||
|
static bool private_bus = false;
|
||||||
|
|
||||||
|
static int daemon_reload(DBusConnection *bus, char **args);
|
||||||
|
-static void halt_now(enum action a);
|
||||||
|
+static int halt_now(enum action a);
|
||||||
|
|
||||||
|
static void pager_open_if_enabled(void) {
|
||||||
|
|
||||||
|
@@ -2227,7 +2227,7 @@ static int start_special(DBusConnection
|
||||||
|
(a == ACTION_HALT ||
|
||||||
|
a == ACTION_POWEROFF ||
|
||||||
|
a == ACTION_REBOOT))
|
||||||
|
- halt_now(a);
|
||||||
|
+ return halt_now(a);
|
||||||
|
|
||||||
|
if (arg_force >= 1 &&
|
||||||
|
(a == ACTION_HALT ||
|
||||||
|
@@ -5973,7 +5973,7 @@ done:
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
-static _noreturn_ void halt_now(enum action a) {
|
||||||
|
+static int halt_now(enum action a) {
|
||||||
|
|
||||||
|
/* Make sure C-A-D is handled by the kernel from this
|
||||||
|
* point on... */
|
||||||
|
@@ -5984,23 +5984,22 @@ static _noreturn_ void halt_now(enum act
|
||||||
|
case ACTION_HALT:
|
||||||
|
log_info("Halting.");
|
||||||
|
reboot(RB_HALT_SYSTEM);
|
||||||
|
- break;
|
||||||
|
+ return -errno;
|
||||||
|
|
||||||
|
case ACTION_POWEROFF:
|
||||||
|
log_info("Powering off.");
|
||||||
|
reboot(RB_POWER_OFF);
|
||||||
|
- break;
|
||||||
|
+ return -errno;
|
||||||
|
|
||||||
|
case ACTION_REBOOT:
|
||||||
|
log_info("Rebooting.");
|
||||||
|
reboot(RB_AUTOBOOT);
|
||||||
|
- break;
|
||||||
|
+ return -errno;
|
||||||
|
|
||||||
|
default:
|
||||||
|
- assert_not_reached("Unknown halt action.");
|
||||||
|
+ assert_not_reached("Unknown action.");
|
||||||
|
+ return -ENOSYS;
|
||||||
|
}
|
||||||
|
-
|
||||||
|
- assert_not_reached("Uh? This shouldn't happen.");
|
||||||
|
}
|
||||||
|
|
||||||
|
static int halt_main(DBusConnection *bus) {
|
||||||
|
@@ -6069,9 +6068,10 @@ static int halt_main(DBusConnection *bus
|
||||||
|
if (arg_dry)
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
- halt_now(arg_action);
|
||||||
|
- /* We should never reach this. */
|
||||||
|
- return -ENOSYS;
|
||||||
|
+ r = halt_now(arg_action);
|
||||||
|
+ log_error("Failed to reboot: %s", strerror(-r));
|
||||||
|
+
|
||||||
|
+ return r;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int runlevel_main(void) {
|
@ -1,3 +1,16 @@
|
|||||||
|
-------------------------------------------------------------------
|
||||||
|
Tue Jan 28 12:44:07 UTC 2014 - werner@suse.de
|
||||||
|
|
||||||
|
- Add patch 0001-upstream-systemctl-halt-reboot-error-handling.patch
|
||||||
|
to be able to detect if the sysctl reboot() returns.
|
||||||
|
- Add patch 0001-add-hdflush-for-reboot-or-hddown-for-poweroff.patch
|
||||||
|
A check for unmaintained disk like devices is added to be able to
|
||||||
|
flush and maybe shut them down. Also the missing sync() system
|
||||||
|
call is added for the direct halt/reboot systemctl command. Then
|
||||||
|
the system halt is used as fallback if poweroff fails for both
|
||||||
|
the direct poweroff systemctl command as well as for the
|
||||||
|
systemd-shutdown utility.
|
||||||
|
|
||||||
-------------------------------------------------------------------
|
-------------------------------------------------------------------
|
||||||
Thu Jan 23 13:24:53 UTC 2014 - werner@suse.de
|
Thu Jan 23 13:24:53 UTC 2014 - werner@suse.de
|
||||||
|
|
||||||
|
@ -261,6 +261,10 @@ Patch82: analyze-fix-crash-in-command-line-parsing.patch
|
|||||||
Patch83: 0001-core-replace-OnFailureIsolate-setting-by-a-more-gene.patch
|
Patch83: 0001-core-replace-OnFailureIsolate-setting-by-a-more-gene.patch
|
||||||
# PATCH-FIX-OPENSUSE make-emergency.service-conflict-with-syslog.socket.patch (bnc#852232)
|
# PATCH-FIX-OPENSUSE make-emergency.service-conflict-with-syslog.socket.patch (bnc#852232)
|
||||||
Patch84: make-emergency.service-conflict-with-syslog.socket.patch
|
Patch84: make-emergency.service-conflict-with-syslog.socket.patch
|
||||||
|
# PATCH-FIX-UPSTREAM 0001-upstream-systemctl-halt-reboot-error-handling.patch
|
||||||
|
Patch85: 0001-upstream-systemctl-halt-reboot-error-handling.patch
|
||||||
|
# PATCH-FIX-SUSE 0001-add-hdflush-for-reboot-or-hddown-for-poweroff.patch
|
||||||
|
Patch86: 0001-add-hdflush-for-reboot-or-hddown-for-poweroff.patch
|
||||||
|
|
||||||
# udev patches
|
# udev patches
|
||||||
# PATCH-FIX-OPENSUSE 1001-re-enable-by_path-links-for-ata-devices.patch
|
# PATCH-FIX-OPENSUSE 1001-re-enable-by_path-links-for-ata-devices.patch
|
||||||
@ -565,6 +569,8 @@ cp %{SOURCE7} m4/
|
|||||||
%patch82 -p1
|
%patch82 -p1
|
||||||
%patch83 -p1
|
%patch83 -p1
|
||||||
%patch84 -p1
|
%patch84 -p1
|
||||||
|
%patch85 -p1
|
||||||
|
%patch86 -p1
|
||||||
|
|
||||||
# udev patches
|
# udev patches
|
||||||
%patch1001 -p1
|
%patch1001 -p1
|
||||||
|
@ -1,3 +1,16 @@
|
|||||||
|
-------------------------------------------------------------------
|
||||||
|
Tue Jan 28 12:44:07 UTC 2014 - werner@suse.de
|
||||||
|
|
||||||
|
- Add patch 0001-upstream-systemctl-halt-reboot-error-handling.patch
|
||||||
|
to be able to detect if the sysctl reboot() returns.
|
||||||
|
- Add patch 0001-add-hdflush-for-reboot-or-hddown-for-poweroff.patch
|
||||||
|
A check for unmaintained disk like devices is added to be able to
|
||||||
|
flush and maybe shut them down. Also the missing sync() system
|
||||||
|
call is added for the direct halt/reboot systemctl command. Then
|
||||||
|
the system halt is used as fallback if poweroff fails for both
|
||||||
|
the direct poweroff systemctl command as well as for the
|
||||||
|
systemd-shutdown utility.
|
||||||
|
|
||||||
-------------------------------------------------------------------
|
-------------------------------------------------------------------
|
||||||
Thu Jan 23 13:24:53 UTC 2014 - werner@suse.de
|
Thu Jan 23 13:24:53 UTC 2014 - werner@suse.de
|
||||||
|
|
||||||
|
@ -256,6 +256,10 @@ Patch82: analyze-fix-crash-in-command-line-parsing.patch
|
|||||||
Patch83: 0001-core-replace-OnFailureIsolate-setting-by-a-more-gene.patch
|
Patch83: 0001-core-replace-OnFailureIsolate-setting-by-a-more-gene.patch
|
||||||
# PATCH-FIX-OPENSUSE make-emergency.service-conflict-with-syslog.socket.patch (bnc#852232)
|
# PATCH-FIX-OPENSUSE make-emergency.service-conflict-with-syslog.socket.patch (bnc#852232)
|
||||||
Patch84: make-emergency.service-conflict-with-syslog.socket.patch
|
Patch84: make-emergency.service-conflict-with-syslog.socket.patch
|
||||||
|
# PATCH-FIX-UPSTREAM 0001-upstream-systemctl-halt-reboot-error-handling.patch
|
||||||
|
Patch85: 0001-upstream-systemctl-halt-reboot-error-handling.patch
|
||||||
|
# PATCH-FIX-SUSE 0001-add-hdflush-for-reboot-or-hddown-for-poweroff.patch
|
||||||
|
Patch86: 0001-add-hdflush-for-reboot-or-hddown-for-poweroff.patch
|
||||||
|
|
||||||
# udev patches
|
# udev patches
|
||||||
# PATCH-FIX-OPENSUSE 1001-re-enable-by_path-links-for-ata-devices.patch
|
# PATCH-FIX-OPENSUSE 1001-re-enable-by_path-links-for-ata-devices.patch
|
||||||
@ -560,6 +564,8 @@ cp %{SOURCE7} m4/
|
|||||||
%patch82 -p1
|
%patch82 -p1
|
||||||
%patch83 -p1
|
%patch83 -p1
|
||||||
%patch84 -p1
|
%patch84 -p1
|
||||||
|
%patch85 -p1
|
||||||
|
%patch86 -p1
|
||||||
|
|
||||||
# udev patches
|
# udev patches
|
||||||
%patch1001 -p1
|
%patch1001 -p1
|
||||||
|
Loading…
Reference in New Issue
Block a user