All of lore.kernel.org
 help / color / mirror / Atom feed
From: Jindrich Makovicka <makovick@gmail.com>
To: linux-ide@vger.kernel.org
Subject: Re: shutdown problem with 2.6.22 and debian 4.0
Date: Thu, 19 Jul 2007 19:20:57 +0200	[thread overview]
Message-ID: <20070719192057.4e4e8691@holly> (raw)
In-Reply-To: 46984CBB.1060006@gmail.com

[-- Attachment #1: Type: text/plain, Size: 1022 bytes --]

On Sat, 14 Jul 2007 13:10:35 +0900
Tejun Heo <htejun@gmail.com> wrote:

> Daniel Filipiuk wrote:
> > Hello, I have a doubt... I have Debian 4.0 and the kernel 2.6.22
> > compiled by me, and now when I shutdown my machine, appears a
> > message telling that the devices (/dev/sda5 , 6 and so on..) are
> > busy and cannot be unmounted, and tells me that I must update my
> > shutdown utility... Then the system go halt ... It doesn´t seem to
> > be any data loss , but I don´t want to leave this error message
> > forever hoping that I don´t loose anything... With the kernel
> > 2.6.21.5 this doesn´t happened, and the mounts were succesfully
> > unmounted. What should I do? Where I found this "shutdown utility"
> > source code?
> > 
> > Thank you very much, greetings,
> 
> Dunno about the busy part but you need to update the shutdown utility.
> Cc'ing Henrique.
> 

I replaced the Debian shutdown patch with the attached one and it seems
to do the job.

Regards,
-- 
Jindrich Makovicka

[-- Attachment #2: 67_init_hddown.dpatch --]
[-- Type: application/octet-stream, Size: 4461 bytes --]

#! /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
#
# Also exclude disks w/ manage_start_stop from the shutdown handling
# (makovick at gmail dot com)

@DPATCH@
--- sysvinit-2.86.ds1/src/hddown.c	2004-06-09 14:47:45.000000000 +0200
+++ sysvinit-2.86.ds1-new/src/hddown.c	2006-01-16 18:05:48.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,102 @@
 		}
 		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.
+ *	Basename w/ const char*.
+ */
+static const char* cbasename(const char *fn)
+{
+	const char *res = strrchr(fn, '/');
+	if (!res)
+		res = fn;
+	return res;
+}
+
+/*
+ *	Test whether the kernel manages the disk start/stop.
+ */
+static int manages_start_stop(const char *dev)
+{
+	const char *devbase = cbasename(dev);
+	const char *id;
+	char tmp[256], tmp2[256];
+	struct stat st;
+	ssize_t size;
+
+	tmp[255] = 0;
+	snprintf(tmp, 255, "/sys/block/%s/device", devbase);
+	memset(tmp2, 0, 256);
+	size = readlink(tmp, tmp2, 255);
+	if (size < 0)
+	    return 0;
+	id = cbasename(tmp2);
+	snprintf(tmp, 255, "/sys/class/scsi_disk/%s/manage_start_stop", id);
+	return stat(tmp, &st) == 0;
+}
+
+static const char *scsi_names[9] = {
+	DEV_BASE "/sda",
+	DEV_BASE "/sdb",
+	DEV_BASE "/sdc",
+	DEV_BASE "/sdd",
+	DEV_BASE "/sde",
+	DEV_BASE "/sdf",
+	DEV_BASE "/sdg",
+	DEV_BASE "/sdh",
+	NULL
+};
+
+/*
+ *	Find all SCSI/SATA disks.
+ */
+static int find_scsidisks(const char **dev, int maxdev, int *count)
+{
+	const char **sn = scsi_names;
+	
+	while (*count < maxdev && *sn) {
+		if (!manages_start_stop(*sn))
+			dev[(*count)++] = *sn;
+		sn++;
+	}
+	
+	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 +154,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 +166,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__ */

      reply	other threads:[~2007-07-19 17:30 UTC|newest]

Thread overview: 3+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2007-07-13 12:07 shutdown problem with 2.6.22 and debian 4.0 Daniel Filipiuk
2007-07-14  4:10 ` Tejun Heo
2007-07-19 17:20   ` Jindrich Makovicka [this message]

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20070719192057.4e4e8691@holly \
    --to=makovick@gmail.com \
    --cc=linux-ide@vger.kernel.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.