LinuxQuestions.org
Help answer threads with 0 replies.
Home Forums Tutorials Articles Register
Go Back   LinuxQuestions.org > Forums > Linux Forums > Linux - Hardware
User Name
Password
Linux - Hardware This forum is for Hardware issues.
Having trouble installing a piece of hardware? Want to know if that peripheral is compatible with Linux?

Notices


Reply
  Search this Thread
Old 10-19-2007, 11:58 PM   #1
macemoneta
Senior Member
 
Registered: Jan 2005
Location: Manalapan, NJ
Distribution: Fedora x86 and x86_64, Debian PPC and ARM, Android
Posts: 4,593
Blog Entries: 2

Rep: Reputation: 344Reputation: 344Reputation: 344Reputation: 344
Howto: Spin down external (USB/Firewire) hard drives on idle


Most external hard drives will respond to an sdparm command to stop the drive. However, it's inconvenient to run the command(s) manually every time, especially if the drives are used off-hours by cron jobs. I created the attached script, idleDrive, which will let you spin down external drives automatically after they go idle. To use the script, add a cron job (usually on root) to run idleDrive, and specify the drive to be idled by either label, vendor or UUID. For example, to spin down a drive with the label "Videos" after five minutes of idle, you would add the cron job (assuming idleDrive is in /usr/local/bin/):

Code:
*/5 * * * * /usr/local/bin/idleDrive label=Videos &>/dev/null
You can easily specify multiple drives, selected with different criteria, using different time intervals:

Code:
*/5  * * * * /usr/local/bin/idleDrive label=Videos &>/dev/null
*/15 * * * * /usr/local/bin/idleDrive uuid=104355ff-685e-4fa9-8869-bfa82d2fb9b6 &>/dev/null
*/30 * * * * /usr/local/bin/idleDrive vendor=Maxtor &>/dev/null
The script itself follows. I use this on five different drives across three system. I've read that some drives will not respond to the spin-down commands. Some USB/IEEE1394 combo drives will only respond on one interface. You will need the sdparm command installed; it should be available from your distributions repositories. Hopefully, this will work for you:

Code:
#!/bin/bash
#-------------------------------------------------------------------------------
#
# idleDrive
# 
# Author:   Mace Moneta
# Version:  1.2
# Created:  10/12/2007
# Modified: 10/18/2007
#
# Description: Spin down the drive when it goes idle
# 
# Options:
#
# vendor=vendor-name     Example: vendor=Maxtor
# uuid=uuid-string       Example: uuid=104355ff-685e-4fa9-8869-bfa82d2fb9b6
# label=volume-label     Example: label=ExternalDisk
#
#-------------------------------------------------------------------------------

#-------------------------------------------------------------------------------
#       ************************** Variables **************************
#-------------------------------------------------------------------------------

PARAM=$1
OPTION=${PARAM%%=*}
VALUE=${PARAM##*=}
LOCK="/dev/shm/idleDrive-${VALUE}.lock"
STATE="/dev/shm/idleDrive-${VALUE}.state"
DOWN="/dev/shm/idleDrive-${VALUE}.down"

#-------------------------------------------------------------------------------
#       ************************* Subroutines *************************
#-------------------------------------------------------------------------------

#---  FUNCTION  ----------------------------------------------------------------
# Name:        log
# Description: Log a message to the syslog and terminal
# Parameters:  The message to log
# Returns:     Nothing
#-------------------------------------------------------------------------------
function log () {
   PREFIX="idleDrive.info"
   PREFIXLEN=${#PREFIX}
   PREFIXLEN=$((10#$PREFIXLEN+2))
   DASHES="---------------------------------------------------------------------------------"
   MSG=$1
   MSGLEN=${#MSG}
   MSGLEN=$((10#$MSGLEN+$PREFIXLEN))
   DASH=${DASHES:0:$MSGLEN}
   echo
   echo "$DASH"
   /usr/bin/logger -s -t $PREFIX "$MSG"
   echo "$DASH"
}

#---  FUNCTION  ----------------------------------------------------------------
# Name:        CLEANUP
# Description: Clear the lock and exit
# Parameters:  None
# Returns:     Nothing
#-------------------------------------------------------------------------------
function CLEANUP () {
   /bin/rm -f $LOCK
   log "Exiting on interrupt"
   exit
}
trap CLEANUP INT
trap CLEANUP HUP
trap CLEANUP QUIT
trap CLEANUP USR1
trap CLEANUP TERM

#-------------------------------------------------------------------------------
#       ************************* Mainline ****************************
#-------------------------------------------------------------------------------

#-------------------------------------------------------------------------------
# Validate the parameters and
# Identify the device that the drive is known to the system as.
#-------------------------------------------------------------------------------
case "$OPTION" in
   "vendor" )
      for drive in `/bin/ls /sys/block/sd?/device/vendor`
      do 
         if [ "`/bin/cat $drive`" == "$VALUE" ]
         then
            drive=${drive##/sys/block/}
            drive="/dev/${drive%%/device/vendor}"
            disk=${drive##/dev/}
            break
         else
            exit 0
         fi
      done ;;
   "uuid"   )
      drive=`/bin/ls -l /dev/disk/by-uuid/  | \
             /bin/grep "$VALUE"             | \
             /bin/awk '{print $11}'`
      drive=${drive##*/}
      disk=${drive:0:3}
      drive="/dev/${disk:0:3}"
      if [ "$disk" == "" ]
      then
         exit 0
      fi ;;
   "label"  )
      drive=`/bin/ls -l /dev/disk/by-label/ | \
             /bin/grep "$VALUE"             | \
             /bin/awk '{print $11}'`
      drive=${drive##*/}
      disk=${drive:0:3}
      drive="/dev/${disk:0:3}"
      if [ "$disk" == "" ]
      then
         exit 0
      fi ;;
   *        )
      log "Invalid option: $OPTION"
      log "Specify vendor, uuid or label"
      exit 1 ;;
esac

#-------------------------------------------------------------------------------
# Serialize execution
#-------------------------------------------------------------------------------
if [ -f $LOCK ]
then
   log "Already in progress for $drive ($VALUE)"
   exit 1
fi
/bin/touch $LOCK

#-------------------------------------------------------------------------------
# Check I/O stats to see if the drive has been idle
#-------------------------------------------------------------------------------
state=`/bin/grep " $disk " /proc/diskstats`
if [ -f $STATE ]
then
   previousState=`/bin/cat $STATE`
else
   log "Initializing state for $drive ($VALUE)"
   echo "$state" > $STATE
   /bin/rm -f $LOCK
   exit 0
fi

#-------------------------------------------------------------------------------
# If the I/O stats haven't changed, the drive is idle
#-------------------------------------------------------------------------------
if [ "$state" == "$previousState" ] && [ ! -f $DOWN ]
then
   log "Spin down drive $drive ($VALUE)"
   /bin/sync
   /usr/bin/sdparm --flexible --command=sync $drive &>/dev/null
   /usr/bin/sdparm --flexible --command=stop $drive &>/dev/null
   state=`/bin/grep " $disk " /proc/diskstats`
   echo "$state" > $STATE
   echo "down" > $DOWN
else
   if [ "$state" != "$previousState" ]
   then
      /bin/rm -f $DOWN
      echo "$state" > $STATE
   fi
fi

#-------------------------------------------------------------------------------
# Done
#-------------------------------------------------------------------------------
/bin/rm -f $LOCK
exit 0
 
Old 11-14-2007, 01:34 PM   #2
radar2k
LQ Newbie
 
Registered: Nov 2007
Posts: 1

Rep: Reputation: 0
some modifications for ubuntu

I'm running [k]ubuntu 7.10, and had to make a few small changes to get this to work on my system. First, awk is located in /usr/bin as opposed to /bin -- you can either create a symlink from /bin/awk to /usr/bin/awk or change the script to point to the right place for ubuntu. Second, for the uuid case, awk should check for the 10th field instead of the 11th. That is,
Code:
/bin/awk '{print $10}'`
Finally, the vendor matching doesn't seem to work for me. The else which results in exit should probably be moved outside of the for loop, after testing on $disk. As it is now, if the first drive doesn't equal the vendor, it'll exit. That is, it seems it should be:
Code:
   "vendor" )
      for drive in `/bin/ls /sys/block/sd?/device/vendor`
      do 
         if [ "`/bin/cat $drive`" == "$VALUE" ]
         then
            drive=${drive##/sys/block/}
            drive="/dev/${drive%%/device/vendor}"
            disk=${drive##/dev/}
            break
         fi
      done 
      if [ "$disk" == "" ] 
      then
         log "found no drive for vendor $VALUE"
         exit 0
      fi ;;
Though I think even that will only match the last drive where the vendor is $VALUE. Even with that change, I can't get vendor matching to work for me. I am far from a shell scripting guru, so there probably are errors in my code.

I did not test the matching by label.

Other than that, the script works great for me. Thanks!


(Note, my whole modified version is below. This code is provided without warranty, including implied warranties. I abandon any copyright claim I may have in any of the modifications I have made into the public domain. The original author Mace Moneta, of course, still holds his copyright on the code.)

Code:
#!/bin/bash
#-------------------------------------------------------------------------------
#
# idleDrive
# 
# Author:   Mace Moneta
# Version:  1.2
# Created:  10/12/2007
# Modified: 10/18/2007
#
# Description: Spin down the drive when it goes idle
# 
# Options:
#
# vendor=vendor-name     Example: vendor=Maxtor
# uuid=uuid-string       Example: uuid=104355ff-685e-4fa9-8869-bfa82d2fb9b6
# label=volume-label     Example: label=ExternalDisk
#
#-------------------------------------------------------------------------------

#-------------------------------------------------------------------------------
#       ************************** Variables **************************
#-------------------------------------------------------------------------------

PARAM=$1
OPTION=${PARAM%%=*}
VALUE=${PARAM##*=}
LOCK="/dev/shm/idleDrive-${VALUE}.lock"
STATE="/dev/shm/idleDrive-${VALUE}.state"
DOWN="/dev/shm/idleDrive-${VALUE}.down"
MYAWK="/usr/bin/awk"

#-------------------------------------------------------------------------------
#       ************************* Subroutines *************************
#-------------------------------------------------------------------------------

#---  FUNCTION  ----------------------------------------------------------------
# Name:        log
# Description: Log a message to the syslog and terminal
# Parameters:  The message to log
# Returns:     Nothing
#-------------------------------------------------------------------------------
function log () {
   PREFIX="idleDrive.info"
   PREFIXLEN=${#PREFIX}
   PREFIXLEN=$((10#$PREFIXLEN+2))
   DASHES="---------------------------------------------------------------------------------"
   MSG=$1
   MSGLEN=${#MSG}
   MSGLEN=$((10#$MSGLEN+$PREFIXLEN))
   DASH=${DASHES:0:$MSGLEN}
   echo
   echo "$DASH"
   /usr/bin/logger -s -t $PREFIX "$MSG"
   echo "$DASH"
}

#---  FUNCTION  ----------------------------------------------------------------
# Name:        CLEANUP
# Description: Clear the lock and exit
# Parameters:  None
# Returns:     Nothing
#-------------------------------------------------------------------------------
function CLEANUP () {
   /bin/rm -f $LOCK
   log "Exiting on interrupt"
   exit
}
trap CLEANUP INT
trap CLEANUP HUP
trap CLEANUP QUIT
trap CLEANUP USR1
trap CLEANUP TERM

#-------------------------------------------------------------------------------
#       ************************* Mainline ****************************
#-------------------------------------------------------------------------------

#-------------------------------------------------------------------------------
# Validate the parameters and
# Identify the device that the drive is known to the system as.
#-------------------------------------------------------------------------------
case "$OPTION" in
   "vendor" )
      for drive in `/bin/ls /sys/block/sd?/device/vendor`
      do 
         if [ "`/bin/cat $drive`" == "$VALUE" ]
         then
            drive=${drive##/sys/block/}
            drive="/dev/${drive%%/device/vendor}"
            disk=${drive##/dev/}
            break
         fi
      done 
      if [ "$disk" == "" ] 
      then
         log "found no drive for vendor $VALUE"
         exit 0
      fi ;;
   "uuid"   )
      drive=`/bin/ls -l /dev/disk/by-uuid/  | \
             /bin/grep "$VALUE"             | \
             $MYAWK '{print $10}'`
      drive=${drive##*/}
      disk=${drive:0:3}
      drive="/dev/${disk:0:3}"
      if [ "$disk" == "" ]
      then
	 log "found no drive for uuid $VALUE"
         exit 0
      fi ;;
   "label"  )
      drive=`/bin/ls -l /dev/disk/by-label/ | \
             /bin/grep "$VALUE"             | \
             $MYAWK '{print $11}'`
      drive=${drive##*/}
      disk=${drive:0:3}
      drive="/dev/${disk:0:3}"
      if [ "$disk" == "" ]
      then
	 log "found no drive for label $VALUE"
         exit 0
      fi ;;
   *        )
      log "Invalid option: $OPTION"
      log "Specify vendor, uuid or label"
      exit 1 ;;
esac

#-------------------------------------------------------------------------------
# Serialize execution
#-------------------------------------------------------------------------------
if [ -f $LOCK ]
then
   log "Already in progress for $drive ($VALUE)"
   exit 1
fi
/bin/touch $LOCK

#-------------------------------------------------------------------------------
# Check I/O stats to see if the drive has been idle
#-------------------------------------------------------------------------------
state=`/bin/grep " $disk " /proc/diskstats`
if [ -f $STATE ]
then
   previousState=`/bin/cat $STATE`
else
   log "Initializing state for $drive ($VALUE)"
   echo "$state" > $STATE
   /bin/rm -f $LOCK
   exit 0
fi

#-------------------------------------------------------------------------------
# If the I/O stats haven't changed, the drive is idle
#-------------------------------------------------------------------------------
if [ "$state" == "$previousState" ] && [ ! -f $DOWN ]
then
   log "Spin down drive $drive ($VALUE)"
   /bin/sync
   /usr/bin/sdparm --flexible --command=sync $drive &>/dev/null
   /usr/bin/sdparm --flexible --command=stop $drive &>/dev/null
   state=`/bin/grep " $disk " /proc/diskstats`
   echo "$state" > $STATE
   echo "down" > $DOWN
else
   if [ "$state" != "$previousState" ]
   then
      /bin/rm -f $DOWN
      echo "$state" > $STATE
   fi
fi

#-------------------------------------------------------------------------------
# Done
#-------------------------------------------------------------------------------
/bin/rm -f $LOCK
exit 0
 
Old 09-19-2010, 04:22 AM   #3
666f6f
LQ Newbie
 
Registered: Aug 2010
Posts: 2

Rep: Reputation: 0
Thank you macemoneta for the script and radar2k for the corrections. I'm using Ubuntu too and I had to modify the script a little.

Firstly, I had to call sdparm --command=stop twice the first time it (sdparm) is run as a workarround to a bug related with that utility (bug url: External disk won't spindown).

Another super tiny fix I've made is to use ls -l --full-time instead of ls -l because it appears that LC_TIME is not set correctly for processes spawned by cron. This must be the explanation as to why radar2k had to have awk check for the 10th field instead of the 11th.

Finally I removed the by vendor and by label disk suspension.

Here is my modified version:

Code:
#!/bin/bash
# Author: Mace Moneta
# Description: Spin down the drive when it goes idle
# Url: http://www.linuxquestions.org/questions/linux-hardware-18/howto-spin-down-external-usb-firewire-hard-drives-on-idle-593192/
# Modified By: 666f6f

PARAM=$1
OPTION=${PARAM%%=*}
VALUE=${PARAM##*=}
LOCK_FILE="/dev/shm/idle-drive-${VALUE}.lock"
STATE_FILE="/dev/shm/idle-drive-${VALUE}.state"
DOWN_FILE="/dev/shm/idle-drive-${VALUE}.down"
FIX="/dev/shm/idle-drive.fixed"

idle_drive_log() {
   local PREFIX="idle-drive.info"
   local PREFIXLEN=${#PREFIX}
   local PREFIXLEN=$((10#$PREFIXLEN+2))
   local MSG=$1
   local MSGLEN=${#MSG}
   local MSGLEN=$((10#$MSGLEN+$PREFIXLEN))
   logger -s -t $PREFIX "$MSG"
}

idle_drive_cleanup() {
   rm -f $LOCK_FILE
   idle_drive_log "Exiting on interrupt."
   exit
}

trap idle_drive_cleanup INT
trap idle_drive_cleanup HUP
trap idle_drive_cleanup QUIT
trap idle_drive_cleanup USR1
trap idle_drive_cleanup TERM

DRIVE=`ls -l --full-time /dev/disk/by-uuid/ | grep "$VALUE" | awk '{print $11}'`
DRIVE=${DRIVE##*/}
DISK=${DRIVE:0:3}
DRIVE="/dev/${DISK:0:3}"
echo $DRIVE
echo $DISK

if [ "$DISK" == "" ]; then
   idle_drive_log 'Disk not found.'
   exit 1
fi

if [ -f $LOCK_FILE ]; then
   idle_drive_log "Already in progress for $DRIVE ($VALUE)."
   exit 1
fi

touch $LOCK_FILE

# Check I/O stats to see if the drive has been idle
STATE=`grep " $DISK " /proc/diskstats`
if [ -f $STATE_FILE ]; then
   STATE_PREVIOUS=`/bin/cat $STATE_FILE`
else
   idle_drive_log "Initializing state for $DRIVE ($VALUE)."
   echo "$STATE" > $STATE_FILE
   rm -f $LOCK_FILE
   exit 0
fi

# If the I/O stats haven't changed, the drive is idle
if [ "$STATE" == "$STATE_PREVIOUS" ] && [ ! -f $DOWN_FILE ]; then
   idle_drive_log "Disk state unchanged and disk spinning. Spin down drive $DRIVE ($VALUE)"
   sync
   sdparm --flexible --command=sync $DRIVE &>/dev/null
   sdparm --flexible --command=stop $DRIVE &>/dev/null
   [ ! -f $FIX ] && sleep 5 && touch $FIX && sdparm --flexible --command=stop $DRIVE &>/dev/null
   STATE=`grep " $DISK " /proc/diskstats`
   echo "$STATE" > $STATE_FILE
   touch $DOWN_FILE
else
   if [ "$STATE" != "$STATE_PREVIOUS" ]; then
      idle_drive_log "Disk state changed. Deleting $DOWN_FILE and refreshing state."
      rm -f $DOWN_FILE
      echo "$STATE" > $STATE_FILE
   fi
fi

# Done
rm -f $LOCK_FILE
exit 0

Last edited by 666f6f; 09-19-2010 at 08:10 AM.
 
Old 04-12-2011, 11:04 PM   #4
MrVas
LQ Newbie
 
Registered: Jul 2010
Posts: 2

Rep: Reputation: 1
I've been trying to spindown my external USB hard drive (solely used for backup purposes) without much success until I stumbled across this and other similar threads. What in the end worked for me, were the following set of commands. I should also add that I'm using Slackware 13.1 (64-bit) and external Buffalo HD enclosure (HD-HC320IU2 - 320GB replaced with a 2TB drive).

Identify the correct SCSI generic (sg) device id for your drive. I only have two, so it was easy to "eyeball" the one I was looking for. If you only have two drives, the second drive will most likely be /dev/sg1 (/dev/sg0 being the primary hdd):
Code:
ls -la /dev/sg*
Use sdparm to spin the drive down (substitute your sg device for /dev/sgx):
Code:
sdparm -C stop /dev/sgx
Use sdparm again to spin the drive back up:
Code:
sdparm -C sync /dev/sgx
Hope this helps someone out.

Vas
 
1 members found this post helpful.
Old 04-13-2011, 01:11 PM   #5
catkin
LQ 5k Club
 
Registered: Dec 2008
Location: Tamil Nadu, India
Distribution: Debian
Posts: 8,578
Blog Entries: 31

Rep: Reputation: 1208Reputation: 1208Reputation: 1208Reputation: 1208Reputation: 1208Reputation: 1208Reputation: 1208Reputation: 1208Reputation: 1208
Thanks MrVas, it certainly helped me out

It works on Slackware64 13.1 with an Hitachi "Portable DRIVE" a.k.a "SimpleDRIVE Mini" (500 GB USB HDD), model 0S00462 -- something I've been wanting to do since Feb 2010.

One surprising phenomenon: the USB HDD did not get much cooler than it is when spinning and idle. Presumably the electronics consume significant power.

Next project: how to determine the /dev/sg* name programatically starting with partition major and minor numbers from udev, preferably without having to install sg_utils.
 
Old 12-04-2011, 09:18 AM   #6
catkin
LQ 5k Club
 
Registered: Dec 2008
Location: Tamil Nadu, India
Distribution: Debian
Posts: 8,578
Blog Entries: 31

Rep: Reputation: 1208Reputation: 1208Reputation: 1208Reputation: 1208Reputation: 1208Reputation: 1208Reputation: 1208Reputation: 1208Reputation: 1208
Given an HDD device file name, for example /dev/sdc, the corresponding /dev/sg* can be found by:
Code:
root@CW8:~# ls -l /sys/block/sdc
lrwxrwxrwx 1 root root 0 2011-12-04 20:35 /sys/block/sdc -> ../devices/pci0000:00/0000:00:1c.5/0000:06:00.0/usb3/3-4/3-4:1.0/host13/target13:0:0/13:0:0:0/block/sdc
root@CW8:~# ls -l /sys/devices/pci0000:00/0000:00:1c.5/0000:06:00.0/usb3/3-4/3-4:1.0/host13/target13:0:0/13:0:0:0/scsi_generic
total 0
drwxr-xr-x 3 root root 0 2011-12-04 20:03 sg4
EDIT: sample bash to implement that technique robustly, using stat instead of ls (assumes $disk_dev_file is something like /dev/sdc):
Code:
    # Spin down
    # ~~~~~~~~~
    msg I "spinning down $disk_dev_file ..." 
    sdX=${disk_dev_file##*/}
    buf=$( stat --format %N /sys/block/$sdX 2>&1 )
    buf=${buf#*../}
    buf=${buf%/block/$sdX*}
    buf=$( stat --format %n /sys/$buf/scsi_generic/* )
    dev_sgX=/dev/${buf##*/}
    msg D "SCSI generic device is $dev_sgX"
    buf=$( sdparm --command stop --quiet $dev_sgX 2>&1 )
    rc=$?
    [[ $buf != '' || $rc -ne 0 ]] && msg W "sdparm return code: $rc, output: "$'\n'"$buf

Last edited by catkin; 12-04-2011 at 10:02 AM.
 
Old 12-05-2012, 03:06 AM   #7
catkin
LQ 5k Club
 
Registered: Dec 2008
Location: Tamil Nadu, India
Distribution: Debian
Posts: 8,578
Blog Entries: 31

Rep: Reputation: 1208Reputation: 1208Reputation: 1208Reputation: 1208Reputation: 1208Reputation: 1208Reputation: 1208Reputation: 1208Reputation: 1208
The information in post 6 is outdated. Under Slackware64 14.0 (kernel 3.2.29, udev 182, sdparm 1.07) the SCSI pass-through device files are /dev/bsg/*, not /dev/sg* as earlier.

The general technique of using the SCSI pass-through device file as the sdparm DEVICE argument when sending commands is still valid.

Here's a function to implement it (logging and error trap code removed for clarity)
Code:
#--------------------------
# Name: spin_down_drive
# Purpose: spins down the drive
# Global variable used: $disk_dev_file
#--------------------------
function spin_down_drive {
    local dev_bsg_X

    # Get the /dev/bsg/* file name from the /dev/sd* file name
    # ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    # /dev/bsg/* is the "pass-through" interface to the SCSI driver.  It must
    # be used as the DEVICE argument when sdparm is used to send commands to
    # the device.
    dev_bsg_X=/dev/bsg/$( lsscsi --generic | grep $disk_dev_file | sed -e 's/\[//' -e 's/].*$//' )

    # Spin down
    # ~~~~~~~~~
    sdparm --command=stop --quiet $dev_bsg_X

}  # end of function spin_down_drive
EDIT: $disk_dev_file is, for example, /dev/sdc

Last edited by catkin; 12-05-2012 at 03:12 AM.
 
  


Reply



Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is Off
HTML code is Off



Similar Threads
Thread Thread Starter Forum Replies Last Post
DISCUSSION: External USB or firewire drives Steel_J LinuxAnswers Discussion 30 03-05-2012 01:46 PM
USB External Hard drives lukepiewalker Fedora 2 08-03-2005 09:14 AM
usb hubs and external hard drives buffed317 Linux - Hardware 1 07-20-2004 01:44 PM
Advice on External, portable FireWire/USB DVD drives garethw Linux - Hardware 2 02-08-2004 01:46 PM
USB / firewire hard drives with Linux? MadCactus Linux - General 2 08-15-2003 02:39 PM

LinuxQuestions.org > Forums > Linux Forums > Linux - Hardware

All times are GMT -5. The time now is 06:48 PM.

Main Menu
Advertisement
My LQ
Write for LQ
LinuxQuestions.org is looking for people interested in writing Editorials, Articles, Reviews, and more. If you'd like to contribute content, let us know.
Main Menu
Syndicate
RSS1  Latest Threads
RSS1  LQ News
Twitter: @linuxquestions
Open Source Consulting | Domain Registration