]> git.proxmox.com Git - pve-common.git/blobdiff - src/PVE/Tools.pm
added syncfs syscall and sync_mountpoint helper
[pve-common.git] / src / PVE / Tools.pm
index ae06c12b224b873dc7a27d5965078f54a8d9a851..6303d2047f5fc02898feb553321336c702710a2c 100644 (file)
@@ -75,6 +75,8 @@ use constant {CLONE_NEWNS   => 0x00020000,
               CLONE_NEWPID  => 0x20000000,
               CLONE_NEWNET  => 0x40000000};
 
+use constant O_PATH => 0x10000000;
+
 sub run_with_timeout {
     my ($timeout, $code, @param) = @_;
 
@@ -126,15 +128,16 @@ sub lock_file_full {
 
     my $lock_func = sub {
         if (!$lock_handles->{$$}->{$filename}) {
-            $lock_handles->{$$}->{$filename} = new IO::File (">>$filename") ||
-                die "can't open file - $!\n";
+           my $fh = new IO::File(">>$filename") ||
+               die "can't open file - $!\n";
+           $lock_handles->{$$}->{$filename} = { fh => $fh, refcount => 0};
         }
 
-        if (!flock ($lock_handles->{$$}->{$filename}, $mode|LOCK_NB)) {
-            print STDERR "trying to aquire lock...";
+        if (!flock($lock_handles->{$$}->{$filename}->{fh}, $mode|LOCK_NB)) {
+            print STDERR "trying to acquire lock...";
            my $success;
            while(1) {
-               $success = flock($lock_handles->{$$}->{$filename}, $mode);
+               $success = flock($lock_handles->{$$}->{$filename}->{fh}, $mode);
                # try again on EINTR (see bug #273)
                if ($success || ($! != EINTR)) {
                    last;
@@ -142,10 +145,11 @@ sub lock_file_full {
            }
             if (!$success) {
                 print STDERR " failed\n";
-                die "can't aquire lock - $!\n";
+                die "can't acquire lock '$filename' - $!\n";
             }
             print STDERR " OK\n";
         }
+       $lock_handles->{$$}->{$filename}->{refcount}++;
     };
 
     my $res;
@@ -159,9 +163,12 @@ sub lock_file_full {
        $err = $@;
     }
 
-    if (my $fh = $lock_handles->{$$}->{$filename}) {
-        $lock_handles->{$$}->{$filename} = undef;
-        close ($fh);
+    if (my $fh = $lock_handles->{$$}->{$filename}->{fh}) {
+       my $refcount = --$lock_handles->{$$}->{$filename}->{refcount};
+       if ($refcount <= 0) {
+           $lock_handles->{$$}->{$filename} = undef;
+           close ($fh);
+       }
     }
 
     if ($err) {
@@ -1185,4 +1192,22 @@ sub unshare($) {
     return 0 == syscall(272, $flags);
 }
 
+sub setns($$) {
+    my ($fileno, $nstype) = @_;
+    return 0 == syscall(308, $fileno, $nstype);
+}
+
+sub syncfs($) {
+    my ($fileno) = @_;
+    return 0 == syscall(306, $fileno);
+}
+
+sub sync_mountpoint {
+    my ($path) = @_;
+    sysopen my $fd, $path, O_PATH or die "failed to open $path: $!\n";
+    my $result = syncfs(fileno($fd));
+    close($fd);
+    return $result;
+}
+
 1;