]> git.proxmox.com Git - pve-common.git/blobdiff - src/PVE/Tools.pm
half-revert: remove autostart property from bridge ports
[pve-common.git] / src / PVE / Tools.pm
index 577a8bc2a70c6e915e6f1c6ba6b74e64cc37d466..32f36ac2d6ac9a2fa9fa5cd9ce6bb21bd60ef422 100644 (file)
@@ -47,7 +47,7 @@ my $pvetaskdir = "$pvelogdir/tasks";
 mkdir $pvelogdir;
 mkdir $pvetaskdir;
 
-my $IPV4OCTET = "(?:25[0-5]|(?:[1-9]|1[0-9]|2[0-4])?[0-9])";
+my $IPV4OCTET = "(?:25[0-5]|(?:2[0-4]|1[0-9]|[1-9])?[0-9])";
 our $IPV4RE = "(?:(?:$IPV4OCTET\\.){3}$IPV4OCTET)";
 my $IPV6H16 = "(?:[0-9a-fA-F]{1,4})";
 my $IPV6LS32 = "(?:(?:$IPV4RE|$IPV6H16:$IPV6H16))";
@@ -63,6 +63,15 @@ our $IPV6RE = "(?:" .
     "(?:(?:(?:(?:$IPV6H16:){0,5}$IPV6H16)?::" .            ")$IPV6H16)|" .
     "(?:(?:(?:(?:$IPV6H16:){0,6}$IPV6H16)?::" .                    ")))";
 
+our $IPRE = "(?:$IPV4RE|$IPV6RE)";
+
+use constant (CLONE_NEWNS   => 0x00020000,
+              CLONE_NEWUTS  => 0x04000000,
+              CLONE_NEWIPC  => 0x08000000,
+              CLONE_NEWUSER => 0x10000000,
+              CLONE_NEWPID  => 0x20000000,
+              CLONE_NEWNET  => 0x40000000);
+
 sub run_with_timeout {
     my ($timeout, $code, @param) = @_;
 
@@ -241,13 +250,52 @@ sub safe_read_from {
     return $input;
 }
 
+# The $cmd parameter can be:
+#  -) a string
+#    This is generally executed by passing it to the shell with the -c option.
+#    However, it can be executed in one of two ways, depending on whether
+#    there's a pipe involved:
+#      *) with pipe: passed explicitly to bash -c, prefixed with:
+#          set -o pipefail &&
+#      *) without a pipe: passed to perl's open3 which uses 'sh -c'
+#      (Note that this may result in two different syntax requirements!)
+#      FIXME?
+#  -) an array of arguments (strings)
+#    Will be executed without interference from a shell. (Parameters are passed
+#    as is, no escape sequences of strings will be touched.)
+#  -) an array of arrays
+#    Each array represents a command, and each command's output is piped into
+#    the following command's standard input.
+#    For this a shell command string is created with pipe symbols between each
+#    command.
+#    Each command is a list of strings meant to end up in the final command
+#    unchanged. In order to achieve this, every argument is shell-quoted.
+#    Quoting can be disabled for a particular argument by turning it into a
+#    reference, this allows inserting arbitrary shell options.
+#    For instance: the $cmd [ [ 'echo', 'hello', \'>/dev/null' ] ] will not
+#    produce any output, while the $cmd [ [ 'echo', 'hello', '>/dev/null' ] ]
+#    will literally print: hello >/dev/null
 sub run_command {
     my ($cmd, %param) = @_;
 
     my $old_umask;
     my $cmdstr;
 
-    if (!ref($cmd)) {
+    if (my $ref = ref($cmd)) {
+       if (ref($cmd->[0])) {
+           $cmdstr = 'set -o pipefail && ';
+           my $pipe = '';
+           foreach my $command (@$cmd) {
+               # concatenate quoted parameters
+               # strings which are passed by reference are NOT shell quoted
+               $cmdstr .= $pipe .  join(' ', map { ref($_) ? $$_ : shellquote($_) } @$command);
+               $pipe = ' | ';
+           }
+           $cmd = [ '/bin/bash', '-c', "set -o pipefail && $cmdstr" ];
+       } else {
+           $cmdstr = cmd2string($cmd);
+       }
+    } else {
        $cmdstr = $cmd;
        if ($cmd =~ m/\|/) {
            # see 'man bash' for option pipefail
@@ -255,8 +303,6 @@ sub run_command {
        } else {
            $cmd = [ $cmd ];
        }
-    } else {
-       $cmdstr = cmd2string($cmd);
     }
 
     my $errmsg;
@@ -894,23 +940,10 @@ sub random_ether_addr {
 
     my $rand = Digest::SHA::sha1_hex($$, rand(), $seconds, $microseconds);
 
-    my $mac = '';
-    for (my $i = 0; $i < 6; $i++) {
-       my $ss = hex(substr($rand, $i*2, 2));
-       if (!$i) {
-           $ss &= 0xfe; # clear multicast
-           $ss |= 2; # set local id
-       }
-       $ss = sprintf("%02X", $ss);
+    # clear multicast, set local id
+    vec($rand, 0, 8) = (vec($rand, 0, 8) & 0xfe) | 2;
 
-       if (!$i) {
-           $mac .= "$ss";
-       } else {
-           $mac .= ":$ss";
-       }
-    }
-
-    return $mac;
+    return sprintf("%02X:%02X:%02X:%02X:%02X:%02X", unpack("C6", $rand));
 }
 
 sub shellquote {
@@ -1116,4 +1149,9 @@ sub parse_host_and_port {
     return; # nothing
 }
 
+sub unshare {
+    my ($flags) = @_;
+    syscall 272, $flags;
+}
+
 1;