it-swarm-eu.dev

Jak zjistím, zda dd stále funguje?

Nepoužil jsem tolik dd, ale zatím mě to nezklamalo. Právě teď jsem měl dd déle než 12 hodin - píšu obrázek zpět na disk, ze kterého vyšel - a trochu se bojím, protože jsem byl schopen dd z disku na obrázek přibližně za 7 hodin.

Používám OSX 10.6.6 na MacBooku s Core 2 Duo při 2,1 Hz/jádro s 4 GB RAM. Čtu z .dmg na pevném disku 7200 ot/min (spouštěcí jednotka) a píšu na jednotku 7200 ot/min připojenou přes konektor SATA-USB. Výchozí blokování jsem nechal a obrázek je asi 160 gb.

EDIT: A po 14 hodinách čistého stresu fungoval dd dokonale. Příště to však budu procházet pv a sledovat jej pomocí strace. Děkujeme všem za vaši pomoc.

150
eckza

Můžete poslat dd určitý signál pomocí příkazu kill, aby byl výstup aktuální. Signál je INFO na BSD systémech (včetně OSX) a USR1 na Linuxu. Ve vašem případě:

kill -INFO $PID

Můžete najít ID procesu ($PID výše) pomocí příkazu ps; nebo viz alternativy pgrep a pkill na mac os x pro pohodlnější metody.

Jednoduše, jak AntoineG poukazuje na jeho odpověď , můžete zadat ctrl-T na Shell běžícím dd, aby mu poslal signál INFO.

Jako příklad na Linuxu můžete uvést všechny aktivní stavy dd zpracovává takto:

pkill -USR1 -x dd

Po výstupu svého stavu bude dd pokračovat v zvládání.

176
Caleb

V OS X (nezkoušejte na Linuxu) můžete jednoduše napsat Ctrl+T v terminálu běžícím dd. Bude tisknout stejný výstup jako kill -INFO $PID plus využití procesoru:

load: 1.40  cmd: dd 34536 uninterruptible 3.49u 64.58s
5020305+0 records in
5020304+0 records out
2570395648 bytes transferred in 4284.349974 secs (599950 bytes/sec)

Zjistil jsem, že to přečtu toto vlákno a pokusím se otevřít v mém terminálu novou kartu, ale smíchat +T s Ctrl+T.

104
AntoineG

Pro dd můžete poslat signál . U ostatních příkazů, které čtou nebo zapisují do souboru, můžete sledovat jejich polohu v souboru pomocí lsof .

lsof -o -p1234    # where 1234 is the process ID of the command
lsof -o /path/to/file

Pokud plánujete předem, posílejte data přes pv .

Obecnějším způsobem je použití iotop , které zobrazuje aktuální množství čtení/zápisu na disk v programu.

UPRAVIT: iotop -o zobrazují pouze programy, které aktuálně provádějí operace I/O (díky Jason C za tento komentář).

17
jofel

Obvykle připojím strace k takovému běžícímu procesu (s -p $PID možnost), abyste zjistili, zda zůstane blokováno při systémovém volání nebo zda je stále aktivní.

Nebo, pokud máte nervozitu z odesílání signálu do běžícího dd, spusťte další dd a ověřte, zda to funguje.

13
philfr

Příště můžete použít pv od začátku (pokud je k dispozici prostřednictvím správce balíků, nainstalujte jej). Jedná se o obslužný program, jehož jediným účelem je vstup potrubí do výstupu a sledování pokroku a rychlosti.

Pak, pro zápis obrazu na disk, řekněme s velikostí bloku 4 MB:

pv -ptearb /path/to/image.bin | dd iflag=fullblock of=/dev/whatever bs=4M

Kromě počátečního ukládání do vyrovnávací paměti (vykompenzovaného konečnou synchronizací, které lze provést pomocí dd, pokud chcete), se zobrazí ukazatel průběhu, průměrná rychlost, aktuální rychlost a ETA.

The iflag=fullblock volba nutí dd chytit celé bloky vstupu skrz pv, jinak jste na milost potrubí pro velikosti bloků.

Chcete-li jít opačným způsobem, použijte dd pro čtení a pv pro zápis, i když musíte určit explicitně velikost, pokud je zdrojem blokové zařízení. Pro 4GB zařízení:

dd if=/dev/whatever bs=4M | pv -ptearb -s 4096m > /path/to/image.bin

Můžete také určit velikost automaticky, například:

dd if=/dev/whatever bs=4M | pv -ptearb -s `blockdev --getsize64 /dev/whatever` > /path/to/image.bin

Opravdu nezáleží na tom, v jakém pořadí dd a pv in, je to zcela závislé na výkonu - pokud zařízení, které čtete nebo od něj, má optimální výkon pro určité blokování, které chcete použijte dd místo pv pro přístup k tomuto zařízení. Můžete dokonce nalepit dd na oba konce, pokud chcete, nebo vůbec ne, pokud vám to nezáleží:

pv -ptearb /path/to/image.bin > /dev/whatever
sync
11
Jason C

Od coreutils v8.24 má dd nativní podporu pro zobrazení pokroku. Stačí přidat možnost status=progress.

Příklad:

dd if=Arch.iso of=/dev/sdb bs=4M status=progress

Zdroj

ddrescue vám poskytne statistiky, jak běží.

demo: http://www.youtube.com/watch?v=vqq9A01geeA#t=144s

5
Ben Preston

Začal jsem používat dcfldd (1), což ukazuje dd operace lépe.

4
Kartik M

Někdy nemusí být možné použít signál INFO nebo USR1, protože stderrový tok procesu dd není přístupný (např. Protože terminál, ve kterém byl proveden, byl již uzavřen). V tomto případě je řešením následující postup (testováno na FreeBSD, v systému Linux se může mírně lišit):

  1. Pomocí iostat můžete odhadnout průměrnou rychlost zápisu (MB/s) do cílového zařízení, např .:

    iostat -d -w30 ada0

    Nahraďte název svého cílového zařízení ada0 zde a počkejte minutu, než se objeví pár výsledků. Parametr „w“ určuje, kolik sekund mezi vzorky. Jeho zvýšení poskytne lepší průměrný odhad s menší rozptylem, ale budete muset čekat déle.

  2. Pomocí ps určete, jak dlouho dd běží:

    ps -xo etime,command | grep dd

    Převeďte na sekundy a získejte celkem sekundy runtime.

  3. Vynásobte celkem sekundy běhu průměrnou rychlostí zápisu, abyste získali celkový přenesený MB.
  4. Získejte velikost zařízení v MB pomocí:

    grep ada0 /var/run/dmesg.boot

    Nahraďte název svého cílového zařízení ada0. Vydělte výsledek průměrnou rychlostí zápisu, abyste získali celkovou dobu přenosu v sekundách. Odečtěte čas, který dosud běžel, abyste získali zbývající čas.

Tato strategie funguje, pouze pokud dd píše nepřetržitě při současné průměrné rychlosti zápisu od začátku. Pokud o procesory nebo I/O prostředky (včetně I/O sběrnice) soupeří jiné procesy, může to snížit rychlost přenosu.

4
D Coetzee

Můžete použít progress , který zejména ukazuje průběh běžícího dd. Používá /proc/$pid/fd a /proc/$pid/fdinfo které můžete také sledovat ručně.

3
jofel

Zatímco dd se provádí, spustím to v jiném terminálu jako root:

while pgrep ^dd; do pkill -INFO dd; sleep 1; done

Vytiskne stav dd každých 1 sekundu v původním okně terminál, kde se provádí dd, a skončí, když je příkaz dokončen.

2
ccpizza

Řádek wchar (psané znaky) v /proc/$pid/io Vám může poskytnout přesné informace o procesu dd. Dokud se změní, vaše dd stále funguje!

Zde je úhledný malý skript php, který můžete uložit a poté spustit pomocí php filename.php Během dd pro zobrazení zapsaných bytů. Výhodou sledování /proc/$pid/io Oproti kill -USR1 $(pidof dd) je, že nemusíte přepínat mezi terminály, což není vždy možnost.

<?php

/** Time between refreshs in seconds */
$refresh = 1;


/**
 * Start of Script 
 */

if (!($pid = exec('pidof dd')))
    exit("no dd running\n");

$history = array();
$break_ms = $refresh * 1000000;
$start_time = exec("ls -ld /proc/$pid --time-style=+\"%s\" | egrep -o [0-9]{10}");


fprintf(STDOUT, "PID: %s\n", $pid);
fprintf(STDOUT, "START TIME: %s\n\n", date("Y-m-d H:i:s", $start_time));


while (true) {
    if (isset($curr))
        array_Push($history, $curr);

    if (count($history) > 10) array_shift($history);
    $oldest = reset($history);
    $latest = end($history);

    /**
     * get number of written bytes from /proc/$pid/io
     */
    #if (!($curr = exec("cat /proc/$pid/io | grep ^write_bytes | sed 's/write_bytes: //g'")))
    #    break;

    /* prepare proc_open() parameter */
    $descriptorspec = array(
        0 => array('pipe', 'r'), // stdin
        1 => array('pipe', 'w'), // stdout
        2 => array('pipe', 'w'), // stderr
    );

    $process = proc_open("cat /proc/$pid/io | grep ^write_bytes | sed 's/write_bytes: //g'", $descriptorspec, $pipes);
    if (!is_resource($process)) break;

    $stdout = stream_get_contents($pipes[1]);
    $stderr = stream_get_contents($pipes[2]);
    proc_close($process);

    if (!empty($stderr)) break;
    $curr = trim($stdout);

    /**
     * caculate elapsed time from start */
    $time_elapsed = time() - $start_time;

    /**
     * avg speed since start */
    $avg = $time_elapsed > 0 ? round($curr / $time_elapsed) : 0;

    /**
     * avg speed of last 10 updates */
    if (count($history) > 0)
        $speed = human_file_size(round(($latest - $oldest) / count($history) / $refresh));

    $output = sprintf("\rBYTES WRITTEN: %s [%s]  ::  CURRENT: %s/s  ::  AVERAGE: %s/s  ::  ELAPSED: %s", $curr, human_file_size($curr), isset($speed) ? $speed : 0, human_file_size($avg), gmdate("H:i:s", $time_elapsed));
    printf("%s%s", $output, str_repeat(" ", exec("tput cols") - strlen($output)));

    usleep($break_ms);
}

fprintf(STDOUT, "\ndd has finished!\n\n");

function human_file_size($size,$unit="") {
  if( (!$unit && $size >= 1<<30) || $unit == "GB")
    return number_format($size/(1<<30),2)." GB";
  if( (!$unit && $size >= 1<<20) || $unit == "MB")
    return number_format($size/(1<<20),2)." MB";
  if( (!$unit && $size >= 1<<10) || $unit == "kB")
    return number_format($size/(1<<10),2)." kB";
  return number_format($size)." bytes";
}
1
Leon Kramer