init
[vuplus_openvuplus] / meta-openvuplus / recipes-core / sysvinit / sysvinit / 67_init_hddown.dpatch
1 #! /bin/sh /usr/share/dpatch/dpatch-run
2 # 67_init_hddown.dpatch by Sebastian Reichelt
3 #
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
7
8 @DPATCH@
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
11 @@ -25,18 +25,17 @@
12  /*
13   *     Find all IDE disks through /proc.
14   */
15 -static int find_idedisks(char **dev, int maxdev)
16 +static int find_idedisks(const char **dev, int maxdev, int *count)
17  {
18         DIR *dd;
19         FILE *fp;
20         struct dirent *d;
21         char buf[256];
22 -       int i = 0;
23  
24         if ((dd = opendir(PROC_IDE)) == NULL)
25                 return -1;
26  
27 -       while ((d = readdir(dd)) != NULL) {
28 +       while (*count < maxdev && (d = readdir(dd)) != NULL) {
29                 if (strncmp(d->d_name, "hd", 2) != 0)
30                         continue;
31                 buf[0] = 0;
32 @@ -50,21 +49,58 @@
33                 }
34                 fclose(fp);
35                 snprintf(buf, sizeof(buf), DEV_BASE "/%s", d->d_name);
36 -               dev[i++] = strdup(buf);
37 -               if (i >= maxdev)
38 -                       break;
39 +               dev[(*count)++] = strdup(buf);
40         }
41         closedir(dd);
42 -       if (i < maxdev) dev[i] = NULL;
43  
44         return 0;
45  }
46  
47  /*
48 - *     Put an IDE disk in standby mode.
49 + *     Find all SCSI/SATA disks.
50 + */
51 +static int find_scsidisks(const char **dev, int maxdev, int *count)
52 +{
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";
61 +
62 +       return 0;
63 +}
64 +
65 +/*
66 + *     Open the device node of a disk.
67 + */
68 +static int open_disk(const char *device)
69 +{
70 +       return open(device, O_RDWR);
71 +}
72 +
73 +/*
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.
77 + */
78 +static int open_disks(const char **disks, int *fds, int count)
79 +{
80 +       int i;
81 +
82 +       for (i = 0; i < count; i++)
83 +               fds[i] = open_disk(disks[i]);
84 +
85 +       return 0;
86 +}
87 +
88 +/*
89 + *     Put an IDE/SCSI/SATA disk in standby mode.
90   *     Code stolen from hdparm.c
91   */
92 -static int do_standby_idedisk(char *device)
93 +static int do_standby_disk(int fd)
94  {
95  #ifndef WIN_STANDBYNOW1
96  #define WIN_STANDBYNOW1 0xE0
97 @@ -74,9 +110,8 @@
98  #endif
99         unsigned char args1[4] = {WIN_STANDBYNOW1,0,0,0};
100         unsigned char args2[4] = {WIN_STANDBYNOW2,0,0,0};
101 -       int fd;
102  
103 -       if ((fd = open(device, O_RDWR)) < 0)
104 +       if (fd < 0)
105                 return -1;
106  
107         if (ioctl(fd, HDIO_DRIVE_CMD, &args1) &&
108 @@ -87,22 +122,37 @@
109  }
110  
111  /*
112 - *     First find all IDE disks, then put them in standby mode.
113 + *     Put all specified disks in standby mode.
114 + */
115 +static int do_standby_disks(const int *fds, int count)
116 +{
117 +       int i;
118 +
119 +       for (i = 0; i < count; i++)
120 +               do_standby_disk(fds[i]);
121 +
122 +       return 0;
123 +}
124 +
125 +/*
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.
129   */
130  int hddown(void)
131  {
132 -       char *disks[MAX_DISKS+1];
133 -       int i;
134 +       const char *disks[MAX_DISKS];
135 +       int fds[MAX_DISKS];
136 +       int count = 0;
137 +       int result1, result2;
138  
139 -       if (find_idedisks(disks, MAX_DISKS) < 0)
140 -               return -1;
141 +       result1 = find_idedisks(disks, MAX_DISKS, &count);
142 +       result2 = find_scsidisks(disks, MAX_DISKS, &count);
143  
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);
148  
149 -       return 0;
150 +       return (result1 ? result1 : result2);
151  }
152  
153  #else /* __linux__ */