it-swarm-id.com

Bagaimana saya tahu jika dd masih berfungsi?

Saya belum menggunakan dd sebanyak itu, tapi sejauh ini saya belum gagal. Saat ini, saya sudah mendapatkan dd selama lebih dari 12 jam - Saya menulis gambar kembali ke disk asalnya - dan saya sedikit khawatir, karena saya dapat dd dari disk ke gambar dalam sekitar 7 jam.

Saya menjalankan OSX 10.6.6 pada MacBook dengan Core 2 Duo di 2.1ghz/core dengan RAM 4GB. Saya membaca dari .dmg pada hard drive 7200rpm (drive boot), dan saya menulis ke drive 7200rpm yang terhubung melalui konektor SATA-to-USB. Saya meninggalkan blocksize secara default, dan gambar sekitar 160gb.

EDIT: Dan, setelah 14 jam penuh stres, dd bekerja dengan baik. Namun lain kali, saya akan menjalankannya melalui pv dan melacaknya dengan strace. Terima kasih untuk semua orang atas semua bantuan Anda.

150
eckza

Anda dapat mengirim dd sinyal tertentu menggunakan perintah kill untuk membuatnya mengeluarkan status saat ini. Sinyal adalah INFO pada sistem BSD (termasuk OSX) dan USR1 di Linux. Dalam kasus Anda:

kill -INFO $PID

Anda dapat menemukan id proses ($PID di atas) dengan perintah ps; atau lihat pgrep dan pkill alternatif pada mac os x untuk metode yang lebih mudah.

Lebih sederhana, seperti AntoineG menunjukkan --- jawabannya , Anda dapat mengetik ctrl-T di Shell yang menjalankan dd untuk mengirimkannya sinyal INFO.

Sebagai contoh di Linux, Anda dapat membuat semua _ dd aktif memproses status keluaran seperti ini:

pkill -USR1 -x dd

Setelah mengeluarkan statusnya, dd akan terus mengatasi.

176
Caleb

Di bawah OS X (tidak mencoba di Linux), Anda cukup mengetik Ctrl+T dalam terminal yang menjalankan dd. Ini akan mencetak output yang sama dengan kill -INFO $PID, ditambah penggunaan CPU:

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)

Saya mengetahui tentang hal itu membaca utas ini, dan mencoba membuka tab baru di terminal saya tetapi mencampur +T dengan Ctrl+T.

104
AntoineG

Untuk dd, Anda dapat mengirim sinyal . Untuk perintah lain yang sedang membaca atau menulis ke file, Anda dapat melihat posisinya dalam file dengan lsof .

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

Jika Anda berencana terlebih dahulu, pipa data melalui pv .

Cara yang lebih umum adalah dengan menggunakan iotop yang menampilkan jumlah saat ini pembacaan/penulisan disk per program.

EDIT: iotop -o hanya tampilkan program yang menjalankan operasi I/O saat ini (terima kasih Jason C untuk komentar ini).

17
jofel

Saya biasanya melampirkan strace ke proses yang berjalan (dengan -p $PID opsi) untuk melihat apakah tetap diblokir dalam panggilan sistem atau jika masih aktif.

Atau, jika Anda merasa gugup mengirim sinyal ke dd berjalan, mulai dd lain untuk memvalidasi jika ini berfungsi.

13
philfr

Untuk waktu berikutnya, Anda bisa menggunakan pv dari awal (jika tersedia melalui manajer paket Anda, instal). Ini adalah utilitas dengan tujuan tunggal menyalurkan input ke output dan memantau kemajuan dan kecepatan.

Kemudian, untuk menulis gambar ke drive, katakan dengan ukuran blok 4MB:

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

Selain dari buffering awal (diimbangi dengan sinkronisasi akhir, yang dapat dilakukan melalui dd jika Anda mau), ini akan menampilkan bilah kemajuan, kecepatan rata-rata, kecepatan saat ini, dan ETA.

iflag=fullblock opsi memaksa dd untuk mengambil blok input penuh melalui pv, jika tidak, Anda berada pada belas kasihan pipa untuk ukuran blok.

Untuk ke arah lain gunakan dd untuk membaca dan pv untuk menulis, meskipun Anda harus secara eksplisit menentukan ukuran jika sumbernya adalah perangkat blok. Untuk perangkat 4GB:

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

Anda juga dapat menentukan ukuran secara otomatis, seperti:

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

Tidak masalah urutan apa yang Anda lakukan dd dan pv in, itu sepenuhnya terkait dengan kinerja - jika perangkat yang Anda baca memiliki kinerja optimal untuk pemblokiran tertentu yang ingin Anda lakukan. gunakan dd alih-alih pv untuk mengakses perangkat itu. Anda bahkan dapat menempelkan dd di kedua ujungnya jika Anda mau, atau tidak sama sekali jika Anda tidak peduli:

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

Pada coreutils v8.24, dd memiliki dukungan asli untuk menunjukkan kemajuan. Cukup tambahkan opsi status=progress.

Contoh:

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

Sumber

ddrescue akan memberi Anda statistik saat sedang berjalan.

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

5
Ben Preston

Saya mulai menggunakan dcfldd (1), yang menunjukkan operasi dd dengan cara yang lebih baik.

4
Kartik M

Kadang-kadang Anda mungkin tidak dapat menggunakan sinyal INFO atau USR1 karena aliran stderr proses dd tidak dapat diakses (mis. Karena terminal tempat eksekusi itu sudah ditutup). Dalam hal ini, solusinya adalah dengan melakukan hal berikut (diuji pada FreeBSD, mungkin sedikit berbeda di Linux):

  1. Gunakan iostat untuk memperkirakan laju tulis rata-rata (MB/d) ke perangkat target, mis .: .:

    iostat -d -w30 ada0

    Ganti nama perangkat target Anda dengan ada0 di sini, dan tunggu sebentar untuk memberikan hasil beberapa. Parameter "w" menentukan berapa detik antara sampel. Menambahnya akan memberikan perkiraan rata-rata yang lebih baik dengan varian yang lebih sedikit, tetapi Anda harus menunggu lebih lama.

  2. Gunakan ps untuk menentukan berapa lama dd telah berjalan:

    ps -xo etime,command | grep dd

    Ubah ini menjadi detik untuk mendapatkan runtime total detik.

  3. Lipat gandakan total detik runtime dengan rata-rata tingkat penulisan untuk mendapatkan MB total yang ditransfer.
  4. Dapatkan ukuran perangkat dalam MB dengan:

    grep ada0 /var/run/dmesg.boot

    Ganti nama perangkat target Anda dengan ada0. Bagi hasil dengan rata-rata tingkat penulisan untuk mendapatkan total waktu transfer dalam detik. Kurangi waktu yang sudah berjalan sejauh ini untuk mendapatkan sisa waktu.

Strategi ini hanya berfungsi jika dd telah menulis terus menerus pada tingkat penulisan rata-rata saat ini sejak dimulai. Jika proses lain bersaing untuk sumber daya CPU atau I/O (termasuk bus I/O) maka dapat mengurangi tingkat transfer.

4
D Coetzee

Anda dapat menggunakan progress yang, secara khusus, menunjukkan progres running dd. Itu menggunakan /proc/$pid/fd dan /proc/$pid/fdinfo yang juga bisa Anda monitor dengan tangan.

3
jofel

Ketika dd dieksekusi, saya menjalankan ini di terminal lain sebagai root:

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

Ia mencetak status dd setiap 1 detik di jendela terminal asli di mana dd mengeksekusi, dan berhenti ketika perintah selesai.

2
ccpizza

Baris wchar (karakter tertulis) di /proc/$pid/io Dapat memberi Anda informasi yang tepat tentang proses dd. Selama itu berubah, dd Anda masih berfungsi!

Berikut ini adalah skrip php kecil yang rapi, yang dapat Anda simpan dan kemudian jalankan dengan php filename.php Selama dd untuk menampilkan byte yang ditulis. Manfaat Nice menonton /proc/$pid/io Lebih dari kill -USR1 $(pidof dd) adalah Anda tidak harus beralih antar terminal, yang tidak selalu menjadi pilihan.

<?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