mrremo
mrremo

Reputation: 13

dd an image to SD card finished, SD card still busy

If I'm using dd to restore an *.img file to an SD card, it works without problems. If I try to safely remove (eject in nautilus) the SD card right after dd is finished, a notification is poping up which says: "Something is writing to SD card". The LED on the card reader is blinking as well. It takes a couple minutes until it's possible to remove the card. First question is, how can that be?

I'm using dd in a bash script. As soon as the script is finished it should be possible to remove the SD card. Second question is, can I somehow check the status of the SD card which means busy or not?

Edit 20170203: This is the script. The purpose is just to restore an raspberry pi backup.

#!/bin/bash
#
#enter path of image
IMG=$(whiptail --inputbox "Enter path to image." 8 78 "$HOME/Downloads/raspberry_backup.img.gz" --title "Name" 3>&1 1>&2 2>&3)

exitstatus=$?
if [ $exitstatus != 0 ]; then
    echo "INFO: User abort."
    exit 1
fi

#check for dependencies
if [ -z "$(which parted 2> /dev/null)" ] || [ -z "$(which gzip 2> /dev/null)" ]; then
    if (whiptail --title "Dependencies" --yesno "This script need parted and gzip. One or more are not installed. Install now?" 8 78) then
        sudo dnf install -y parted gzip
    else
        exit 1
    fi
fi

#show information of drives
whiptail --scrolltext --title "Info about mounted devices:" --msgbox "$(sudo parted -l -m init G print | grep /dev/sd | cut -d: -f1,2)" 8 78

#enter drive name
DEV=$(whiptail --inputbox "Enter Device Name." 8 78 /dev/sd --title "Device Name" 3>&1 1>&2 2>&3)

exitstatus=$?
if [ $exitstatus != 0 ]; then
    echo "INFO: User abort."
    exit 1
fi

#check for /dev/sd* vaidity
if [[ $DEV != "/dev/sd"* ]]; then
    echo "ERROR: ${DEV} is not valid."
    exit 1
fi

#if restore image is *.gz then uncomress first
if [[ "$IMG" == *".gz" ]]; then
    (pv -n ${IMG} | gzip -d -k > $HOME/raspberry_restore.img) 2>&1 | whiptail --gauge "Please wait while uncompressing image..." 6 50 0
    IMG=$HOME/raspberry_restore.img
fi

if [[ "$IMG" == *".img" ]]; then
    SIZEDD=$(sudo parted -m $IMG unit B print | grep ext4 | cut -d: -f3 | cut -dB -f1)
    (sudo dd if=$IMG bs=1M | pv -n --size $SIZEDD | sudo dd of=$DEV bs=1M) 2>&1 | whiptail --gauge "Please wait while restoring image to SD card..." 6 50 0
else
    echo "ERROR: Not an *.img file"
    exit 1
fi

sudo rm $HOME/raspberry_restore.img

#show information
whiptail --title "Restore finished." --msgbox "Restored to path: "$DEV"" 8 78
exit 1

Thanks

Upvotes: 1

Views: 1055

Answers (3)

Charles Duffy
Charles Duffy

Reputation: 295325

The fsync() syscall will cause any write caching at the OS level to be flushed. While something could be written in C to call this for the specific block device at hand, from the shell, your easiest way to get there in shell is using the sync command to flush all pending writes, across all filesystems and devices:

sync

Alternately, you can tell dd to use the O_SYNC flag, by passing oflag=sync, preventing dd from exiting until the write is persisted to disk:

# note that oflag is a GNU extension, not found on MacOS/BSD
dd oflag=nocache,sync of="$DEV" bs=1M

If you know the native block size for your SD card, consider using O_DIRECT instead:

# 4k is a reasonable guess on block size; tune based on your actual hardware.
dd oflag=direct of="$DEV" bs=4K

Upvotes: 3

Defrag
Defrag

Reputation: 416

I suggest you using this very quick perl script described here: https://askubuntu.com/a/216628

I've used myself sometimes too to find unwanted/hidden/unknown processes that keeps resources busy.

Once you get the process, the inner behaviour that keeps your SSD busy can be investigated.

Upvotes: 1

mgor
mgor

Reputation: 230

You can use lsof if something is using the device. If your SD card is identified as /dev/sdd:

lsof /dev/sdd 2>/dev/null && echo "device is busy"

Upvotes: 0

Related Questions