diff --git a/sysvinit-2.86-hddown.patch b/sysvinit-2.86-hddown.patch index 947e1c9..221f15c 100644 --- a/sysvinit-2.86-hddown.patch +++ b/sysvinit-2.86-hddown.patch @@ -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 #include #include -@@ -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 #include - ++#include ++ +#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 diff --git a/sysvinit.changes b/sysvinit.changes index 422818c..52066da 100644 --- a/sysvinit.changes +++ b/sysvinit.changes @@ -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 diff --git a/sysvinit.spec b/sysvinit.spec index c87e359..c7ba789 100644 --- a/sysvinit.spec +++ b/sysvinit.spec @@ -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