Date: Thu, 16 Sep 2010 18:19:10 +0200 (CEST) From: Oliver Fromme <olli@lurza.secnetix.de> To: tijl@coosemans.org (Tijl Coosemans) Cc: freebsd-hackers@freebsd.org, mav@freebsd.org, Alexander Best <arundel@freebsd.org> Subject: Re: Summary: Re: Spin down HDD after disk sync or before power off Message-ID: <201009161619.o8GGJAmv035378@lurza.secnetix.de> In-Reply-To: <201009161742.24228.tijl@coosemans.org>
next in thread | previous in thread | raw e-mail | index | archive | help
Tijl Coosemans wrote: > On Thursday 16 September 2010 16:10:22 Oliver Fromme wrote: > > Tijl Coosemans wrote: > > > I would just spin down the disk in case of a halt. An unwanted spin > > > down is harmless compared to an emergency shutdown and usually the > > > intention is to power off rather than reboot. > > > > Is it? When I intend to power-off, I use shutdown -p, not > > shutdown -h. Quite often (but not always) when I halt a > > machine, I'm going to reboot to multi-user, not power off. > > Hmm, I suppose support for power off is ubiquitous nowadays. It used to > be that halt meant: bring the system in a state where we can safely cut > the power. In that case it makes sense to let halt spin down the disks. > If you intend to reboot why not explicitly reboot rather than halt? For example, I use shutdown -h in order to swap disks that are not hot-swappable, or other kind of hardware work that can be done while the machine is switched on. Of course, in that particular case the disk which is about to be swapped out should be spun down, while the others should not. But that's not a problem because I can use atacontrol(8) and camcontrol(8) to spin down a specific disk drive manually. > Also, to go from single to multi user mode you can just exit(1) the > shell. Yes, of course, that's a different matter. I've updated the patch for ada(4). It includes a bug fix (command1 vs. command2) and uses the howto flags passed to the shutdown function. Thanks again for pointing these out. Best regards Oliver --- ata_da.c.orig 2010-05-23 18:16:33.000000000 +0200 +++ ata_da.c 2010-09-16 17:21:10.000000000 +0200 @@ -42,6 +42,7 @@ #include <sys/eventhandler.h> #include <sys/malloc.h> #include <sys/cons.h> +#include <sys/reboot.h> #include <geom/geom_disk.h> #endif /* _KERNEL */ @@ -79,7 +80,8 @@ ADA_FLAG_CAN_TRIM = 0x080, ADA_FLAG_OPEN = 0x100, ADA_FLAG_SCTX_INIT = 0x200, - ADA_FLAG_CAN_CFA = 0x400 + ADA_FLAG_CAN_CFA = 0x400, + ADA_FLAG_CAN_POWERMGT = 0x800 } ada_flags; typedef enum { @@ -180,6 +182,10 @@ #define ADA_DEFAULT_SEND_ORDERED 1 #endif +#ifndef ADA_DEFAULT_SPINDOWN_SHUTDOWN +#define ADA_DEFAULT_SPINDOWN_SHUTDOWN 1 +#endif + /* * Most platforms map firmware geometry to actual, but some don't. If * not overridden, default to nothing. @@ -191,6 +197,7 @@ static int ada_retry_count = ADA_DEFAULT_RETRY; static int ada_default_timeout = ADA_DEFAULT_TIMEOUT; static int ada_send_ordered = ADA_DEFAULT_SEND_ORDERED; +static int ada_spindown_shutdown = ADA_DEFAULT_SPINDOWN_SHUTDOWN; SYSCTL_NODE(_kern_cam, OID_AUTO, ada, CTLFLAG_RD, 0, "CAM Direct Access Disk driver"); @@ -203,6 +210,9 @@ SYSCTL_INT(_kern_cam_ada, OID_AUTO, ada_send_ordered, CTLFLAG_RW, &ada_send_ordered, 0, "Send Ordered Tags"); TUNABLE_INT("kern.cam.ada.ada_send_ordered", &ada_send_ordered); +SYSCTL_INT(_kern_cam_ada, OID_AUTO, spindown_shutdown, CTLFLAG_RW, + &ada_spindown_shutdown, 0, "Spin down upon shutdown"); +TUNABLE_INT("kern.cam.ada.spindown_shutdown", &ada_spindown_shutdown); /* * ADA_ORDEREDTAG_INTERVAL determines how often, relative @@ -665,6 +675,8 @@ softc->flags |= ADA_FLAG_CAN_48BIT; if (cgd->ident_data.support.command2 & ATA_SUPPORT_FLUSHCACHE) softc->flags |= ADA_FLAG_CAN_FLUSHCACHE; + if (cgd->ident_data.support.command1 & ATA_SUPPORT_POWERMGT) + softc->flags |= ADA_FLAG_CAN_POWERMGT; if (cgd->ident_data.satacapabilities & ATA_SUPPORT_NCQ && cgd->inq_flags & SID_CmdQue) softc->flags |= ADA_FLAG_CAN_NCQ; @@ -1222,6 +1234,58 @@ /*getcount_only*/0); cam_periph_unlock(periph); } + + if (ada_spindown_shutdown == 0 || + (howto & (RB_HALT | RB_POWEROFF)) == 0) + return; + + DELAY(500000); + + TAILQ_FOREACH(periph, &adadriver.units, unit_links) { + union ccb ccb; + + /* If we paniced with lock held - not recurse here. */ + if (cam_periph_owned(periph)) + continue; + cam_periph_lock(periph); + softc = (struct ada_softc *)periph->softc; + /* + * We only spin-down the drive if it is capable of it.. + */ + if ((softc->flags & ADA_FLAG_CAN_POWERMGT) == 0) { + cam_periph_unlock(periph); + continue; + } + + /* XXX Hide this behind bootverbose? */ + xpt_print(periph->path, "spin-down\n"); + + xpt_setup_ccb(&ccb.ccb_h, periph->path, CAM_PRIORITY_NORMAL); + + ccb.ccb_h.ccb_state = ADA_CCB_DUMP; + cam_fill_ataio(&ccb.ataio, + 1, + adadone, + CAM_DIR_NONE, + 0, + NULL, + 0, + ada_default_timeout*1000); + + ata_28bit_cmd(&ccb.ataio, ATA_STANDBY_IMMEDIATE, 0, 0, 0); + xpt_polled_action(&ccb); + + if ((ccb.ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP) + xpt_print(periph->path, "Spin-down disk failed\n"); + + if ((ccb.ccb_h.status & CAM_DEV_QFRZN) != 0) + cam_release_devq(ccb.ccb_h.path, + /*relsim_flags*/0, + /*reduction*/0, + /*timeout*/0, + /*getcount_only*/0); + cam_periph_unlock(periph); + } } #endif /* _KERNEL */ -- Oliver Fromme, secnetix GmbH & Co. KG, Marktplatz 29, 85567 Grafing b. M. Handelsregister: Registergericht Muenchen, HRA 74606, Geschäftsfuehrung: secnetix Verwaltungsgesellsch. mbH, Handelsregister: Registergericht Mün- chen, HRB 125758, Geschäftsführer: Maik Bachmann, Olaf Erb, Ralf Gebhart FreeBSD-Dienstleistungen, -Produkte und mehr: http://www.secnetix.de/bsd "I have stopped reading Stephen King novels. Now I just read C code instead." -- Richard A. O'Keefe
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?201009161619.o8GGJAmv035378>