Escreva o mesmo arquivo várias vezes em um arquivo usando o dd

4

Eu estou tentando criar grandes arquivos fictícios em uma unidade usando o dd. Atualmente estou fazendo isso:

#!/bin/bash
writeFile(){ #$1 - destination directory/filename, $2 - source filepath $3 - blocksize, $4 - blockcount $5 - log file name

if [ "$#" -ne 5 ]; then
    echo "Bad number of args - Should be 4, not $#"
    return 1;
fi

dest_filepath=$1
src_filepath=$2
block_size=$3
block_count=$4
log_file=$5

int_regex='^[0-9]+$' 

file_size=$(($block_size * $block_count))
src_file_size='ls -l $src_filepath | awk '{print $5}''
full_iter=0
while [[ $file_size -ge $src_file_size ]]; do
    file_size=$((file_size - $src_file_size))
    full_iter=$((full_iter + 1))
done

section_block_count=$(($src_file_size / $block_size))
echo $section_block_count $block_size
topping_off_block_count=$(($file_size / $block_size))

dest_dir=$(dirname $dest_filepath)
if [ -d "$dest_dir" ] && [ -r $src_filepath ] && [[ $block_size =~ $int_regex ]] && [[ $block_count =~ $int_regex ]]; then
    data_written=0
    for (( i=0 ; i < $full_iter ; i=$((i+1)) )); do
        (time dd of=$dest_filepath if=$src_filepath bs=$block_size count=$section_block_count seek=$data_written) >> $log_file 2>&1 #Output going to external file
        data_written=$(($data_written + $src_file_size +1 ))
        echo $data_written
    done

    if [[ $file_size -gt 0 ]]; then
        (time dd of=$dest_filepath if=$src_filepath bs=$block_size count=$topping_off_block_count seek=$data_written) >> $log_file 2>&1 & #Output going to external file
    fi
    return 0;
fi

return 1;   
}

No entanto, isso não está funcionando, já que é só gravar do src_filepath uma vez ou gravar na mesma parte do arquivo várias vezes, não sei como descobrir a diferença. Neste caso em particular, o que estou fazendo é escrever de um arquivo de 256MB 4 vezes para criar um único arquivo de 1GB, mas eu quero mantê-lo genérico para que eu possa escrever qualquer tamanho de e para.

O objetivo é fragmentar um disco rígido e medir a saída de dd (taxa de transferência especificamente) e o tempo que levou.

Eu estou em um sistema embarcado com funcionalidade limitada, e o sistema operacional é uma versão muito ruim do linux usando o busybox.

Como eu altero isso para que ele escreva o arquivo de tamanho correto?

    
por Yann 28.10.2014 / 16:29

1 resposta

1

respondendo aos comentários: conv=notrunc torna dd não truncado, mas não o leva até o fim. (Ele deixa de fora O_TRUNC , mas não adiciona O_APPEND na chamada do sistema open(2) ).

Respondendo a pergunta: Se você insistir em usar dd em vez de cat , então pegue o shell para abrir o arquivo de saída para acrescentar, e escreva dd em seu stdout.

dd if=src bs=128k count=$count of=/dev/stdout >> dest 2>> log

Além disso, se você estiver tentando fragmentar sua unidade, poderá fazer um monte de fallocate(1) alocações para usar espaço e começar a usar o dd quando a unidade estiver quase cheia. O programa fallocate do util-linux é um simples front-end para a chamada do sistema fallocate(2) .

O

xfs, por exemplo, detectará o padrão aberto, anexado e deixará seu espaço espectralmente pré-alocado além do EOF alocado por alguns segundos após o fechamento. Portanto, no XFS, um loop de anexação ao mesmo arquivo repetidamente não produzirá tanta fragmentação quanto a gravação de muitos arquivos pequenos.

Você está em um sistema embarcado, então eu suponho que você não esteja usando o xfs. Nesse caso, você ainda poderá ver menos fragmentação do seu close / reabrir / gravar mais do que você esperaria, com um sistema de arquivos decentemente inteligente. Talvez sincronizar entre cada gravação, esperar que o FS aloque e escreva todos os seus dados, antes de informar que há mais novidades.

    
por 18.04.2015 / 14:32