四
lustre的manual上有个用shell写的脚本, 但那个脚本需要等查找整个目录完了才开始重写.如果目录很大(如果不大就不需要做集群了), 这个搜索的时间会非常长. 我用perl重新实现了这个脚本, 可以边搜索边重写.
lustre难免某个ost因为空间变少或其它原因, 要更换ost. 这时, 就需要把这个ost上的数据导出转移到其它ost上,然后再更换设备.
或者, 当新加了一个ost, 但这里面没有数据, 而同时其它的ost上数据过多, 这时负载不均.
这个脚本用来把某个目录中属于某个OST上的文件, 重写来达到均衡.如果你是需要迁移数据, 请先把指定的ost deactivate.( lctl dl; lctl –device n deactivate)
注: 本脚本未保留原文件的属主, 权限位等属性. 如对此有要求, 请暂时用系统的cp命令并加-dp选项.
1 #!/usr/bin/perl -w
2
3 use Digest::MD5;
4 use File::Copy;
5 use File::Temp qw/:mktemp/;;
6 use strict;
7
8
9 if (@ARGV != 2)
10 {
11 print “Usage: <obd> <directory>\n”;
12 exit 1;
13 }
14
15 open IN, ‘-|’, “lfs getstripe -r -O $ARGV[0] $ARGV[1]” or die “$!”;
16 #open IN, “<felix” or die “$!”;
17
18 while (<IN>)
19 {
20 chomp;
21 my $f = $_;
22 if (-d $f)
23 {
24 print “$f : is a directory, skip\n”;
25 next;
26 }
27
28 ### get the md5
29 my $md5 = Digest::MD5->new;
30 open F, $f or die “Can’t read $f: $!”;
31 binmode(F);
32 $md5->addfile(*F);
33 close F;
34
35 ### copy to temporary file
36 my $tpl = $f . ‘.XXXXXX’;
37 my $new = mktemp($tpl);
38 unless(copy($f, $new))
39 {
40 print “$f: copy error: $!”;
41 unlink $new;
42 exit 1;
43 }
44
45 my $newmd5 = Digest::MD5->new;
46 open NF, $new or die “Can’t read $new: $!”;
47 binmode(NF);
48 $newmd5->addfile(*NF);
49 close NF;
50 if( $md5->hexdigest ne $newmd5->hexdigest)
51 {
52 print “$new bad checksum, $f not moved\n”;
53 unlink $new;
54 exit 1;
55 }
56 unless (move($new, $f))
57 {
58 print “$f move error: $!”;
59 unlink $new;
60 exit 1;
61 }
62 print “$f\n”;
63 }