]> git.proxmox.com Git - pve-container.git/blob - src/PVE/VZDump/ConvertOVZ.pm
cleanup mp size parameter (add units, same code as QemuServer)
[pve-container.git] / src / PVE / VZDump / ConvertOVZ.pm
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
303 my $disksize = $ovz_conf->{'diskspace'}->{'bar'} * 1024;
304
305 my ($mem, $swap) = ovz_config_extract_mem_swap($ovz_conf, 0);
306
307 $conf->{memory} = $mem / 1024 / 1024;
308
309 $conf->{swap} = ($swap + $mem) / 1024 / 1024;
310
311 $conf->{cpuunits} = 1024;
312
313 $conf->{cpulimit} = $ovz_conf->{cpus}->{value} if $ovz_conf->{cpus};
314
315 $conf->{hostname} = $ovz_conf->{hostname}->{value};
316
317 return wantarray ? ($conf, $disksize) : $conf;
318 }