OBS User unknown 2008-05-22 03:00:03 +00:00 committed by Git OBS Bridge
parent 7fe3a13993
commit d9a0503d97
3 changed files with 128 additions and 39 deletions

View File

@ -1,5 +1,24 @@
--- src/halt.c
+++ src/halt.c 2008-05-21 14:04:11.762054000 +0200
@@ -57,6 +57,7 @@ char *progname;
extern int ifdown(void);
extern int hddown(void);
+extern int hdflush(void);
extern void write_wtmp(char *user, char *id, int pid, int type, char *line);
/*
@@ -259,6 +260,8 @@ int main(int argc, char **argv)
if (do_hddown)
(void)hddown();
+ else
+ (void)hdflush();
if (do_nothing) exit(0);
--- src/hddown.c
+++ src/hddown.c 2007-06-12 19:24:34.351142441 +0200
+++ src/hddown.c 2008-05-21 14:48:40.913836000 +0200
@@ -5,6 +5,9 @@
*/
char *v_hddown = "@(#)hddown.c 1.02 22-Apr-2003 miquels@cistron.nl";
@ -10,10 +29,12 @@
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
@@ -18,6 +21,326 @@ char *v_hddown = "@(#)hddown.c 1.02 22
@@ -17,7 +20,371 @@ char *v_hddown = "@(#)hddown.c 1.02 22
#include <sys/ioctl.h>
#include <linux/hdreg.h>
+#include <linux/fs.h>
+
+#define USE_SYSFS
+#ifdef USE_SYSFS
+/*
@ -44,6 +65,10 @@
+#define DISK_IS_IDE 0x00000001
+#define DISK_IS_SATA 0x00000002
+#define DISK_EXTFLUSH 0x00000004
+#define DISK_REMOVABLE 0x00000008
+#define DISK_MANAGED 0x00000010
+#define DISK_NOSTANDBY 0x00000020
+#define DISK_FLUSHONLY DISK_NOSTANDBY
+
+static char *strstrip(char *str);
+static FILE *hdopen(const char* const format, const char* const name);
@ -57,10 +82,9 @@
+ struct dirent *d;
+
+ while ((d = readdir(blk))) {
+ *flags = 0;
+ (*flags) = 0;
+ if (d->d_name[1] == 'd' && (d->d_name[0] == 'h' || d->d_name[0] == 's')) {
+ char buf[NAME_MAX+1], lnk[NAME_MAX+1], *ptr;
+ struct stat st;
+ FILE *fp;
+ int ret;
+
@ -75,9 +99,12 @@
+ fclose(fp);
+
+ if (ret != '0')
+ continue; /* not a hard disk */
+ (*flags) |= DISK_REMOVABLE;
+
+ if (d->d_name[0] == 'h') {
+ if ((*flags) & DISK_REMOVABLE)
+ continue; /* not a hard disk */
+
+ (*flags) |= DISK_IS_IDE;
+ if ((ret = flush_cache_ext(d->d_name))) {
+ if (ret < 0)
@ -88,11 +115,11 @@
+ }
+
+ ret = snprintf(buf, sizeof(buf), SYS_BLK "/%s/device", d->d_name);
+ if ((ret >= sizeof(buf)) || (ret < 0))
+ if ((ret >= (int)sizeof(buf)) || (ret < 0))
+ goto empty; /* error */
+
+ ret = readlink(buf, lnk, sizeof(lnk));
+ if (ret >= sizeof(lnk))
+ if (ret >= (int)sizeof(lnk))
+ goto empty; /* error */
+ if (ret < 0) {
+ if (errno != ENOENT)
@ -105,16 +132,19 @@
+ if (!ptr || !*ptr)
+ continue; /* should not happen */
+
+ ret = snprintf(buf, sizeof(buf), SYS_CLASS "/%s/manage_start_stop", ptr);
+ if ((ret >= sizeof(buf)) || (ret < 0))
+ goto empty; /* error */
+ fp = hdopen(SYS_CLASS "/%s/manage_start_stop", ptr);
+ if ((long)fp <= 0) {
+ if ((long)fp < 0)
+ goto empty; /* error */
+ } else {
+ ret = getc(fp);
+ fclose(fp);
+
+ ret = stat(buf, &st);
+ if (ret == 0)
+ continue; /* disk found but managed by kernel */
+
+ if (errno != ENOENT)
+ goto empty; /* error */
+ if (ret != '0') {
+ (*flags) |= DISK_MANAGED;
+ continue;
+ }
+ }
+
+ fp = hdopen(SYS_BLK "/%s/device/vendor", d->d_name);
+ if ((long)fp <= 0) {
@ -132,16 +162,28 @@
+ if (*ptr == '\0')
+ continue; /* should not happen */
+
+ if (strncmp(buf, "ATA", sizeof(buf)))
+ continue; /* no SATA but a real SCSI disk */
+ if (strncmp(buf, "ATA", sizeof(buf)) == 0) {
+ if ((*flags) & DISK_REMOVABLE)
+ continue; /* not a hard disk */
+
+ (*flags) |= (DISK_IS_IDE|DISK_IS_SATA);
+ if ((ret = flush_cache_ext(d->d_name))) {
+ if (ret < 0)
+ goto empty;
+ (*flags) |= DISK_EXTFLUSH;
+ }
+ break; /* new SATA disk to shutdown, out here */
+ }
+
+ if (((*flags) & DISK_REMOVABLE) == 0)
+ continue; /* Seems to be a real SCSI disk */
+
+ (*flags) |= (DISK_IS_IDE|DISK_IS_SATA);
+ if ((ret = flush_cache_ext(d->d_name))) {
+ if (ret < 0)
+ goto empty;
+ (*flags) |= DISK_EXTFLUSH;
+ }
+ break; /* new SATA disk to shutdown, out here */
+ break; /* Removable disk like USB stick to shutdown */
+ }
+ }
+ if (d == (struct dirent*)0)
@ -155,7 +197,7 @@
+ * Put an disk in standby mode.
+ * Code stolen from hdparm.c
+ */
+static int do_standby_idedisk(char *device, unsigned int flags)
+static int do_standby_disk(char *device, unsigned int flags)
+{
+#ifndef WIN_STANDBYNOW1
+#define WIN_STANDBYNOW1 0xE0
@ -177,24 +219,28 @@
+ int fd, ret;
+
+ ret = snprintf(buf, sizeof(buf), DEV_BASE "/%s", device);
+ if ((ret >= sizeof(buf)) || (ret < 0))
+ if ((ret >= (int)sizeof(buf)) || (ret < 0))
+ return -1;
+
+ if ((fd = open(buf, O_RDWR)) < 0)
+ if ((fd = open(buf, O_RDWR|O_NONBLOCK)) < 0)
+ return -1;
+
+ switch (flags & DISK_EXTFLUSH) {
+ case DISK_EXTFLUSH:
+ if (ioctl(fd, HDIO_DRIVE_CMD, &flush1) == 0)
+ if ((ret = ioctl(fd, HDIO_DRIVE_CMD, &flush1)) == 0)
+ break;
+ /* Extend flush rejected, try standard flush */
+ default:
+ ioctl(fd, HDIO_DRIVE_CMD, &flush2);
+ ret = ioctl(fd, HDIO_DRIVE_CMD, &flush2) &&
+ ioctl(fd, BLKFLSBUF);
+ break;
+ }
+
+ ret = ioctl(fd, HDIO_DRIVE_CMD, &stdby1) &&
+ ioctl(fd, HDIO_DRIVE_CMD, &stdby2);
+ if ((flags & DISK_NOSTANDBY) == 0x0) {
+ ret = ioctl(fd, HDIO_DRIVE_CMD, &stdby1) &&
+ ioctl(fd, HDIO_DRIVE_CMD, &stdby2);
+ }
+
+ close(fd);
+
+ if (ret)
@ -217,7 +263,25 @@
+ return -1;
+
+ while ((disk = list_disks(blk, &flags)))
+ do_standby_idedisk(disk, flags);
+ do_standby_disk(disk, flags);
+
+ return closedir(blk);
+}
+
+/*
+ * List all disks and cause them to flush their buffers.
+ */
+int hdflush(void)
+{
+ unsigned int flags;
+ char *disk;
+ DIR *blk;
+
+ if ((blk = opendir(SYS_BLK)) == (DIR*)0)
+ return -1;
+
+ while ((disk = list_disks(blk, &flags)))
+ do_standby_disk(disk, (flags|DISK_NOSTANDBY));
+
+ return closedir(blk);
+}
@ -248,7 +312,7 @@
+ int fd, ret;
+
+ ret = snprintf(buf, sizeof(buf), format, name);
+ if ((ret >= sizeof(buf)) || (ret < 0))
+ if ((ret >= (int)sizeof(buf)) || (ret < 0))
+ goto error; /* error */
+
+ fd = open(buf, O_RDONLY|O_NOCTTY);
@ -301,7 +365,7 @@
+ goto out; /* small disk */
+
+ ret = snprintf(buf, sizeof(buf), DEV_BASE "/%s", device);
+ if ((ret >= sizeof(buf)) || (ret < 0))
+ if ((ret >= (int)sizeof(buf)) || (ret < 0))
+ return -1; /* error */
+
+ if ((fd = open(buf, O_RDONLY|O_NONBLOCK)) < 0)
@ -337,12 +401,28 @@
#define MAX_DISKS 64
#define PROC_IDE "/proc/ide"
#define DEV_BASE "/dev"
@@ -104,7 +427,7 @@ int hddown(void)
@@ -105,6 +472,12 @@ int hddown(void)
return 0;
}
-
+int hdflush(void)
+{
+ return 0;
+}
+
+#endif /* ! USE_SYSFS */
#else /* __linux__ */
int hddown(void)
@@ -112,6 +485,11 @@ int hddown(void)
return 0;
}
+int hdflush(void)
+{
+ return 0;
+}
+
#endif /* __linux__ */
#ifdef STANDALONE

View File

@ -1,3 +1,9 @@
-------------------------------------------------------------------
Tue May 20 14:31:14 CEST 2008 - werner@suse.de
- On halt flush not only unmanged disk but also removable devices
like usb sticks (bnc#386487 related to bnc#229210)
-------------------------------------------------------------------
Thu Mar 13 17:27:50 CET 2008 - werner@suse.de

View File

@ -23,7 +23,7 @@ Group: System/Base
PreReq: coreutils
AutoReqProv: on
Version: 2.86
Release: 132
Release: 146
Summary: SysV-Style init
BuildRoot: %{_tmppath}/%{name}-%{version}-build
Source: sysvinit-2.86.tar.bz2
@ -285,6 +285,9 @@ rm -rf ${RPM_BUILD_ROOT}
%doc %{_mandir}/man8/startpar.8.gz
%changelog
* Tue May 20 2008 werner@suse.de
- On halt flush not only unmanged disk but also removable devices
like usb sticks (bnc#386487 related to bnc#229210)
* Thu Mar 13 2008 werner@suse.de
- Avoid race in blogd due sheduling priority which may raise EIO
otherwise and do not free name of second tty needed for reconnect
@ -377,7 +380,7 @@ rm -rf ${RPM_BUILD_ROOT}
* Tue Nov 08 2005 werner@suse.de
- Move version of killproc to 2.11
* Allow to set a prefix and to disable usleep
* Wed Nov 02 2005 dmueller@suse.de
* Thu Nov 03 2005 dmueller@suse.de
- don't build as root
* Wed Nov 02 2005 werner@suse.de
- Move version of killporc to 2.10
@ -781,7 +784,7 @@ rm -rf ${RPM_BUILD_ROOT}
- Set the terminal line immediately
* Mon Mar 06 2000 werner@suse.de
- Avoid script handling for kernel threads
* Sun Mar 05 2000 werner@suse.de
* Mon Mar 06 2000 werner@suse.de
- If open fails -1 is returned (close bug #2200)
* Fri Mar 03 2000 kukuk@suse.de
- Create /usr/bin/shutdown link for UltraSPARC kernel
@ -817,7 +820,7 @@ rm -rf ${RPM_BUILD_ROOT}
- ran old prepare_spec on spec file to switch to new prepare_spec.
* Wed Sep 08 1999 werner@suse.de
- Enable mingetty resetting the terminal
* Fri Aug 06 1999 werner@suse.de
* Sat Aug 07 1999 werner@suse.de
- New killproc-1.10
* startproc which is able to sleep
* better zombie handling