-----BEGIN PGP SIGNED MESSAGE----- Hash: SHA1 Kel Modderman pisze: > Package: sysvinit > Version: 2.86.ds1-38.1 > > Hi, > > I'm following up on this ticket, since I've not received any response for the > best part of 6 months. > > The patch I proposed here is, IMHO, the most complete of the ones offered > so far. Recently, I was made aware of someone also claiming [0] the patch [1] > from Werner Fink, discussed [2] on the novell bug tracker, would be great to > include into our own Debian version of sysvinit to fix the shutdown issue of > spinning down disks correctly (...or not). > > However, r1067 [3] was committed to pkg-sysvinit trunk, which merges the > changes done in the "libata-fixes" branch which was for testing [4]. Tejun Heo, > an active libata/kernel hacker, replied [5] with information that Werner Fink > was also working on this issue. Tejun was also active in the development of > the patch as seen on the novell bug discussion [2]. > > I emailed the list [6] with discussion requested at [4], created a patch for > the debian package [7], and tested the patch thoroughly on a very wide variety > of hardware from debian installed and live-cd environments over the last 6 > months. The patch works as advertised. > > opensuse 10.3 also contains a sysvinit using the mentioned patch. This means > it has seen widespread testing from a variety of people on a variety of > hardware. > > The patch matches the criteria set out at [8] about how hddown.c could best > handle this (except using /proc): > > [quote] > a) it uses sysfs and not /proc to locate disks, and that it locates > all IDE and SCSI/libata disks, or maybe do both /proc and sysfs. > b) that it verifies the state of kernel disk spindown control for > each disk, and for the disks where it is unavailable: > b1) issue cache sync to disk > b2) issue spin down to disk > c) for the disks where kernel spin down control is available, enable > it and skip to next disk. > [/quote] > > The patch does not suffer from limitation of an alternate patch offered to > fix the situation that is discussed at [9], which seems to be similar in > limitation to what has been merged [3]. > > Ok, there are too many damn numbers listed below with references. But you get > the picture I hope, that I'm concerned about the direction the maintainers [10] > intend to take in order to fix this issue, and that I've laid out as much > information, patch and help that I can to try and convince them there is a > better solution. > > Thanks, Kel. > > [0] http://lists.alioth.debian.org/pipermail/pkg-sysvinit-devel/2007-December/002141.html > [1] https://bugzilla.novell.com/attachment.cgi?id=145904 > [2] https://bugzilla.novell.com/show_bug.cgi?id=229210 > [3] http://lists.alioth.debian.org/pipermail/pkg-sysvinit-commits/2007-November/000955.html > [4] http://lists.alioth.debian.org/pipermail/pkg-sysvinit-devel/2007-June/001961.html > [5] http://lists.alioth.debian.org/pipermail/pkg-sysvinit-devel/2007-June/001963.html > [6] http://lists.alioth.debian.org/pipermail/pkg-sysvinit-devel/2007-June/001972.html > [7] http://lists.alioth.debian.org/pipermail/pkg-sysvinit-devel/2007-June/001974.html > [8] http://bugs.debian.org/cgi-bin/bugreport.cgi?bug=426224#10 > [9] http://bugs.debian.org/cgi-bin/bugreport.cgi?bug=436703 > [10] http://lists.alioth.debian.org/pipermail/pkg-sysvinit-devel/2007-December/002142.html > > > > _______________________________________________ > Pkg-sysvinit-devel mailing list > [EMAIL PROTECTED] > http://lists.alioth.debian.org/mailman/listinfo/pkg-sysvinit-devel > > Greetings,
I've sent a patch for Debian sysv init hdd down over a month ago (4.11.2007). Till now I haven't receive any comment regarding it. Could you please review it too ? Attached files (hdd.c and a patch in attachment). With best regards Artur Szymiec - -- - -------------------------------------------------------------------------- Registered User No 397465 Linux Debian 2.6.21-2-k7 i686 AMD Athlon(tm) XP 2800+ Conquer your Desktop! http://www.spreadkde.org/try_kde Reclaim Your Inbox! http://www.mozilla.org/products/thunderbird/ - -------------------------------------------------------------------------- -----BEGIN PGP SIGNATURE----- Version: GnuPG v1.4.6 (GNU/Linux) Comment: Using GnuPG with Mozilla - http://enigmail.mozdev.org iD8DBQFHYOC4bB2ld6kq2MsRAns/AKCPqqmZMNYKmJ1IN8qE1XlMQgyiQACfZ0Rq mvqtdYFV246B/SdzMpC0ZVo= =TTOA -----END PGP SIGNATURE-----
#! /bin/sh /usr/share/dpatch/dpatch-run # 67_init_hddown.dpatch by Sebastian Reichelt # # Make sure SATA disks are powered down as well as IDE disks. This # patch could use some more work to make it more dynamic when # detecting SATA/SCSI disks. Closes: #348172 @DPATCH@ --- sysvinit-2.86.ds1/src/hddown.c 2004-06-09 14:47:45.000000000 +0200 +++ sysvinit-2.86.ds1-new/src/hddown.c 2007-11-04 12:12:38.000000000 +0100 @@ -25,18 +25,17 @@ /* * Find all IDE disks through /proc. */ -static int find_idedisks(char **dev, int maxdev) +static int find_idedisks(const char **dev, int maxdev, int *count) { DIR *dd; FILE *fp; struct dirent *d; char buf[256]; - int i = 0; if ((dd = opendir(PROC_IDE)) == NULL) return -1; - while ((d = readdir(dd)) != NULL) { + while (*count < maxdev && (d = readdir(dd)) != NULL) { if (strncmp(d->d_name, "hd", 2) != 0) continue; buf[0] = 0; @@ -50,21 +49,81 @@ } fclose(fp); snprintf(buf, sizeof(buf), DEV_BASE "/%s", d->d_name); - dev[i++] = strdup(buf); - if (i >= maxdev) - break; + dev[(*count)++] = strdup(buf); } closedir(dd); - if (i < maxdev) dev[i] = NULL; return 0; } /* - * Put an IDE disk in standby mode. + * Find all SCSI/SATA disks. + */ +static int find_scsidisks(const char **dev, int maxdev, int *count) +{ + char mbuf[256],nbuf[256]; + DIR *dp; + struct dirent *ep; + int i=97; //set first sd letter to a + while (*count<maxdev && i<123) { + mbuf[0] = 0; + snprintf(mbuf,sizeof(mbuf),DEV_BASE "/sd%c",i); + if(access(mbuf,F_OK)==0) + { + nbuf[0] = 0; + snprintf(nbuf,sizeof(nbuf),"/sys/block/sd%c/device/",i); + if((dp = opendir(nbuf))){ + while ((ep = readdir(dp))){ + if(strstr(ep->d_name,"scsi_disk:")){ + nbuf[0]=0; + snprintf(nbuf,sizeof(nbuf),"/sys/block/sd%c/device/%s/manage_start_stop",i,ep->d_name); + if(access(nbuf,F_OK)==0){ + break; + }else{ + dev[(*count)++] = strdup(mbuf); + } + } + } + closedir (dp); + } + } + else + { + break; + } + i++; + } + return 0; +} + +/* + * Open the device node of a disk. + */ +static int open_disk(const char *device) +{ + return open(device, O_RDWR); +} + +/* + * Open device nodes of all disks, and store the file descriptors in fds. + * This has to be done in advance because accessing the device nodes + * might cause a disk to spin back up. + */ +static int open_disks(const char **disks, int *fds, int count) +{ + int i; + + for (i = 0; i < count; i++) + fds[i] = open_disk(disks[i]); + + return 0; +} + +/* + * Put an IDE/SCSI/SATA disk in standby mode. * Code stolen from hdparm.c */ -static int do_standby_idedisk(char *device) +static int do_standby_disk(int fd) { #ifndef WIN_STANDBYNOW1 #define WIN_STANDBYNOW1 0xE0 @@ -74,9 +133,8 @@ #endif unsigned char args1[4] = {WIN_STANDBYNOW1,0,0,0}; unsigned char args2[4] = {WIN_STANDBYNOW2,0,0,0}; - int fd; - if ((fd = open(device, O_RDWR)) < 0) + if (fd < 0) return -1; if (ioctl(fd, HDIO_DRIVE_CMD, &args1) && @@ -87,22 +145,37 @@ } /* - * First find all IDE disks, then put them in standby mode. + * Put all specified disks in standby mode. + */ +static int do_standby_disks(const int *fds, int count) +{ + int i; + + for (i = 0; i < count; i++) + do_standby_disk(fds[i]); + + return 0; +} + +/* + * First find all IDE/SCSI/SATA disks, then put them in standby mode. * This has the side-effect of flushing the writecache, * which is exactly what we want on poweroff. */ int hddown(void) { - char *disks[MAX_DISKS+1]; - int i; + const char *disks[MAX_DISKS]; + int fds[MAX_DISKS]; + int count = 0; + int result1, result2; - if (find_idedisks(disks, MAX_DISKS) < 0) - return -1; + result1 = find_idedisks(disks, MAX_DISKS, &count); + result2 = find_scsidisks(disks, MAX_DISKS, &count); - for (i = 0; disks[i] && i < MAX_DISKS; i++) - do_standby_idedisk(disks[i]); + open_disks(disks, fds, count); + do_standby_disks(fds, count); - return 0; + return (result1 ? result1 : result2); } #else /* __linux__ */
/* * hddown.c Find all disks on the system and * shut them down. * */ char *v_hddown = "@(#)hddown.c 1.02 22-Apr-2003 [EMAIL PROTECTED]"; #include <stdio.h> #include <stdlib.h> #include <unistd.h> #include <time.h> #include <string.h> #include <fcntl.h> #include <dirent.h> #ifdef __linux__ #include <sys/ioctl.h> #include <linux/hdreg.h> #define MAX_DISKS 64 #define PROC_IDE "/proc/ide" #define DEV_BASE "/dev" /* * Find all IDE disks through /proc. */ static int find_idedisks(const char **dev, int maxdev, int *count) { DIR *dd; FILE *fp; struct dirent *d; char buf[256]; if ((dd = opendir(PROC_IDE)) == NULL) return -1; while (*count < maxdev && (d = readdir(dd)) != NULL) { if (strncmp(d->d_name, "hd", 2) != 0) continue; buf[0] = 0; snprintf(buf, sizeof(buf), PROC_IDE "/%s/media", d->d_name); if ((fp = fopen(buf, "r")) == NULL) continue; if (fgets(buf, sizeof(buf), fp) == 0 || strcmp(buf, "disk\n") != 0) { fclose(fp); continue; } fclose(fp); snprintf(buf, sizeof(buf), DEV_BASE "/%s", d->d_name); dev[(*count)++] = strdup(buf); } closedir(dd); return 0; } /* * Find all SCSI/SATA disks. */ static int find_scsidisks(const char **dev, int maxdev, int *count) { char mbuf[256],nbuf[256]; DIR *dp; struct dirent *ep; int i=97; //set first sd letter to a while (*count<maxdev && i<123) { mbuf[0] = 0; snprintf(mbuf,sizeof(mbuf),DEV_BASE "/sd%c",i); if(access(mbuf,F_OK)==0) { nbuf[0] = 0; snprintf(nbuf,sizeof(nbuf),"/sys/block/sd%c/device/",i); if((dp = opendir(nbuf))){ while ((ep = readdir(dp))){ if(strstr(ep->d_name,"scsi_disk:")){ nbuf[0]=0; snprintf(nbuf,sizeof(nbuf),"/sys/block/sd%c/device/%s/manage_start_stop",i,ep->d_name); if(access(nbuf,F_OK)==0){ break; }else{ dev[(*count)++] = strdup(mbuf); } } } closedir (dp); } } else { break; } i++; } return 0; } /* * Open the device node of a disk. */ static int open_disk(const char *device) { return open(device, O_RDWR); } /* * Open device nodes of all disks, and store the file descriptors in fds. * This has to be done in advance because accessing the device nodes * might cause a disk to spin back up. */ static int open_disks(const char **disks, int *fds, int count) { int i; for (i = 0; i < count; i++) fds[i] = open_disk(disks[i]); return 0; } /* * Put an IDE/SCSI/SATA disk in standby mode. * Code stolen from hdparm.c */ static int do_standby_disk(int fd) { #ifndef WIN_STANDBYNOW1 #define WIN_STANDBYNOW1 0xE0 #endif #ifndef WIN_STANDBYNOW2 #define WIN_STANDBYNOW2 0x94 #endif unsigned char args1[4] = {WIN_STANDBYNOW1,0,0,0}; unsigned char args2[4] = {WIN_STANDBYNOW2,0,0,0}; if (fd < 0) return -1; if (ioctl(fd, HDIO_DRIVE_CMD, &args1) && ioctl(fd, HDIO_DRIVE_CMD, &args2)) return -1; return 0; } /* * Put all specified disks in standby mode. */ static int do_standby_disks(const int *fds, int count) { int i; for (i = 0; i < count; i++) do_standby_disk(fds[i]); return 0; } /* * First find all IDE/SCSI/SATA disks, then put them in standby mode. * This has the side-effect of flushing the writecache, * which is exactly what we want on poweroff. */ int hddown(void) { const char *disks[MAX_DISKS]; int fds[MAX_DISKS]; int count = 0; int result1, result2; result1 = find_idedisks(disks, MAX_DISKS, &count); result2 = find_scsidisks(disks, MAX_DISKS, &count); open_disks(disks, fds, count); do_standby_disks(fds, count); return (result1 ? result1 : result2); } #else /* __linux__ */ int hddown(void) { return 0; } #endif /* __linux__ */ #ifdef STANDALONE int main(int argc, char **argv) { return (hddown() == 0); } #endif