1 #! /bin/sh /usr/share/dpatch/dpatch-run
2 # 67_init_hddown.dpatch by Sebastian Reichelt
4 # Make sure SATA disks are powered down as well as IDE disks. This
5 # patch could use some more work to make it more dynamic when
6 # detecting SATA/SCSI disks. Closes: #348172
9 --- sysvinit-2.86.ds1/src/hddown.c 2004-06-09 14:47:45.000000000 +0200
10 +++ sysvinit-2.86.ds1-new/src/hddown.c 2006-01-16 18:05:48.000000000 +0100
13 * Find all IDE disks through /proc.
15 -static int find_idedisks(char **dev, int maxdev)
16 +static int find_idedisks(const char **dev, int maxdev, int *count)
24 if ((dd = opendir(PROC_IDE)) == NULL)
27 - while ((d = readdir(dd)) != NULL) {
28 + while (*count < maxdev && (d = readdir(dd)) != NULL) {
29 if (strncmp(d->d_name, "hd", 2) != 0)
35 snprintf(buf, sizeof(buf), DEV_BASE "/%s", d->d_name);
36 - dev[i++] = strdup(buf);
39 + dev[(*count)++] = strdup(buf);
42 - if (i < maxdev) dev[i] = NULL;
48 - * Put an IDE disk in standby mode.
49 + * Find all SCSI/SATA disks.
51 +static int find_scsidisks(const char **dev, int maxdev, int *count)
53 + if (*count < maxdev) dev[(*count)++] = DEV_BASE "/sda";
54 + if (*count < maxdev) dev[(*count)++] = DEV_BASE "/sdb";
55 + if (*count < maxdev) dev[(*count)++] = DEV_BASE "/sdc";
56 + if (*count < maxdev) dev[(*count)++] = DEV_BASE "/sdd";
57 + if (*count < maxdev) dev[(*count)++] = DEV_BASE "/sde";
58 + if (*count < maxdev) dev[(*count)++] = DEV_BASE "/sdf";
59 + if (*count < maxdev) dev[(*count)++] = DEV_BASE "/sdg";
60 + if (*count < maxdev) dev[(*count)++] = DEV_BASE "/sdh";
66 + * Open the device node of a disk.
68 +static int open_disk(const char *device)
70 + return open(device, O_RDWR);
74 + * Open device nodes of all disks, and store the file descriptors in fds.
75 + * This has to be done in advance because accessing the device nodes
76 + * might cause a disk to spin back up.
78 +static int open_disks(const char **disks, int *fds, int count)
82 + for (i = 0; i < count; i++)
83 + fds[i] = open_disk(disks[i]);
89 + * Put an IDE/SCSI/SATA disk in standby mode.
90 * Code stolen from hdparm.c
92 -static int do_standby_idedisk(char *device)
93 +static int do_standby_disk(int fd)
95 #ifndef WIN_STANDBYNOW1
96 #define WIN_STANDBYNOW1 0xE0
99 unsigned char args1[4] = {WIN_STANDBYNOW1,0,0,0};
100 unsigned char args2[4] = {WIN_STANDBYNOW2,0,0,0};
103 - if ((fd = open(device, O_RDWR)) < 0)
107 if (ioctl(fd, HDIO_DRIVE_CMD, &args1) &&
112 - * First find all IDE disks, then put them in standby mode.
113 + * Put all specified disks in standby mode.
115 +static int do_standby_disks(const int *fds, int count)
119 + for (i = 0; i < count; i++)
120 + do_standby_disk(fds[i]);
126 + * First find all IDE/SCSI/SATA disks, then put them in standby mode.
127 * This has the side-effect of flushing the writecache,
128 * which is exactly what we want on poweroff.
132 - char *disks[MAX_DISKS+1];
134 + const char *disks[MAX_DISKS];
135 + int fds[MAX_DISKS];
137 + int result1, result2;
139 - if (find_idedisks(disks, MAX_DISKS) < 0)
141 + result1 = find_idedisks(disks, MAX_DISKS, &count);
142 + result2 = find_scsidisks(disks, MAX_DISKS, &count);
144 - for (i = 0; disks[i] && i < MAX_DISKS; i++)
145 - do_standby_idedisk(disks[i]);
146 + open_disks(disks, fds, count);
147 + do_standby_disks(fds, count);
150 + return (result1 ? result1 : result2);
153 #else /* __linux__ */