Hello community,
here is the log from the commit of package hdparm for openSUSE:Factory checked in at 2012-10-03 07:45:27
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Comparing /work/SRC/openSUSE:Factory/hdparm (Old)
and /work/SRC/openSUSE:Factory/.hdparm.new (New)
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Package is "hdparm", Maintainer is "VDziewiecki@suse.com"
Changes:
--------
--- /work/SRC/openSUSE:Factory/hdparm/hdparm.changes 2012-03-07 13:42:36.000000000 +0100
+++ /work/SRC/openSUSE:Factory/.hdparm.new/hdparm.changes 2012-10-03 07:45:29.000000000 +0200
@@ -1,0 +2,18 @@
+Mon Oct 1 10:53:29 UTC 2012 - puzel@suse.com
+
+- update to hdparm-9.42
+ - fix ordering of -S -y flags
+ - spelling, typo, and formatting fixes for manpage and others
+ - set block-count to 1 for Security commands sent via SAT (sgio)
+ - use FIGETBSZ to determine filesystem block size for fibmap -- needed for FAT
+ - fix master password revcode handling
+ - try and fix reg_flags (again!) for old IDE taskfile ioctls
+ - fixed '&&' bug in dco_identify code
+ - force sector dumps (read-sector, identify, ..) to use le16 output format
+ - proper SCT identify info courtesy of Leonid Evdokimov
+ - updated raid1ext4trim.sh-1.5 script
+ - avoid HDIO_GETGEO_BIG when possible (doesn't exist in
+ linux-2.6.xx and beyond)
+ - pad secure erase timeouts by 30minutes rather than 5minutes.
+
+-------------------------------------------------------------------
Old:
----
hdparm-9.39.tar.gz
New:
----
hdparm-9.42.tar.gz
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Other differences:
------------------
++++++ hdparm.spec ++++++
--- /var/tmp/diff_new_pack.NKje3M/_old 2012-10-03 07:45:30.000000000 +0200
+++ /var/tmp/diff_new_pack.NKje3M/_new 2012-10-03 07:45:30.000000000 +0200
@@ -19,7 +19,7 @@
Name: hdparm
PreReq: %insserv_prereq %fillup_prereq coreutils
Provides: base:/sbin/hdparm
-Version: 9.39
+Version: 9.42
Release: 0
Summary: A Program to get and set hard disk parameters
License: SUSE-Permissive
++++++ hdparm-9.39.tar.gz -> hdparm-9.42.tar.gz ++++++
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/hdparm-9.39/Changelog new/hdparm-9.42/Changelog
--- old/hdparm-9.39/Changelog 2012-02-06 14:45:27.000000000 +0100
+++ new/hdparm-9.42/Changelog 2012-09-28 20:10:36.000000000 +0200
@@ -1,3 +1,18 @@
+hdparm-9.42
+ - fix ordering of -S -y flags
+ - spelling, typo, and formatting fixes for manpage and others
+ - set block-count to 1 for Security commands sent via SAT (sgio)
+ - use FIGETBSZ to determine filesystem block size for fibmap -- needed for FAT
+ - fix master password revcode handling
+ - try and fix reg_flags (again!) for old IDE taskfile ioctls
+ - fixed '&&' bug in dco_identify code
+ - force sector dumps (read-sector, identify, ..) to use le16 output format
+hdparm-9.41
+ - proper SCT identify info courtesy of Leonid Evdokimov
+ - updated raid1ext4trim.sh-1.5 script
+hdparm-9.40
+ - avoid HDIO_GETGEO_BIG when possible (doesn't exist in linux-2.6.xx and beyond)
+ - pad secure erase timeouts by 30minutes rather than 5minutes.
hdparm-9.39
- added -R flag to control Read-Write-Verify feature, courtesy of Gordan Bobic
- nuked leftover sgio.c.orig file
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/hdparm-9.39/TODO new/hdparm-9.42/TODO
--- old/hdparm-9.39/TODO 2010-03-09 15:20:02.000000000 +0100
+++ new/hdparm-9.42/TODO 2012-09-28 18:51:04.000000000 +0200
@@ -1,8 +1,6 @@
Mark's TO-DO list for hdparm:
============================
-- Make parameter parsing/etc.. LBA48 safe everywhere (instead of merely u32).
-
- Add "wipe-drive" functionality via SCT WRITE_SAME (or manual).
- Add "surface-scan" functionality via SG READ_VERIFY.
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/hdparm-9.39/fibmap.c new/hdparm-9.42/fibmap.c
--- old/hdparm-9.39/fibmap.c 2010-11-24 22:20:17.000000000 +0100
+++ new/hdparm-9.42/fibmap.c 2012-09-28 19:40:23.000000000 +0200
@@ -222,7 +222,7 @@
int fd, err;
struct stat st;
__u64 start_lba = 0;
- unsigned int sectors_per_block;
+ unsigned int sectors_per_block, blksize;
if ((fd = open(file_name, O_RDONLY)) == -1) {
err = errno;
@@ -253,11 +253,15 @@
close(fd);
return EIO;
}
-
- sectors_per_block = st.st_blksize / sector_bytes;
- printf("\n%s:\n filesystem blocksize %lu, begins at LBA %llu;"
+ if((err=ioctl(fd,FIGETBSZ,&blksize))){
+ fprintf(stderr, "Unable to determine block size, aborting.\n");
+ close(fd);
+ return err;
+ };
+ sectors_per_block = blksize / sector_bytes;
+ printf("\n%s:\n filesystem blocksize %u, begins at LBA %llu;"
" assuming %u byte sectors.\n",
- file_name, (unsigned long)st.st_blksize, start_lba, sector_bytes);
+ file_name, blksize, start_lba, sector_bytes);
printf("%12s %10s %10s %10s\n", "byte_offset", "begin_LBA", "end_LBA", "sectors");
if (st.st_size == 0) {
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/hdparm-9.39/geom.c new/hdparm-9.42/geom.c
--- old/hdparm-9.39/geom.c 2010-11-24 22:54:48.000000000 +0100
+++ new/hdparm-9.42/geom.c 2012-05-04 15:20:57.000000000 +0200
@@ -144,7 +144,7 @@
{
static struct local_hd_geometry g;
static struct local_hd_big_geometry bg;
- int err = 0;
+ int err = 0, try_getgeo_big_first = 1;
if (nsectors) {
err = get_sector_count(fd, nsectors);
@@ -163,14 +163,17 @@
{
*start_lba = result;
start_lba = NULL;
+ try_getgeo_big_first = 0; /* if kernel has sysfs, it probably lacks GETGEO_BIG */
} else if (fd_is_raid(fd)) {
- *start_lba = START_LBA_UNKNOWN; /* RAID: no such thing as a "start_lba" */
+ *start_lba = START_LBA_UNKNOWN; /* RAID: no such thing as a "start_lba" */
start_lba = NULL;
+ try_getgeo_big_first = 0; /* no point even trying it on RAID */
}
}
if (cyls || heads || sects || start_lba) {
- if (!ioctl(fd, HDIO_GETGEO_BIG, &bg)) {
+ /* Skip HDIO_GETGEO_BIG (doesn't exist) on kernels with sysfs (>= 2.6.xx) */
+ if (try_getgeo_big_first && !ioctl(fd, HDIO_GETGEO_BIG, &bg)) {
if (cyls) *cyls = bg.cylinders;
if (heads) *heads = bg.heads;
if (sects) *sects = bg.sectors;
@@ -180,6 +183,11 @@
if (heads) *heads = g.heads;
if (sects) *sects = g.sectors;
if (start_lba) *start_lba = g.start;
+ } else if (!try_getgeo_big_first && !ioctl(fd, HDIO_GETGEO_BIG, &bg)) {
+ if (cyls) *cyls = bg.cylinders;
+ if (heads) *heads = bg.heads;
+ if (sects) *sects = bg.sectors;
+ if (start_lba) *start_lba = bg.start;
} else {
err = errno;
perror(" HDIO_GETGEO failed");
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/hdparm-9.39/hdparm.8 new/hdparm-9.42/hdparm.8
--- old/hdparm-9.39/hdparm.8 2012-02-03 04:24:42.000000000 +0100
+++ new/hdparm-9.42/hdparm.8 2012-09-28 20:12:12.000000000 +0200
@@ -1,4 +1,4 @@
-.TH HDPARM 8 "January 2012" "Version 9.39"
+.TH HDPARM 8 "September 2012" "Version 9.42"
.SH NAME
hdparm \- get/set SATA/IDE device parameters
@@ -346,9 +346,9 @@
option should therefore only be set after one has achieved confidence in
correct system operation with a chosen set of configuration settings.
In practice, all that is typically necessary to test a configuration
-(prior to using -k) is to verify that the drive can be read/written,
+(prior to using \-k) is to verify that the drive can be read/written,
and that no error logs (kernel messages) are generated in the process
-(look in /var/adm/messages on most systems).
+(look in /var/log/messages on most systems).
.TP
.I -K
Set the drive\'s "keep_features_over_reset" flag. Setting this enables
@@ -579,7 +579,7 @@
share a power supply. Primarily for use in large RAID setups.
This feature is usually disabled and the drive is powered-up in the
.B active
-mode (see -C above).
+mode (see \-C above).
Note that a drive may also allow enabling this feature by a jumper.
Some SATA drives support the control of this feature by pin 11 of
the SATA power connector. In these cases, this command may be
@@ -674,7 +674,7 @@
provides a safe fix for the problem for use with earlier kernels.
.TP
.I -v
-Display some basic settings, similar to -acdgkmur for IDE.
+Display some basic settings, similar to \-acdgkmur for IDE.
This is also the default behaviour when no options are specified.
.TP
.I --verbose
@@ -767,19 +767,19 @@
.B USE AT YOUR OWN RISK.
.TP
.I --security-help
-Display terse usage info for all of the --security-* options.
+Display terse usage info for all of the \--security-* options.
.TP
.I --security-freeze
Freeze the drive\'s security settings.
The drive does not accept any security commands until next power-on reset.
-Use this function in combination with --security-unlock to protect drive
+Use this function in combination with \--security-unlock to protect drive
from any attempt to set a new password. Can be used standalone, too.
No other options are permitted on the command line with this one.
.TP
.I --security-unlock PWD
Unlock the drive, using password PWD.
Password is given as an ASCII string and is padded with NULs to reach 32 bytes.
-The applicable drive password is selected with the --user-master switch
+The applicable drive password is selected with the \--user-master switch
(default is "user" password).
No other options are permitted on the command line with this one.
.TP
@@ -790,15 +790,15 @@
Use the special password
.B NULL
to set an empty password.
-The applicable drive password is selected with the --user-master switch
+The applicable drive password is selected with the \--user-master switch
(default is "user" password)
-and the applicable security mode with the --security-mode switch.
+and the applicable security mode with the \--security-mode switch.
No other options are permitted on the command line with this one.
.TP
.I --security-disable PWD
Disable drive locking, using password PWD.
Password is given as an ASCII string and is padded with NULs to reach 32 bytes.
-The applicable drive password is selected with the --user-master switch
+The applicable drive password is selected with the \--user-master switch
(default is "user" password).
No other options are permitted on the command line with this one.
.TP
@@ -809,7 +809,7 @@
Use the special password
.B NULL
to represent an empty password.
-The applicable drive password is selected with the --user-master switch
+The applicable drive password is selected with the \--user-master switch
(default is "user" password).
No other options are permitted on the command line with this one.
.TP
@@ -817,15 +817,15 @@
Enhanced erase (locked) drive, using password PWD
.B (DANGEROUS).
Password is given as an ASCII string and is padded with NULs to reach 32 bytes.
-The applicable drive password is selected with the --user-master switch
+The applicable drive password is selected with the \--user-master switch
(default is "user" password).
No other options are permitted on the command line with this one.
.TP
.I --user-master USER
Specifies which password (user/master) to select.
.B Defaults to "user" password.
-Only useful in combination with --security-unlock, --security-set-pass,
---security-disable, --security-erase or --security-erase-enhanced.
+Only useful in combination with \--security-unlock, \--security-set-pass,
+\--security-disable, \--security-erase or \--security-erase-enhanced.
u user password
m master password
@@ -833,7 +833,7 @@
.I --security-mode MODE
Specifies which security mode (high/maximum) to set.
.B Defaults to high.
-Only useful in combination with --security-set-pass.
+Only useful in combination with \--security-set-pass.
h high security
m maximum security
@@ -850,7 +850,7 @@
a few drive/controller combinations are not 100% compatible. Filesystem
corruption may result. Backup everything before experimenting!
.PP
-Some options (e.g. -r for SCSI) may not work with old kernels as
+Some options (e.g. \-r for SCSI) may not work with old kernels as
necessary ioctl()\'s were not supported.
.PP
Although this utility is intended primarily for use with SATA/IDE hard disk
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/hdparm-9.39/hdparm.c new/hdparm-9.42/hdparm.c
--- old/hdparm-9.39/hdparm.c 2012-02-03 04:24:33.000000000 +0100
+++ new/hdparm-9.42/hdparm.c 2012-09-28 20:12:01.000000000 +0200
@@ -1,5 +1,7 @@
-/* hdparm.c - Command line interface to get/set hard disk parameters */
-/* - by Mark Lord (C) 1994-2012 -- freely distributable */
+/*
+ * hdparm.c - Command line interface to get/set hard disk parameters.
+ * - by Mark Lord (C) 1994-2012 -- freely distributable.
+ */
#define _LARGEFILE64_SOURCE /*for lseek64*/
#define _BSD_SOURCE /* for strtoll() */
#include
@@ -23,6 +25,7 @@
#include
#include
#include
+#include
#include
#include "hdparm.h"
@@ -35,7 +38,7 @@
extern const char *minor_str[];
-#define VERSION "v9.39"
+#define VERSION "v9.42"
#ifndef O_DIRECT
#define O_DIRECT 040000 /* direct disk access, not easily obtained from headers */
@@ -719,7 +722,7 @@
if (timeout < estimate)
timeout = estimate;
} else {
- timeout = (timeout * 2) + 5; /* Add on a 5min margin */
+ timeout = (timeout * 2) + 30; /* Add on a 30min margin */
}
}
}
@@ -749,6 +752,8 @@
r->dphase = TASKFILE_DPHASE_PIO_OUT;
r->obytes = 512;
r->lob.command = security_command;
+ r->oflags.lob.nsect = 1;
+ r->lob.nsect = 1;
data = (__u8*)r->data;
data[0] = security_master & 0x01;
memcpy(data+2, security_password, 32);
@@ -777,7 +782,7 @@
if (!id)
exit(EIO);
revcode = id[92];
- if (revcode == 0xffff)
+ if (revcode == 0xfffe)
revcode = 0;
revcode += 1;
data[34] = revcode;
@@ -922,8 +927,18 @@
unsigned int i;
for (i = 0; i < (count*256/8); ++i) {
- printf("%04x %04x %04x %04x %04x %04x %04x %04x\n", w[0], w[1], w[2], w[3], w[4], w[5], w[6], w[7]);
+#if 0
+ printf("%04x %04x %04x %04x %04x %04x %04x %04x\n",
+ w[0], w[1], w[2], w[3], w[4], w[5], w[6], w[7]);
w += 8;
+#else
+ int word;
+ for (word = 0; word < 8; ++word) {
+ printf("%04x", le16toh(w[0]));
+ ++w;
+ putchar(word == 7 ? '\n' : ' ');
+ }
+#endif
}
}
@@ -1517,7 +1532,7 @@
" --security-erase PASSWD Erase a (locked) drive.\n"
" --security-erase-enhanced PASSWD Enhanced-erase a (locked) drive.\n"
"\n"
- " The above four commands may optionally be preceeded by these options:\n"
+ " The above four commands may optionally be preceded by these options:\n"
" --security-mode LEVEL Use LEVEL to select security level:\n"
" h high security (default).\n"
" m maximum security.\n"
@@ -1841,6 +1856,17 @@
if (!wcache)
err = flush_wcache(fd);
}
+ if (set_standby) {
+ __u8 args[4] = {ATA_OP_SETIDLE,standby,0,0};
+ if (get_standby) {
+ printf(" setting standby to %u", standby);
+ interpret_standby();
+ }
+ if (do_drive_cmd(fd, args, 0)) {
+ err = errno;
+ perror(" HDIO_DRIVE_CMD(setidle) failed");
+ }
+ }
if (set_standbynow) {
__u8 args1[4] = {ATA_OP_STANDBYNOW1,0,0,0};
__u8 args2[4] = {ATA_OP_STANDBYNOW2,0,0,0};
@@ -1917,17 +1943,6 @@
perror(" HDIO_DRIVE_CMD(seagatepwrsave) failed");
}
}
- if (set_standby) {
- __u8 args[4] = {ATA_OP_SETIDLE,standby,0,0};
- if (get_standby) {
- printf(" setting standby to %u", standby);
- interpret_standby();
- }
- if (do_drive_cmd(fd, args, 0)) {
- err = errno;
- perror(" HDIO_DRIVE_CMD(setidle) failed");
- }
- }
if (set_busstate) {
if (get_busstate)
printf(" setting bus state to %d (%s)\n", busstate, busstate_str(busstate));
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/hdparm-9.39/hdparm.lsm new/hdparm-9.42/hdparm.lsm
--- old/hdparm-9.39/hdparm.lsm 2012-02-03 04:26:50.000000000 +0100
+++ new/hdparm-9.42/hdparm.lsm 2012-09-28 20:12:45.000000000 +0200
@@ -1,9 +1,12 @@
Begin4
Title: hdparm
-Version: 9.39
-Entered-date: 2012-02-02
+Version: 9.42
+Entered-date: 2012-09-28
Description: hdparm - get/set hard disk parameters for Linux SATA/IDE drives.
- v9.38 Added -R, courtesy of Gordan Bobic
+ v9.42 lots of fixes from the sourceforge queue
+ v9.41 updated SCT identification, other small fixes.
+ v9.40 internal release
+ v9.39 Added -R, courtesy of Gordan Bobic
v9.38 Added -J, fixed erase timeouts, updated wiper.sh
v9.37 Enable --fibmap to work on RAID1; other tweaks
v9.36 manpage updates, wiper.sh version 3.1
@@ -113,7 +116,7 @@
Maintained-by: mlord@pobox.com (Mark Lord)
Primary-site: http://sourceforge.net/projects/hdparm/
Alternate-site: http://www.ibiblio.org/pub/Linux/system/hardware
- 127K hdparm-9.39.tar.gz
+ 127K hdparm-9.42.tar.gz
4K hdparm.lsm
Platforms: Linux
Copying-policy: BSD License
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/hdparm-9.39/identify.c new/hdparm-9.42/identify.c
--- old/hdparm-9.39/identify.c 2011-12-04 23:49:22.000000000 +0100
+++ new/hdparm-9.42/identify.c 2012-09-28 18:55:17.000000000 +0200
@@ -514,8 +514,8 @@
"SCT Data Tables (AC5)", /* word 206 bit 5 */
"SCT Features Control (AC4)", /* word 206 bit 4 */
"SCT Error Recovery Control (AC3)", /* word 206 bit 3 */
- "SCT LBA Segment Access (AC2)", /* word 206 bit 2 */
- "SCT Long Sector Access (AC1)", /* word 206 bit 1 */
+ "SCT Write Same (AC2)", /* word 206 bit 2 */
+ "SCT Read/Write Long (AC1), obsolete", /* word 206 bit 1: obsolete per T13/e08153r1 */
"SMART Command Transport (SCT) feature set" /* word 206 bit 0 */
};
@@ -1473,7 +1473,7 @@
}
putchar('\n');
- if (dco[8] && 0x1f) {
+ if (dco[8] & 0x1f) {
printf("\tSATA command/feature sets:\n\t\t");
if (dco[0] < 2)
printf(" (?):");
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/hdparm-9.39/sgio.h new/hdparm-9.42/sgio.h
--- old/hdparm-9.39/sgio.h 2012-01-06 15:45:00.000000000 +0100
+++ new/hdparm-9.42/sgio.h 2012-09-28 19:25:46.000000000 +0200
@@ -115,7 +115,8 @@
TASKFILE_DPHASE_PIO_OUT = 4, /* ide: TASKFILE_OUT */
};
-struct reg_flags {
+union reg_flags {
+ unsigned all :16;
union {
unsigned lob_all : 8;
struct {
@@ -142,7 +143,7 @@
unsigned command : 1;
} hob;
};
-};
+} __attribute__((packed));
struct taskfile_regs {
__u8 data;
@@ -158,8 +159,8 @@
struct hdio_taskfile {
struct taskfile_regs lob;
struct taskfile_regs hob;
- struct reg_flags oflags;
- struct reg_flags iflags;
+ union reg_flags oflags;
+ union reg_flags iflags;
int dphase;
int cmd_req; /* IDE command_type */
unsigned long obytes;
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/hdparm-9.39/sgio.h.xx new/hdparm-9.42/sgio.h.xx
--- old/hdparm-9.39/sgio.h.xx 1970-01-01 01:00:00.000000000 +0100
+++ new/hdparm-9.42/sgio.h.xx 2012-09-28 19:25:46.000000000 +0200
@@ -0,0 +1,233 @@
+/* prototypes and stuff for ATA command ioctls */
+
+#include
+
+enum {
+ ATA_OP_DSM = 0x06, // Data Set Management (TRIM)
+ ATA_OP_READ_PIO = 0x20,
+ ATA_OP_READ_PIO_ONCE = 0x21,
+ ATA_OP_READ_LONG = 0x22,
+ ATA_OP_READ_LONG_ONCE = 0x23,
+ ATA_OP_READ_PIO_EXT = 0x24,
+ ATA_OP_READ_DMA_EXT = 0x25,
+ ATA_OP_READ_FPDMA = 0x60, // NCQ
+ ATA_OP_WRITE_PIO = 0x30,
+ ATA_OP_WRITE_LONG = 0x32,
+ ATA_OP_WRITE_LONG_ONCE = 0x33,
+ ATA_OP_WRITE_PIO_EXT = 0x34,
+ ATA_OP_WRITE_DMA_EXT = 0x35,
+ ATA_OP_WRITE_FPDMA = 0x61, // NCQ
+ ATA_OP_READ_VERIFY = 0x40,
+ ATA_OP_READ_VERIFY_ONCE = 0x41,
+ ATA_OP_READ_VERIFY_EXT = 0x42,
+ ATA_OP_WRITE_UNC_EXT = 0x45, // lba48, no data, uses feat reg
+ ATA_OP_FORMAT_TRACK = 0x50,
+ ATA_OP_DOWNLOAD_MICROCODE = 0x92,
+ ATA_OP_STANDBYNOW2 = 0x94,
+ ATA_OP_CHECKPOWERMODE2 = 0x98,
+ ATA_OP_SLEEPNOW2 = 0x99,
+ ATA_OP_PIDENTIFY = 0xa1,
+ ATA_OP_READ_NATIVE_MAX = 0xf8,
+ ATA_OP_READ_NATIVE_MAX_EXT = 0x27,
+ ATA_OP_SMART = 0xb0,
+ ATA_OP_DCO = 0xb1,
+ ATA_OP_ERASE_SECTORS = 0xc0,
+ ATA_OP_READ_DMA = 0xc8,
+ ATA_OP_WRITE_DMA = 0xca,
+ ATA_OP_DOORLOCK = 0xde,
+ ATA_OP_DOORUNLOCK = 0xdf,
+ ATA_OP_STANDBYNOW1 = 0xe0,
+ ATA_OP_IDLEIMMEDIATE = 0xe1,
+ ATA_OP_SETIDLE = 0xe3,
+ ATA_OP_SET_MAX = 0xf9,
+ ATA_OP_SET_MAX_EXT = 0x37,
+ ATA_OP_SET_MULTIPLE = 0xc6,
+ ATA_OP_CHECKPOWERMODE1 = 0xe5,
+ ATA_OP_SLEEPNOW1 = 0xe6,
+ ATA_OP_FLUSHCACHE = 0xe7,
+ ATA_OP_FLUSHCACHE_EXT = 0xea,
+ ATA_OP_IDENTIFY = 0xec,
+ ATA_OP_SETFEATURES = 0xef,
+ ATA_OP_SECURITY_SET_PASS = 0xf1,
+ ATA_OP_SECURITY_UNLOCK = 0xf2,
+ ATA_OP_SECURITY_ERASE_PREPARE = 0xf3,
+ ATA_OP_SECURITY_ERASE_UNIT = 0xf4,
+ ATA_OP_SECURITY_FREEZE_LOCK = 0xf5,
+ ATA_OP_SECURITY_DISABLE = 0xf6,
+ ATA_OP_VENDOR_SPECIFIC_0x80 = 0x80,
+};
+
+/*
+ * Some useful ATA register bits
+ */
+enum {
+ ATA_USING_LBA = (1 << 6),
+ ATA_STAT_DRQ = (1 << 3),
+ ATA_STAT_ERR = (1 << 0),
+};
+
+/*
+ * Useful parameters for init_hdio_taskfile():
+ */
+enum { RW_READ = 0,
+ RW_WRITE = 1,
+ LBA28_OK = 0,
+ LBA48_FORCE = 1,
+};
+
+/*
+ * Definitions and structures for use with SG_IO + ATA_16:
+ */
+struct ata_lba_regs {
+ __u8 feat;
+ __u8 nsect;
+ __u8 lbal;
+ __u8 lbam;
+ __u8 lbah;
+};
+struct ata_tf {
+ __u8 dev;
+ __u8 command;
+ __u8 error;
+ __u8 status;
+ __u8 is_lba48;
+ struct ata_lba_regs lob;
+ struct ata_lba_regs hob;
+};
+
+/*
+ * Definitions and structures for use with HDIO_DRIVE_TASKFILE:
+ */
+
+enum {
+ /*
+ * These (redundantly) specify the category of the request
+ */
+ TASKFILE_CMD_REQ_NODATA = 0, /* ide: IDE_DRIVE_TASK_NO_DATA */
+ TASKFILE_CMD_REQ_IN = 2, /* ide: IDE_DRIVE_TASK_IN */
+ TASKFILE_CMD_REQ_OUT = 3, /* ide: IDE_DRIVE_TASK_OUT */
+ TASKFILE_CMD_REQ_RAW_OUT= 4, /* ide: IDE_DRIVE_TASK_RAW_WRITE */
+ /*
+ * These specify the method of transfer (pio, dma, multi, ..)
+ */
+ TASKFILE_DPHASE_NONE = 0, /* ide: TASKFILE_IN */
+ TASKFILE_DPHASE_PIO_IN = 1, /* ide: TASKFILE_IN */
+ TASKFILE_DPHASE_PIO_OUT = 4, /* ide: TASKFILE_OUT */
+};
+
+union reg_flags {
+ unsigned all :16;
+ union {
+ unsigned lob_all : 8;
+ struct {
+ unsigned data : 1;
+ unsigned feat : 1;
+ unsigned lbal : 1;
+ unsigned nsect : 1;
+ unsigned lbam : 1;
+ unsigned lbah : 1;
+ unsigned dev : 1;
+ unsigned command : 1;
+ } lob;
+ };
+ union {
+ unsigned hob_all : 8;
+ struct {
+ unsigned data : 1;
+ unsigned feat : 1;
+ unsigned lbal : 1;
+ unsigned nsect : 1;
+ unsigned lbam : 1;
+ unsigned lbah : 1;
+ unsigned dev : 1;
+ unsigned command : 1;
+ } hob;
+ };
+} __attribute__((packed));
+
+struct taskfile_regs {
+ __u8 data;
+ __u8 feat;
+ __u8 nsect;
+ __u8 lbal;
+ __u8 lbam;
+ __u8 lbah;
+ __u8 dev;
+ __u8 command;
+};
+
+struct hdio_taskfile {
+ struct taskfile_regs lob;
+ struct taskfile_regs hob;
+ union reg_flags oflags;
+ union reg_flags iflags;
+ int dphase;
+ int cmd_req; /* IDE command_type */
+ unsigned long obytes;
+ unsigned long ibytes;
+ __u16 data[0];
+};
+
+struct scsi_sg_io_hdr {
+ int interface_id;
+ int dxfer_direction;
+ unsigned char cmd_len;
+ unsigned char mx_sb_len;
+ unsigned short iovec_count;
+ unsigned int dxfer_len;
+ void * dxferp;
+ unsigned char * cmdp;
+ void * sbp;
+ unsigned int timeout;
+ unsigned int flags;
+ int pack_id;
+ void * usr_ptr;
+ unsigned char status;
+ unsigned char masked_status;
+ unsigned char msg_status;
+ unsigned char sb_len_wr;
+ unsigned short host_status;
+ unsigned short driver_status;
+ int resid;
+ unsigned int duration;
+ unsigned int info;
+};
+
+#ifndef SG_DXFER_NONE
+ #define SG_DXFER_NONE -1
+ #define SG_DXFER_TO_DEV -2
+ #define SG_DXFER_FROM_DEV -3
+ #define SG_DXFER_TO_FROM_DEV -4
+#endif
+
+#define SG_READ 0
+#define SG_WRITE 1
+
+#define SG_PIO 0
+#define SG_DMA 1
+
+#define SG_CHECK_CONDITION 0x02
+#define SG_DRIVER_SENSE 0x08
+
+#define SG_ATA_16 0x85
+#define SG_ATA_16_LEN 16
+
+#define SG_ATA_12 0xa1
+#define SG_ATA_12_LEN 12
+
+#define SG_ATA_LBA48 1
+#define SG_ATA_PROTO_NON_DATA ( 3 << 1)
+#define SG_ATA_PROTO_PIO_IN ( 4 << 1)
+#define SG_ATA_PROTO_PIO_OUT ( 5 << 1)
+#define SG_ATA_PROTO_DMA ( 6 << 1)
+#define SG_ATA_PROTO_UDMA_IN (11 << 1) /* not yet supported in libata */
+#define SG_ATA_PROTO_UDMA_OUT (12 << 1) /* not yet supported in libata */
+
+void tf_init (struct ata_tf *tf, __u8 ata_op, __u64 lba, unsigned int nsect);
+__u64 tf_to_lba (struct ata_tf *tf);
+int sg16 (int fd, int rw, int dma, struct ata_tf *tf, void *data, unsigned int data_bytes, unsigned int timeout_secs);
+int do_drive_cmd (int fd, unsigned char *args, unsigned int timeout);
+int do_taskfile_cmd (int fd, struct hdio_taskfile *r, unsigned int timeout_secs);
+int dev_has_sgio (int fd);
+void init_hdio_taskfile (struct hdio_taskfile *r, __u8 ata_op, int rw, int force_lba48,
+ __u64 lba, unsigned int nsect, int data_bytes);
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/hdparm-9.39/wiper/Changelog new/hdparm-9.42/wiper/Changelog
--- old/hdparm-9.39/wiper/Changelog 2011-02-21 15:59:43.000000000 +0100
+++ new/hdparm-9.42/wiper/Changelog 2012-09-28 19:33:15.000000000 +0200
@@ -1,3 +1,5 @@
+wiper.sh-3.5
+ - don't skip Group 0 on ext* filesystems
wiper.sh-3.4
- updated to allow all SCSI_DISK_MAJOR numbers, not just "8"
wiper.sh-3.3
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/hdparm-9.39/wiper/contrib/README.contrib new/hdparm-9.42/wiper/contrib/README.contrib
--- old/hdparm-9.39/wiper/contrib/README.contrib 2010-11-07 16:06:44.000000000 +0100
+++ new/hdparm-9.42/wiper/contrib/README.contrib 2012-09-28 18:47:18.000000000 +0200
@@ -1,7 +1,7 @@
Contributed scripts and notes from others (untested by me).
===========================================================
-raid1ext4trim.sh-1.4
+raid1ext4trim.sh-1.5
Similar to wiper.sh, but for ext4/RAID1 mirrors.
By Chris Caputo .
Adapted from wiper.sh (ver 2.6 by Mark Lord).
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/hdparm-9.39/wiper/contrib/raid1ext4trim.sh-1.4 new/hdparm-9.42/wiper/contrib/raid1ext4trim.sh-1.4
--- old/hdparm-9.39/wiper/contrib/raid1ext4trim.sh-1.4 2010-11-07 16:05:35.000000000 +0100
+++ new/hdparm-9.42/wiper/contrib/raid1ext4trim.sh-1.4 1970-01-01 01:00:00.000000000 +0100
@@ -1,407 +0,0 @@
-#!/bin/bash
-#
-# SSD TRIM utility for live RAID1 mirrored ext4 drives.
-#
-# By Chris Caputo. Adapted from wiper.sh (ver 2.6) by Mark Lord.
-
-VERSION=1.4
-
-# Copyright (C) 2010 Chris Caputo. All rights reserved.
-#
-# This program is free software; you can redistribute it and/or
-# modify it under the terms of the GNU General Public License Version 2,
-# as published by the Free Software Foundation.
-#
-# This program is distributed in the hope that it would be useful,
-# but WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-# GNU General Public License for more details.
-#
-# You should have received a copy of the GNU General Public License
-# along with this program; if not, write to the Free Software Foundation,
-# Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
-
-function usage_error(){
- echo "Usage:"
- echo " ${0##*/} [--verbose] [--commit] [--reserve=#megs] [--max-ranges=#ranges] <fsdir>"
- echo "Examples:"
- echo " ${0##*/} --verbose --commit --reserve=100 --max-ranges=512 md0 /"
- echo " ${0##*/} --verbose --verbose md1 /boot"
- echo
- echo "Note: For best results, this script should be run on each ext4-based filesystem present on a RAID1 array."
- echo
- exit 1
-}
-
-echo "${0##*/}: TRIM utility for live RAID1 ext4 SATA SSDs, version $VERSION, by Chris Caputo, based on Mark Lord's wiper.sh."
-echo
-
-## Parameter parsing for the main script.
-##
-
-export verbose=0
-commit=""
-reservemegs=0
-max_ranges=0
-argc=$#
-raiddev=""
-fsdir=""
-while [ $argc -gt 0 ]; do
- if [ "$1" = "--commit" ]; then
- commit=yes
- elif [ "$1" = "--verbose" ]; then
- verbose=$((verbose + 1))
- elif [[ "$1" =~ --reserve=[[:digit:]] ]]; then
- reservemegs=${1##--reserve=}
- elif [[ "$1" =~ --max-ranges=[[:digit:]] ]]; then
- max_ranges=${1##--max-ranges=}
- elif [ "$1" = "" ]; then
- usage_error
- else
- if [ "$raiddev" = "" ]; then
- raiddev=${1##*/}
- elif [ "$fsdir" = "" ]; then
- fsdir=$1
- else
- echo "$1: too many arguments, aborting."
- exit 1
- fi
- fi
- argc=$((argc - 1))
- shift
-done
-[ "$raiddev" = "" ] && usage_error
-[ "$fsdir" = "" ] && usage_error
-
-## Check --reserve number.
-##
-
-isdigit () # Tests whether *entire string* is numerical.
-{ # In other words, tests for integer variable.
- [ $# -eq 1 ] || return -1
-
- case $1 in
- *[!0-9]*|"") return -1;;
- *) return 0;;
- esac
-}
-
-if ! isdigit "$reservemegs" ; then
- echo "'$reservemegs' is not numerical"
- exit 1
-fi
-if ! isdigit "$max_ranges" ; then
- echo "'$max_ranges' is not numerical"
- exit 1
-fi
-
-if [ $reservemegs -eq 0 ]; then
- echo "Reserve defaulting to 10 megabytes."
- reservemegs=10
-fi
-reservekilos=$((reservemegs * 1024))
-
-## Find a required program, or else give a nicer error message than we'd otherwise see:
-##
-function find_prog(){
- prog="$1"
- if [ ! -x "$prog" ]; then
- prog="${prog##*/}"
- p=`type -f -P "$prog" 2>/dev/null`
- if [ "$p" = "" ]; then
- echo "$1: needed but not found, aborting."
- exit 1
- fi
- prog="$p"
- [ $verbose -gt 0 ] && echo " --> using $prog instead of $1"
- fi
- echo "$prog"
-}
-
-## Ensure we have most of the necessary utilities available before trying to proceed:
-##
-hash -r ## Refresh bash's cached PATH entries
-HDPARM=`find_prog /sbin/hdparm` || exit 1
-GAWK=`find_prog /usr/bin/gawk` || exit 1
-GREP=`find_prog /bin/grep` || exit 1
-ID=`find_prog /usr/bin/id` || exit 1
-LS=`find_prog /bin/ls` || exit 1
-DF=`find_prog /bin/df` || exit 1
-RM=`find_prog /bin/rm` || exit 1
-
-[ $verbose -gt 1 ] && HDPARM="$HDPARM --verbose"
-
-## I suppose this will confuse the three SELinux users out there:
-##
-if [ `$ID -u` -ne 0 ]; then
- echo "Only the super-user can use this (try \"sudo $0\" instead), aborting."
- exit 1
-fi
-
-## We need a very modern hdparm, for its --fallocate and --trim-sector-ranges-stdin flags:
-## Version 9.25 added automatic determination of safe max-size of TRIM commands.
-##
-HDPVER=`$HDPARM -V | $GAWK '{gsub("[^0-9.]","",$2); if ($2 > 0) print ($2 * 100); else print 0; exit(0)}'`
-if [ $HDPVER -lt 925 ]; then
- echo "$HDPARM: version >= 9.25 is required, aborting."
- exit 1
-fi
-
-## Check that this is a RAID1 device.
-##
-if ! $GREP raid1 /sys/block/$raiddev/md/level 1>/dev/null ; then
- echo "$raiddev is not a RAID1 array."
- exit 1
-fi
-
-## Get list of slave devices in the RAID1 mirror.
-##
-slaves=(`$LS /sys/block/$raiddev/slaves`)
-#slaves=(sda sdb sdc)
-#slaves=(md0)
-
-## Check for DEVTYPE disk and TRIM support on each slave.
-##
-index=0
-for slave in "${slaves[@]}"
-do
- # Check that slave is of DEVTYPE disk.
- if ! $GREP "DEVTYPE=disk" /sys/block/$slave/uevent 1>/dev/null ; then
- echo "$slave is not a whole disk. This program only works with full-disk RAID1, not RAID1 partitions."
- exit 1
- fi
-
- # Check that slave has TRIM support. Exclude if not.
- if ! $HDPARM -I /dev/$slave | $GREP -i '[ ][*][ ]*Data Set Management TRIM supported' &>/dev/null ; then
- echo "$slave doesn't appear to support TRIM, per $HDPARM. Excluding."
- unset slaves[index]
- fi
-
- let "index = $index + 1"
-done
-if [ "${slaves[0]}" = "" ]; then
- echo "No constituent of $raiddev array supports TRIM. Aborting."
- exit 1
-fi
-
-## Check that fsdir is on an ext4 volume.
-##
-lines=`$DF --type=ext4 $fsdir 2>/dev/null | $GREP -v ^Filesystem | wc -l`
-if [ $lines -ne 1 ]; then
- echo "'$fsdir' does not appear to be on an ext4 filesystem. Aborting."
- exit 1
-fi
-
-## Check that fsdir is a directory.
-##
-if [ ! -d $fsdir ]; then
- echo "'$fsdir' is not a directory. Aborting."
- exit 1
-fi
-
-## Check free space & calculate tmpfile size.
-##
-freesize=`$DF -P -B 1024 $fsdir | $GAWK '{r=$4}END{print r}'`
-if [ "$freesize" = "" ]; then
- echo "'$fsdir' is unknown to '$DF'. Aborting."
- exit 1
-fi
-if [ $freesize -lt $reservekilos ]; then
- echo "'$fsdir' available space of $freesize KB is less than the $reservekilos KB to be reserved for the TRIM operation. Aborting." >&2
- exit 1
-fi
-tmpsize=$((freesize - reservekilos))
-tmpfile="$fsdir/${0##*/}_TMPFILE.$$"
-
-## Clean up tmpfile (if any) and exit:
-##
-function do_cleanup(){
- if [ -e $tmpfile ]; then
- echo "Removing temporary file '$tmpfile'..."
- $RM -f $tmpfile
- if [ -e $tmpfile ]; then
- echo "Failed to remove '$tmpfile'!!!"
- fi
- fi
- [ $1 -eq 0 ] && echo "Done."
- [ $1 -eq 0 ] || echo "Aborted." >&2
- exit $1
-}
-
-## Prepare signal handling, in case we get interrupted while $tmpfile exists:
-##
-function do_abort(){
- echo
- do_cleanup 1
-}
-trap do_abort SIGTERM
-trap do_abort SIGQUIT
-trap do_abort SIGINT
-trap do_abort SIGHUP
-trap do_abort SIGPIPE
-
-## Do the fallocate.
-## This is where we finally discover whether the filesystem actually
-## supports --fallocate or not. Some folks will be disappointed here.
-##
-## Note that --fallocate does not actually write any file data to fsdev,
-## but rather simply allocates formerly-free space to the tmpfile.
-##
-echo -n "Creating temporary file (${tmpsize} KB '$tmpfile') ... "
-if ! $HDPARM --fallocate "${tmpsize}" $tmpfile ; then
- echo "This kernel may not support 'fallocate'. Aborting."
- exit 1
-fi
-echo
-
-## Verify that slaves and RAID1 mirror have same base LBA. First add a test
-## string to the tmpfile. "date" is used since it is ever changing.
-##
-TESTSTR=`date`
-echo "$TESTSTR" >> $tmpfile
-sync # this is critical
-SECTOR_BYTES=`$HDPARM --fibmap $tmpfile | \
- $GREP "byte sectors" | \
- $GAWK '{print $9}'`
-LAST_EXTENT_SECTOR_COUNT=`$HDPARM --fibmap $tmpfile | \
- tail -1 | \
- $GAWK '{print $4}'`
-LAST_EXTENT_LBA=`$HDPARM --fibmap $tmpfile | tail -1 | $GAWK '{print $2}'`
-
-## Verify the test string is in the extent read.
-if ! dd iflag=direct status=noxfer bs=$SECTOR_BYTES count=$LAST_EXTENT_SECTOR_COUNT skip=$LAST_EXTENT_LBA if=/dev/$raiddev 2>/dev/null | $GREP "$TESTSTR" &>/dev/null ; then
- echo "Test string was not found in last extent of tmpfile, as it should have been. Aborting."
- do_cleanup 1
-fi
-
-## Now compare the mirror and the slaves to make sure they have the same data at the same LBA.
-##
-refchksum=`dd iflag=direct status=noxfer bs=$SECTOR_BYTES count=$LAST_EXTENT_SECTOR_COUNT skip=$LAST_EXTENT_LBA if=/dev/$raiddev 2>/dev/null | sha1sum`
-index=0
-for slave in "${slaves[@]}"
-do
- chksum=`dd iflag=direct status=noxfer bs=$SECTOR_BYTES count=$LAST_EXTENT_SECTOR_COUNT skip=$LAST_EXTENT_LBA if=/dev/$slave 2>/dev/null | sha1sum`
-
- if [ "$chksum" != "$refchksum" ]; then
- echo "Direct I/O of last extent of tmpfile on $slave doesn't match that of $raiddev. Excluding."
- unset slaves[index]
- fi
-
- let "index = $index + 1"
-done
-if [ "${slaves[0]}" = "" ]; then
- echo "No constituent of $raiddev array has a matching checksum. Aborting."
- do_cleanup 1
-fi
-
-echo "TRIMable constituents of $raiddev: ${slaves[@]}"
-
-## If they specified "--commit" on the command line, then prompt for confirmation first:
-##
-if [ "$commit" = "yes" ]; then
- echo "Beginning TRIM operations..."
-else
- echo "This will be a DRY-RUN only. Use --commit to do it for real."
- echo "Simulating TRIM operations..."
-fi
-get_trimlist="$HDPARM --fibmap $tmpfile"
-[ $verbose -gt 0 ] && echo "get_trimlist=$get_trimlist"
-
-
-## Begin gawk program
-GAWKPROG='
- function append_range (lba,count ,this_count){
- nsectors += count;
- while (count > 0) {
- this_count = (count > 65535) ? 65535 : count
- printf "%u:%u \n", lba, this_count
- if (verbose > 1)
- printf "%u:%u ", lba, this_count > "/dev/stderr"
- lba += this_count
- count -= this_count
- nranges++;
- }
- }
- { ## Output from "hdparm --fibmap", in absolute sectors:
- if (NF == 4 && $2 ~ "^[1-9][0-9]*$")
- append_range($2,$4)
- next
- }
- END {
- if (verbose > 1)
- printf "\n" > "/dev/stderr"
- if (err == 0 && commit != "yes")
- printf "(dry-run) trimming %u sectors from %u ranges\n", nsectors, nranges > "/dev/stderr"
- exit err
- }'
-## End gawk program
-
-## Run TRIM on each slave. Batch as requested.
-sync
-index=0
-for slave in "${slaves[@]}"
-do
- echo "TRIM beginning on $slave..."
-
- if [ "$commit" = "yes" ]; then
- TRIM="$HDPARM --please-destroy-my-drive \
- --trim-sector-ranges-stdin /dev/$slave"
- else
- TRIM="$GAWK {}"
- fi
-
- ## Different SSD's have a different maximum number of ranges they'll
- ## accept in a single TRIM command.
- if [ $max_ranges -eq 0 ] ; then
- model=`$HDPARM -I /dev/$slave | $GAWK '/Model Number/ { print $NF }'`
- case "$model" in
- SSDSA[12]*) slave_max_range=512 ;; # Intel X18-M/X25-M
- OCZ-VERTEX2) slave_max_range=64 ;; # OCZ Vertex2
- *) slave_max_range=65535
- esac
- else
- slave_max_range=$max_ranges
- fi
- [ $verbose -gt 0 ] && echo "$slave: max-ranges = $slave_max_range"
-
- $get_trimlist 2>/dev/null | $GAWK \
- -v commit="$commit" \
- -v verbose="$verbose" \
- "$GAWKPROG" | \
- if true; then
- i=0
- while read range; do
- (( i++ ))
- if (( i <= $slave_max_range )); then
- ranges=$ranges" "$range
- else
- [ $verbose -gt 0 ] && echo -e "Trim ranges:" $ranges
- echo $ranges | $TRIM
- ret=$?
- if [ $ret -ne 0 ] ; then
- do_cleanup $ret
- fi
- ranges=$range
- i=1
- fi
- done
- [ $verbose -gt 0 ] && echo -e "Trim ranges:" $ranges
- echo $ranges | $TRIM
- ret=$?
- if [ $ret -ne 0 ] ; then
- do_cleanup $ret
- fi
- ranges=""
- fi
-
- ret=$?
- if [ $ret -ne 0 ] ; then
- echo "TRIM failed on $slave. Aborting."
- do_cleanup $ret
- else
- echo "TRIM finished successfully on $slave."
- fi
-done
-
-do_cleanup 0
-
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/hdparm-9.39/wiper/contrib/raid1ext4trim.sh-1.5 new/hdparm-9.42/wiper/contrib/raid1ext4trim.sh-1.5
--- old/hdparm-9.39/wiper/contrib/raid1ext4trim.sh-1.5 1970-01-01 01:00:00.000000000 +0100
+++ new/hdparm-9.42/wiper/contrib/raid1ext4trim.sh-1.5 2012-09-28 18:46:21.000000000 +0200
@@ -0,0 +1,407 @@
+#!/bin/bash
+#
+# SSD TRIM utility for live RAID1 mirrored ext4 drives.
+#
+# By Chris Caputo. Adapted from wiper.sh (ver 2.6) by Mark Lord.
+
+VERSION=1.5
+
+# Copyright (C) 2010-2012 Chris Caputo. All rights reserved.
+#
+# This program is free software; you can redistribute it and/or
+# modify it under the terms of the GNU General Public License Version 2,
+# as published by the Free Software Foundation.
+#
+# This program is distributed in the hope that it would be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software Foundation,
+# Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+
+function usage_error(){
+ echo "Usage:"
+ echo " ${0##*/} [--verbose] [--commit] [--reserve=#megs] [--max-ranges=#ranges] <fsdir>"
+ echo "Examples:"
+ echo " ${0##*/} --verbose --commit --reserve=100 --max-ranges=512 md0 /"
+ echo " ${0##*/} --verbose --verbose md1 /boot"
+ echo
+ echo "Note: For best results, this script should be run on each ext4-based filesystem present on a RAID1 array."
+ echo
+ exit 1
+}
+
+echo "${0##*/}: TRIM utility for live RAID1 ext4 SATA SSDs, version $VERSION, by Chris Caputo, based on Mark Lord's wiper.sh."
+echo
+
+## Parameter parsing for the main script.
+##
+
+export verbose=0
+commit=""
+reservemegs=0
+max_ranges=0
+argc=$#
+raiddev=""
+fsdir=""
+while [ $argc -gt 0 ]; do
+ if [ "$1" = "--commit" ]; then
+ commit=yes
+ elif [ "$1" = "--verbose" ]; then
+ verbose=$((verbose + 1))
+ elif [[ "$1" =~ --reserve= ]]; then
+ reservemegs=${1##--reserve=}
+ elif [[ "$1" =~ --max-ranges= ]]; then
+ max_ranges=${1##--max-ranges=}
+ elif [ "$1" = "" ]; then
+ usage_error
+ else
+ if [ "$raiddev" = "" ]; then
+ raiddev=${1##*/}
+ elif [ "$fsdir" = "" ]; then
+ fsdir=$1
+ else
+ echo "$1: too many arguments, aborting."
+ exit 1
+ fi
+ fi
+ argc=$((argc - 1))
+ shift
+done
+[ "$raiddev" = "" ] && usage_error
+[ "$fsdir" = "" ] && usage_error
+
+## Check --reserve number.
+##
+
+isdigit () # Tests whether *entire string* is numerical.
+{ # In other words, tests for integer variable.
+ [ $# -eq 1 ] || return 1
+
+ case $1 in
+ *[!0-9]*|"") return 1;;
+ *) return 0;;
+ esac
+}
+
+if ! isdigit "$reservemegs" ; then
+ echo "'$reservemegs' is not numerical"
+ exit 1
+fi
+if ! isdigit "$max_ranges" ; then
+ echo "'$max_ranges' is not numerical"
+ exit 1
+fi
+
+if [ $reservemegs -eq 0 ]; then
+ echo "Reserve defaulting to 10 megabytes."
+ reservemegs=10
+fi
+reservekilos=$((reservemegs * 1024))
+
+## Find a required program, or else give a nicer error message than we'd otherwise see:
+##
+function find_prog(){
+ prog="$1"
+ if [ ! -x "$prog" ]; then
+ prog="${prog##*/}"
+ p=`type -f -P "$prog" 2>/dev/null`
+ if [ "$p" = "" ]; then
+ echo "$1: needed but not found, aborting."
+ exit 1
+ fi
+ prog="$p"
+ [ $verbose -gt 0 ] && echo " --> using $prog instead of $1"
+ fi
+ echo "$prog"
+}
+
+## Ensure we have most of the necessary utilities available before trying to proceed:
+##
+hash -r ## Refresh bash's cached PATH entries
+HDPARM=`find_prog /sbin/hdparm` || exit 1
+GAWK=`find_prog /usr/bin/gawk` || exit 1
+GREP=`find_prog /bin/grep` || exit 1
+ID=`find_prog /usr/bin/id` || exit 1
+LS=`find_prog /bin/ls` || exit 1
+DF=`find_prog /bin/df` || exit 1
+RM=`find_prog /bin/rm` || exit 1
+
+[ $verbose -gt 1 ] && HDPARM="$HDPARM --verbose"
+
+## I suppose this will confuse the three SELinux users out there:
+##
+if [ `$ID -u` -ne 0 ]; then
+ echo "Only the super-user can use this (try \"sudo $0\" instead), aborting."
+ exit 1
+fi
+
+## We need a very modern hdparm, for its --fallocate and --trim-sector-ranges-stdin flags:
+## Version 9.25 added automatic determination of safe max-size of TRIM commands.
+##
+HDPVER=`$HDPARM -V | $GAWK '{gsub("[^0-9.]","",$2); if ($2 > 0) print ($2 * 100); else print 0; exit(0)}'`
+if [ $HDPVER -lt 925 ]; then
+ echo "$HDPARM: version >= 9.25 is required, aborting."
+ exit 1
+fi
+
+## Check that this is a RAID1 device.
+##
+if ! $GREP raid1 /sys/block/$raiddev/md/level 1>/dev/null ; then
+ echo "$raiddev is not a RAID1 array."
+ exit 1
+fi
+
+## Get list of slave devices in the RAID1 mirror.
+##
+slaves=(`$LS /sys/block/$raiddev/slaves`)
+#slaves=(sda sdb sdc)
+#slaves=(md0)
+
+## Check for DEVTYPE disk and TRIM support on each slave.
+##
+index=0
+for slave in "${slaves[@]}"
+do
+ # Check that slave is of DEVTYPE disk.
+ if ! $GREP "DEVTYPE=disk" /sys/block/$slave/uevent 1>/dev/null ; then
+ echo "$slave is not a whole disk. This program only works with full-disk RAID1, not RAID1 partitions."
+ exit 1
+ fi
+
+ # Check that slave has TRIM support. Exclude if not.
+ if ! $HDPARM -I /dev/$slave | $GREP -i '[ ][*][ ]*Data Set Management TRIM supported' &>/dev/null ; then
+ echo "$slave doesn't appear to support TRIM, per $HDPARM. Excluding."
+ unset slaves[index]
+ fi
+
+ let "index = $index + 1"
+done
+if [ "${slaves[0]}" = "" ]; then
+ echo "No constituent of $raiddev array supports TRIM. Aborting."
+ exit 1
+fi
+
+## Check that fsdir is on an ext4 volume.
+##
+lines=`$DF --type=ext4 $fsdir 2>/dev/null | $GREP -v ^Filesystem | wc -l`
+if [ $lines -ne 1 ]; then
+ echo "'$fsdir' does not appear to be on an ext4 filesystem. Aborting."
+ exit 1
+fi
+
+## Check that fsdir is a directory.
+##
+if [ ! -d $fsdir ]; then
+ echo "'$fsdir' is not a directory. Aborting."
+ exit 1
+fi
+
+## Check free space & calculate tmpfile size.
+##
+freesize=`$DF -P -B 1024 $fsdir | $GAWK '{r=$4}END{print r}'`
+if [ "$freesize" = "" ]; then
+ echo "'$fsdir' is unknown to '$DF'. Aborting."
+ exit 1
+fi
+if [ $freesize -lt $reservekilos ]; then
+ echo "'$fsdir' available space of $freesize KB is less than the $reservekilos KB to be reserved for the TRIM operation. Aborting." >&2
+ exit 1
+fi
+tmpsize=$((freesize - reservekilos))
+tmpfile="$fsdir/${0##*/}_TMPFILE.$$"
+
+## Clean up tmpfile (if any) and exit:
+##
+function do_cleanup(){
+ if [ -e $tmpfile ]; then
+ echo "Removing temporary file '$tmpfile'..."
+ $RM -f $tmpfile
+ if [ -e $tmpfile ]; then
+ echo "Failed to remove '$tmpfile'!!!"
+ fi
+ fi
+ [ $1 -eq 0 ] && echo "Done."
+ [ $1 -eq 0 ] || echo "Aborted." >&2
+ exit $1
+}
+
+## Prepare signal handling, in case we get interrupted while $tmpfile exists:
+##
+function do_abort(){
+ echo
+ do_cleanup 1
+}
+trap do_abort SIGTERM
+trap do_abort SIGQUIT
+trap do_abort SIGINT
+trap do_abort SIGHUP
+trap do_abort SIGPIPE
+
+## Do the fallocate.
+## This is where we finally discover whether the filesystem actually
+## supports --fallocate or not. Some folks will be disappointed here.
+##
+## Note that --fallocate does not actually write any file data to fsdev,
+## but rather simply allocates formerly-free space to the tmpfile.
+##
+echo -n "Creating temporary file (${tmpsize} KB '$tmpfile') ... "
+if ! $HDPARM --fallocate "${tmpsize}" $tmpfile ; then
+ echo "This kernel may not support 'fallocate'. Aborting."
+ exit 1
+fi
+echo
+
+## Verify that slaves and RAID1 mirror have same base LBA. First add a test
+## string to the tmpfile. "date" is used since it is ever changing.
+##
+TESTSTR=`date`
+echo "$TESTSTR" >> $tmpfile
+sync # this is critical
+SECTOR_BYTES=`$HDPARM --fibmap $tmpfile | \
+ $GREP "byte sectors" | \
+ $GAWK '{print $9}'`
+LAST_EXTENT_SECTOR_COUNT=`$HDPARM --fibmap $tmpfile | \
+ tail -1 | \
+ $GAWK '{print $4}'`
+LAST_EXTENT_LBA=`$HDPARM --fibmap $tmpfile | tail -1 | $GAWK '{print $2}'`
+
+## Verify the test string is in the extent read.
+if ! dd iflag=direct status=noxfer bs=$SECTOR_BYTES count=$LAST_EXTENT_SECTOR_COUNT skip=$LAST_EXTENT_LBA if=/dev/$raiddev 2>/dev/null | $GREP "$TESTSTR" &>/dev/null ; then
+ echo "Test string was not found in last extent of tmpfile, as it should have been. Aborting."
+ do_cleanup 1
+fi
+
+## Now compare the mirror and the slaves to make sure they have the same data at the same LBA.
+##
+refchksum=`dd iflag=direct status=noxfer bs=$SECTOR_BYTES count=$LAST_EXTENT_SECTOR_COUNT skip=$LAST_EXTENT_LBA if=/dev/$raiddev 2>/dev/null | sha1sum`
+index=0
+for slave in "${slaves[@]}"
+do
+ chksum=`dd iflag=direct status=noxfer bs=$SECTOR_BYTES count=$LAST_EXTENT_SECTOR_COUNT skip=$LAST_EXTENT_LBA if=/dev/$slave 2>/dev/null | sha1sum`
+
+ if [ "$chksum" != "$refchksum" ]; then
+ echo "Direct I/O of last extent of tmpfile on $slave doesn't match that of $raiddev. Excluding."
+ unset slaves[index]
+ fi
+
+ let "index = $index + 1"
+done
+if [ "${slaves[0]}" = "" ]; then
+ echo "No constituent of $raiddev array has a matching checksum. Aborting."
+ do_cleanup 1
+fi
+
+echo "TRIMable constituents of $raiddev: ${slaves[@]}"
+
+## If they specified "--commit" on the command line, then prompt for confirmation first:
+##
+if [ "$commit" = "yes" ]; then
+ echo "Beginning TRIM operations..."
+else
+ echo "This will be a DRY-RUN only. Use --commit to do it for real."
+ echo "Simulating TRIM operations..."
+fi
+get_trimlist="$HDPARM --fibmap $tmpfile"
+[ $verbose -gt 0 ] && echo "get_trimlist=$get_trimlist"
+
+
+## Begin gawk program
+GAWKPROG='
+ function append_range (lba,count ,this_count){
+ nsectors += count;
+ while (count > 0) {
+ this_count = (count > 65535) ? 65535 : count
+ printf "%u:%u \n", lba, this_count
+ if (verbose > 1)
+ printf "%u:%u ", lba, this_count > "/dev/stderr"
+ lba += this_count
+ count -= this_count
+ nranges++;
+ }
+ }
+ { ## Output from "hdparm --fibmap", in absolute sectors:
+ if (NF == 4 && $2 ~ "^[1-9][0-9]*$")
+ append_range($2,$4)
+ next
+ }
+ END {
+ if (verbose > 1)
+ printf "\n" > "/dev/stderr"
+ if (err == 0 && commit != "yes")
+ printf "(dry-run) trimming %u sectors from %u ranges\n", nsectors, nranges > "/dev/stderr"
+ exit err
+ }'
+## End gawk program
+
+## Run TRIM on each slave. Batch as requested.
+sync
+index=0
+for slave in "${slaves[@]}"
+do
+ echo "TRIM beginning on $slave..."
+
+ if [ "$commit" = "yes" ]; then
+ TRIM="$HDPARM --please-destroy-my-drive \
+ --trim-sector-ranges-stdin /dev/$slave"
+ else
+ TRIM="$GAWK {}"
+ fi
+
+ ## Different SSD's have a different maximum number of ranges they'll
+ ## accept in a single TRIM command.
+ if [ $max_ranges -eq 0 ] ; then
+ model=`$HDPARM -I /dev/$slave | $GAWK '/Model Number/ { print $NF }'`
+ case "$model" in
+ SSDSA[12]*) slave_max_range=512 ;; # Intel X18-M/X25-M
+ OCZ-VERTEX2) slave_max_range=64 ;; # OCZ Vertex2
+ *) slave_max_range=65535
+ esac
+ else
+ slave_max_range=$max_ranges
+ fi
+ [ $verbose -gt 0 ] && echo "$slave: max-ranges = $slave_max_range"
+
+ $get_trimlist 2>/dev/null | $GAWK \
+ -v commit="$commit" \
+ -v verbose="$verbose" \
+ "$GAWKPROG" | \
+ if true; then
+ i=0
+ while read range; do
+ (( i++ ))
+ if (( i <= $slave_max_range )); then
+ ranges=$ranges" "$range
+ else
+ [ $verbose -gt 0 ] && echo -e "Trim ranges:" $ranges
+ echo $ranges | $TRIM
+ ret=$?
+ if [ $ret -ne 0 ] ; then
+ do_cleanup $ret
+ fi
+ ranges=$range
+ i=1
+ fi
+ done
+ [ $verbose -gt 0 ] && echo -e "Trim ranges:" $ranges
+ echo $ranges | $TRIM
+ ret=$?
+ if [ $ret -ne 0 ] ; then
+ do_cleanup $ret
+ fi
+ ranges=""
+ fi
+
+ ret=$?
+ if [ $ret -ne 0 ] ; then
+ echo "TRIM failed on $slave. Aborting."
+ do_cleanup $ret
+ else
+ echo "TRIM finished successfully on $slave."
+ fi
+done
+
+do_cleanup 0
+
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/hdparm-9.39/wiper/wiper.sh new/hdparm-9.42/wiper/wiper.sh
--- old/hdparm-9.39/wiper/wiper.sh 2011-02-21 15:58:26.000000000 +0100
+++ new/hdparm-9.42/wiper/wiper.sh 2012-09-28 20:08:37.000000000 +0200
@@ -2,7 +2,7 @@
#
# SATA SSD free-space TRIM utility, by Mark Lord
-VERSION=3.4
+VERSION=3.5
# Copyright (C) 2009-2010 Mark Lord. All rights reserved.
#
@@ -252,6 +252,11 @@
## because that's the pattern such systems also use in /proc/mounts.
## Later, at time of use, we'll try harder to find the real rootdev.
##
+## FIXME: apparently this doesn't work on SuSE Linux, though.
+## So for there, we'll likely need to read /etc/mtab,
+## or be a lot more clever and get it somehow from statfs or something.
+## FIXME: or use target from /dev/root symlink for Gentoo as well.
+##
function match_rootdev() {
rdev=""
rdevno="$1"
@@ -793,7 +798,7 @@
blksects = $NF / 512
next
}
- /^Group [1-9][0-9]*:/ { ## Second stage output from dumpe2fs:
+ /^Group [0-9][0-9]*:/ { ## Second stage output from dumpe2fs:
in_groups = 1
next
}
--
To unsubscribe, e-mail: opensuse-commit+unsubscribe@opensuse.org
For additional commands, e-mail: opensuse-commit+help@opensuse.org