1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
|
package MDV::Draklive::Loopback;
use MDK::Common;
use File::Temp;
use MDV::Draklive::Progress;
use MDV::Draklive::Utils;
use Exporter;
our @ISA = qw(Exporter);
our @EXPORT = qw(%loop_types);
my $loop_number = 0;
our %loop_types;
%loop_types = (
squashfs => {
read_only => 1,
is_loopback => 1,
modules => sub { "loop", best_squashfs4_compression($_[0]) ? "squashfs" : "squashfs_lzma" },
extension => '-lzma.sqfs',
build => sub {
my ($live, $dir) = @_;
my $dest = $live->get_builddir . $live->{prefix}{build}{loopbacks} . $dir->{path} . $loop_types{squashfs}{extension};
mkdir_p(dirname($dest));
my $root = $dir->{root} || $live->get_system_root;
my $src = $root . $dir->{build_from};
my $total = directory_usage($src);
print "have to process " . int($total/1000000) . " MB\n";
my $progress = MDV::Draklive::Progress->new($total, time(), 6);
my $exclude_file = tmpnam();
output_p($exclude_file, map { $root . "$_\n" } grep { -e $root . $_ } @{$dir->{exclude} || []});
my $sort = $live->{settings}{config_root} . '/' . $dir->{sort};
my $squashfs4_comp = best_squashfs4_compression($live);
run_foreach(sub {
if (/^mksquashfs: file .*, uncompressed size (\d+) bytes\s*(?:DUPLICATE|LINK)?$/) {
$progress->{current} += $1;
$progress->show(time());
}
},
$squashfs4_comp ? 'mksquashfs' : 'mksquashfs3', $src, $dest,
$squashfs4_comp ? ('-comp', $squashfs4_comp) : '-lzma',
'-noappend', '-no-progress', '-info', '-b', '1048576',
#'-processors', 1,
'-ef', $exclude_file,
if_(-f $sort, '-sort', $sort),
) or die "unable to run mksquashfs\n";
$progress->end;
unlink $exclude_file;
},
mount => sub {
my ($live, $dir) = @_;
$dir->{loop} = "/dev/loop" . $loop_number++;
my $media_loopbacks = $live->get_media_prefix('loopbacks');
(
"/bin/losetup $dir->{loop} $live->{prefix}{live}{mnt}$live->{prefix}{media}{mnt}${media_loopbacks}$dir->{path}$loop_types{squashfs}{extension}",
"nash-mount -o ro -t squashfs $dir->{loop} $live->{prefix}{live}{mnt}$dir->{mountpoint}",
);
},
},
modules => {
read_only => 1,
delay_mount => 1,
mount => sub {
my ($live, $dir) = @_;
my $media_loopbacks = $live->get_media_prefix('loopbacks');
"sh -c 'modules=; for m in $live->{prefix}{live}{mnt}$live->{prefix}{media}{mnt}${media_loopbacks}$dir->{path}/*; do n=\$(basename \$m); n=\${n%.sqfs}; d=$live->{prefix}{live}{mnt}$dir->{mountpoint}/\$n; mkdir -p \$d; mount -n -o loop,ro -t squashfs \$m \$d && modules=\$modules\$d=ro:; done; echo \$modules | sed -e s/:\$// > $live->{prefix}{live}{mnt}/$dir->{list}'";
},
pivot_clean => sub {
my ($live, $dir, $initrdroot) = @_;
(
"sh -c 'cd $initrdroot$live->{prefix}{live}{mnt}$dir->{mountpoint}; for i in `ls -1`; do mkdir -p $live->{prefix}{live}{mnt}$dir->{mountpoint}/\$i; mount -n --move \$i $live->{prefix}{live}{mnt}$dir->{mountpoint}/\$i; rmdir \$i; done; rmdir $initrdroot$live->{prefix}{live}{mnt}$dir->{mountpoint}'",
"sh -c 'mv $initrdroot$live->{prefix}{live}{mnt}/$dir->{list} $live->{prefix}{live}{mnt}/'",
);
},
},
loopfs => {
is_loopback => 1,
modules => [],
extension => '.loop',
build => sub {
my ($live, $dir) = @_;
my $dest = $live->get_builddir . $live->{prefix}{build}{loopbacks} . $dir->{path} . $loop_types{loopfs}{extension};
mkdir_p(dirname($dest));
MDV::Draklive::Utils::device_allocate_file($dest, $dir->{pre_allocate});
MDV::Draklive::Utils::device_mkfs($dest, $dir->{fs}) if !defined $dir->{min_size};
},
mount => sub {
my ($live, $dir) = @_;
$dir->{loop} = "/dev/loop" . $loop_number++;
my $fsck = "chroot </dev/tty1 $live->{prefix}{live}{mnt}$dir_distrib_sqfs->{mountpoint} /sbin/fsck $dir->{loop}";
my $media_loopbacks = $live->get_media_prefix('loopbacks');
(
"losetup $dir->{loop} $live->{prefix}{live}{mnt}$live->{prefix}{media}{mnt}${media_loopbacks}$dir->{path}$loop_types{loopfs}{extension}",
qq(sh -c "$fsck -a || $fsck -y"),
"nash-mount -t $dir->{fs} $dir->{loop} $live->{prefix}{live}{mnt}$dir->{mountpoint}",
);
},
},
plain => {
skip_mkdir => 1,
mount => sub {
my ($live, $dir) = @_;
qq(sh -c "mkdir -p $live->{prefix}{live}{mnt}$dir->{mountpoint}");
},
},
partition => {
files => [ '/sbin/fsck', '/sbin/blkid' ],
mount => sub {
my ($live, $dir) = @_;
my $fsck = "/bin/fsck";
(
qq(sh -c 'dev=`blkid -l -t $dir->{path} -o device`; [ -z "\$dev" ] || $fsck -a \$dev || $fsck -y \$dev'),
"nash-mount -t $dir->{fs} $dir->{path} $live->{prefix}{live}{mnt}$dir->{mountpoint}",
);
},
},
tmpfs => {
mount => sub {
my ($live, $dir) = @_;
my $mnt = $live->{prefix}{live}{mnt} . $dir->{mountpoint};
my $mount_opts = $dir->{mount_opts}?"-o $dir->{mount_opts}":"";
my $cmd = "mount -t tmpfs $mount_opts $mnt $mnt";
$dir->{fallback} ? qq(sh -c 'if ! grep -q " $mnt " /proc/mounts; then $cmd; fi') : $cmd;
},
},
);
sub get_loop_modules {
my ($live, $type) = @_;
my $modules = $loop_types{$_}{modules};
my $type = ref $modules;
return $type eq 'CODE' ? $modules->($live) :
$type eq 'ARRAY' ? @$modules :
();
}
sub has_squashfs4_with {
my ($live, $comp) = @_;
my $kernel = $live->find_kernel;
my $ucomp = uc($comp);
cat_($live->get_system_root . "/boot/config-" . $live->find_kernel->{version}) =~ /^CONFIG_SQUASHFS_$ucomp=y$/m;
}
sub mksquashfs4_compressors() {
map { /^Compressors available/ .. /^$/ ? if_(/^\t(\w+)/, chomp_($1)) : () } `mksquashfs 2>&1`;
}
sub best_squashfs4_compression {
my ($live) = @_;
find { has_squashfs4_with($live, $_) } intersection([ mksquashfs4_compressors() ], [ qw(xz lzma) ]);
}
1;
|