]>
Commit | Line | Data |
---|---|---|
f507c3a7 WL |
1 | package PVE::VZDump::ConvertOVZ; |
2 | ||
3 | use strict; | |
4 | use warnings; | |
5 | use POSIX qw (LONG_MAX); | |
6 | ||
7 | my $res_unlimited = LONG_MAX; | |
8 | ||
9 | sub ovz_config_extract_mem_swap { | |
10 | my ($veconf, $unit) = @_; | |
11 | ||
12 | $unit = 1 if !$unit; | |
13 | ||
14 | my ($mem, $swap) = (int((512*1024*1024 + $unit - 1)/$unit), 0); | |
15 | ||
16 | my $maxpages = ($res_unlimited / 4096); | |
17 | ||
18 | if ($veconf->{swappages}) { | |
19 | if ($veconf->{physpages} && $veconf->{physpages}->{lim} && | |
20 | ($veconf->{physpages}->{lim} < $maxpages)) { | |
21 | $mem = int(($veconf->{physpages}->{lim} * 4096 + $unit - 1) / $unit); | |
22 | } | |
23 | if ($veconf->{swappages}->{lim} && ($veconf->{swappages}->{lim} < $maxpages)) { | |
24 | $swap = int (($veconf->{swappages}->{lim} * 4096 + $unit - 1) / $unit); | |
25 | } | |
26 | } else { | |
27 | if ($veconf->{vmguarpages} && $veconf->{vmguarpages}->{bar} && | |
28 | ($veconf->{vmguarpages}->{bar} < $maxpages)) { | |
29 | $mem = int(($veconf->{vmguarpages}->{bar} * 4096 + $unit - 1) / $unit); | |
30 | } | |
31 | } | |
32 | ||
33 | return ($mem, $swap); | |
34 | } | |
35 | ||
36 | sub parse_res_num_ignore { | |
37 | my ($key, $text) = @_; | |
38 | ||
39 | if ($text =~ m/^(\d+|unlimited)(:.*)?$/) { | |
40 | return { bar => $1 eq 'unlimited' ? $res_unlimited : $1 }; | |
41 | } | |
42 | ||
43 | return undef; | |
44 | } | |
45 | ||
46 | sub parse_res_num_num { | |
47 | my ($key, $text) = @_; | |
48 | ||
49 | if ($text =~ m/^(\d+|unlimited)(:(\d+|unlimited))?$/) { | |
50 | my $res = { bar => $1 eq 'unlimited' ? $res_unlimited : $1 }; | |
51 | if (defined($3)) { | |
52 | $res->{lim} = $3 eq 'unlimited' ? $res_unlimited : $3; | |
53 | } else { | |
54 | $res->{lim} = $res->{bar}; | |
55 | } | |
56 | return $res; | |
57 | } | |
58 | ||
59 | return undef; | |
60 | } | |
61 | ||
62 | sub parse_res_bar_limit { | |
63 | my ($text, $base) = @_; | |
64 | ||
65 | return $res_unlimited if $text eq 'unlimited'; | |
66 | ||
67 | if ($text =~ m/^(\d+)([TGMKP])?$/i) { | |
68 | my $val = $1; | |
69 | my $mult = $2 ? lc($2) : ''; | |
70 | if ($mult eq 'k') { | |
71 | $val = $val * 1024; | |
72 | } elsif ($mult eq 'm') { | |
73 | $val = $val * 1024 * 1024; | |
74 | } elsif ($mult eq 'g') { | |
75 | $val = $val * 1024 * 1024 * 1024; | |
76 | } elsif ($mult eq 't') { | |
77 | $val = $val * 1024 * 1024 * 1024 * 1024; | |
78 | } elsif ($mult eq 'p') { | |
79 | $val = $val * 4096; | |
80 | } else { | |
81 | return $val; | |
82 | } | |
83 | return int($val/$base); | |
84 | } | |
85 | ||
86 | return undef; | |
87 | } | |
88 | ||
89 | sub parse_res_bytes_bytes { | |
90 | my ($key, $text) = @_; | |
91 | ||
92 | my @a = split(/:/, $text); | |
93 | $a[1] = $a[0] if !defined($a[1]); | |
94 | ||
95 | my $bar = parse_res_bar_limit($a[0], 1); | |
96 | my $lim = parse_res_bar_limit($a[1], 1); | |
97 | ||
98 | if (defined($bar) && defined($lim)) { | |
99 | return { bar => $bar, lim => $lim }; | |
100 | } | |
101 | ||
102 | return undef; | |
103 | } | |
104 | ||
105 | sub parse_res_block_block { | |
106 | my ($key, $text) = @_; | |
107 | ||
108 | my @a = split(/:/, $text); | |
109 | $a[1] = $a[0] if !defined($a[1]); | |
110 | ||
111 | my $bar = parse_res_bar_limit($a[0], 1024); | |
112 | my $lim = parse_res_bar_limit($a[1], 1024); | |
113 | ||
114 | if (defined($bar) && defined($lim)) { | |
115 | return { bar => $bar, lim => $lim }; | |
116 | } | |
117 | ||
118 | return undef; | |
119 | } | |
120 | ||
121 | sub parse_res_pages_pages { | |
122 | my ($key, $text) = @_; | |
123 | ||
124 | my @a = split(/:/, $text); | |
125 | $a[1] = $a[0] if !defined($a[1]); | |
126 | ||
127 | my $bar = parse_res_bar_limit($a[0], 4096); | |
128 | my $lim = parse_res_bar_limit($a[1], 4096); | |
129 | ||
130 | if (defined($bar) && defined($lim)) { | |
131 | return { bar => $bar, lim => $lim }; | |
132 | } | |
133 | ||
134 | return undef; | |
135 | } | |
136 | ||
137 | sub parse_res_pages_unlimited { | |
138 | my ($key, $text) = @_; | |
139 | ||
140 | my @a = split(/:/, $text); | |
141 | ||
142 | my $bar = parse_res_bar_limit($a[0], 4096); | |
143 | ||
144 | if (defined($bar)) { | |
145 | return { bar => $bar, lim => $res_unlimited }; | |
146 | } | |
147 | ||
148 | return undef; | |
149 | } | |
150 | ||
151 | sub parse_res_pages_ignore { | |
152 | my ($key, $text) = @_; | |
153 | ||
154 | my @a = split(/:/, $text); | |
155 | ||
156 | my $bar = parse_res_bar_limit($a[0], 4096); | |
157 | ||
158 | if (defined($bar)) { | |
159 | return { bar => $bar }; | |
160 | } | |
161 | ||
162 | return undef; | |
163 | } | |
164 | ||
165 | sub parse_res_ignore_pages { | |
166 | my ($key, $text) = @_; | |
167 | ||
168 | my @a = split(/:/, $text); | |
169 | $a[1] = $a[0] if !defined($a[1]); | |
170 | ||
171 | my $lim = parse_res_bar_limit($a[1] , 4096); | |
172 | ||
173 | if (defined($lim)) { | |
174 | return { bar => 0, lim => $lim }; | |
175 | } | |
176 | ||
177 | return undef; | |
178 | } | |
179 | ||
180 | sub parse_boolean { | |
181 | my ($key, $text) = @_; | |
182 | ||
183 | return { value => 1 } if $text =~ m/^(yes|true|on|1)$/i; | |
184 | return { value => 0 } if $text =~ m/^(no|false|off|0)$/i; | |
185 | ||
186 | return undef; | |
187 | }; | |
188 | ||
189 | sub parse_integer { | |
190 | my ($key, $text) = @_; | |
191 | ||
192 | if ($text =~ m/^(\d+)$/) { | |
193 | return { value => int($1) }; | |
194 | } | |
195 | ||
196 | return undef; | |
197 | }; | |
198 | ||
199 | my $ovz_ressources = { | |
200 | numproc => \&parse_res_num_ignore, | |
201 | numtcpsock => \&parse_res_num_ignore, | |
202 | numothersock => \&parse_res_num_ignore, | |
203 | numfile => \&parse_res_num_ignore, | |
204 | numflock => \&parse_res_num_num, | |
205 | numpty => \&parse_res_num_ignore, | |
206 | numsiginfo => \&parse_res_num_ignore, | |
207 | numiptent => \&parse_res_num_ignore, | |
208 | ||
209 | vmguarpages => \&parse_res_pages_unlimited, | |
210 | oomguarpages => \&parse_res_pages_unlimited, | |
211 | lockedpages => \&parse_res_pages_ignore, | |
212 | privvmpages => \&parse_res_pages_pages, | |
213 | shmpages => \&parse_res_pages_ignore, | |
214 | physpages => \&parse_res_pages_pages, | |
215 | swappages => \&parse_res_ignore_pages, | |
216 | ||
217 | kmemsize => \&parse_res_bytes_bytes, | |
218 | tcpsndbuf => \&parse_res_bytes_bytes, | |
219 | tcprcvbuf => \&parse_res_bytes_bytes, | |
220 | othersockbuf => \&parse_res_bytes_bytes, | |
221 | dgramrcvbuf => \&parse_res_bytes_bytes, | |
222 | dcachesize => \&parse_res_bytes_bytes, | |
223 | ||
224 | disk_quota => \&parse_boolean, | |
225 | diskspace => \&parse_res_block_block, | |
226 | diskinodes => \&parse_res_num_num, | |
227 | quotatime => \&parse_integer, | |
228 | quotaugidlimit => \&parse_integer, | |
229 | ||
230 | cpuunits => \&parse_integer, | |
231 | cpulimit => \&parse_integer, | |
232 | cpus => \&parse_integer, | |
233 | cpumask => 'string', | |
234 | meminfo => 'string', | |
235 | iptables => 'string', | |
236 | ||
237 | ip_address => 'string', | |
238 | netif => 'string', | |
239 | hostname => 'string', | |
240 | nameserver => 'string', | |
241 | searchdomain => 'string', | |
242 | ||
243 | name => 'string', | |
244 | description => 'string', | |
245 | onboot => \&parse_boolean, | |
246 | initlog => \&parse_boolean, | |
247 | bootorder => \&parse_integer, | |
248 | ostemplate => 'string', | |
249 | ve_root => 'string', | |
250 | ve_private => 'string', | |
251 | disabled => \&parse_boolean, | |
252 | origin_sample => 'string', | |
253 | noatime => \&parse_boolean, | |
254 | capability => 'string', | |
255 | devnodes => 'string', | |
256 | devices => 'string', | |
257 | pci => 'string', | |
258 | features => 'string', | |
259 | ioprio => \&parse_integer, | |
260 | ||
261 | }; | |
262 | ||
263 | my $parse_ovz_config = sub { | |
264 | my ($raw) = @_; | |
265 | ||
266 | my $data = {}; | |
267 | ||
268 | return undef if !defined($raw); | |
269 | ||
270 | while ($raw && $raw =~ /^(.*?)(\n|$)/mg) { | |
271 | my $line = $1; | |
272 | ||
273 | next if $line =~ m/^\#/; | |
274 | next if $line =~ m/^\s*$/; | |
275 | ||
276 | if ($line =~ m/^\s*([A-Z][A-Z0-9_]*)\s*=\s*\"(.*)\"\s*$/i) { | |
277 | my $name = lc($1); | |
278 | my $text = $2; | |
279 | my $parser = $ovz_ressources->{$name}; | |
280 | if (!$parser || !ref($parser)) { | |
281 | $data->{$name}->{value} = $text; | |
282 | next; | |
283 | } else { | |
284 | if (my $res = &$parser($name, $text)) { | |
285 | $data->{$name} = $res; | |
286 | next; | |
287 | } | |
288 | } | |
289 | } | |
290 | die "unable to parse config line: $line\n"; | |
291 | } | |
292 | ||
293 | return $data; | |
294 | }; | |
295 | ||
296 | sub convert_ovz { | |
297 | my ($raw) = @_; | |
298 | ||
299 | my $conf = {}; | |
300 | ||
301 | my $ovz_conf = &$parse_ovz_config($raw); | |
302 | ||
8ed5ff9d | 303 | my $disksize = $ovz_conf->{'diskspace'}->{'bar'} * 1024; |
27916659 | 304 | |
f507c3a7 WL |
305 | my ($mem, $swap) = ovz_config_extract_mem_swap($ovz_conf, 0); |
306 | ||
d8a460e4 | 307 | $conf->{memory} = $mem / 1024 / 1024; |
f507c3a7 | 308 | |
d8a460e4 | 309 | $conf->{swap} = ($swap + $mem) / 1024 / 1024; |
f507c3a7 | 310 | |
27916659 | 311 | $conf->{cpuunits} = 1024; |
f507c3a7 | 312 | |
27916659 | 313 | $conf->{cpulimit} = $ovz_conf->{cpus}->{value} if $ovz_conf->{cpus}; |
f507c3a7 | 314 | |
27916659 | 315 | $conf->{hostname} = $ovz_conf->{hostname}->{value}; |
f507c3a7 | 316 | |
032fea95 | 317 | my $rootfsinfo = { size => $disksize, mp => '/' }; |
3650ed50 | 318 | |
032fea95 | 319 | return wantarray ? ($conf, $rootfsinfo) : $conf; |
f507c3a7 | 320 | } |