/src/tools: Cleanup tempfiles in folder

Signed-off-by: Christian Ebner <c.ebner@proxmox.com>
This commit is contained in:
Christian Ebner 2019-04-10 13:29:10 +02:00 committed by Dietmar Maurer
parent a665dea128
commit 1cd33633aa
2 changed files with 0 additions and 232 deletions

View File

@ -1,185 +0,0 @@
use failure::*;
use std::thread;
use std::sync::{Arc, Mutex};
use std::os::unix::io::AsRawFd;
//use proxmox_backup::tools;
// fixme: use F_OFD_ locks when implemented with nix::fcntl
// flock lock conversion is not atomic, so we need to use fcntl
struct ProcessLocker {
file: std::fs::File,
exclusive: bool,
writers: usize,
}
struct SharedLock {
locker: Arc<Mutex<ProcessLocker>>,
}
impl Drop for SharedLock {
fn drop(&mut self) {
let tid = std::thread::current().id();
let pid = std::process::id();
println!("{:?}:{:?}: Drop Writerlock", pid, tid);
let mut data = self.locker.lock().unwrap();
if data.writers == 0 { panic!("unexpected ProcessLocker state"); }
if data.writers == 1 && !data.exclusive {
let op = libc::flock {
l_type: libc::F_UNLCK as i16,
l_whence: libc::SEEK_SET as i16,
l_start: 0,
l_len: 0,
l_pid: 0,
};
if let Err(err) = nix::fcntl::fcntl(data.file.as_raw_fd(), nix::fcntl::FcntlArg::F_SETLKW(&op)) {
panic!("unable to drop writer lock - {}", err);
}
data.writers = 0;
}
}
}
struct ExclusiveLock {
locker: Arc<Mutex<ProcessLocker>>,
}
impl Drop for ExclusiveLock {
fn drop(&mut self) {
let tid = std::thread::current().id();
let pid = std::process::id();
println!("{:?}:{:?}: Drop Exclusive lock", pid, tid);
let mut data = self.locker.lock().unwrap();
if !data.exclusive { panic!("unexpected ProcessLocker state"); }
let ltype = if data.writers != 0 { libc::F_RDLCK } else { libc::F_UNLCK };
let op = libc::flock {
l_type: ltype as i16,
l_whence: libc::SEEK_SET as i16,
l_start: 0,
l_len: 0,
l_pid: 0,
};
if let Err(err) = nix::fcntl::fcntl(data.file.as_raw_fd(), nix::fcntl::FcntlArg::F_SETLKW(&op)) {
panic!("unable to drop exclusive lock - {}", err);
}
data.exclusive = false;
}
}
impl ProcessLocker {
pub fn new(lockfile: &str) -> Result<Arc<Mutex<Self>>, Error> {
let file = std::fs::OpenOptions::new()
.create(true)
.read(true)
.write(true)
.open(lockfile)?;
Ok(Arc::new(Mutex::new(Self {
file: file,
exclusive: false,
writers: 0,
})))
}
pub fn try_shared_lock(locker: Arc<Mutex<Self>>) -> Result<SharedLock, Error> {
let mut data = locker.lock().unwrap();
if data.writers == 0 && !data.exclusive {
let op = libc::flock {
l_type: libc::F_RDLCK as i16,
l_whence: libc::SEEK_SET as i16,
l_start: 0,
l_len: 0,
l_pid: 0,
};
if let Err(err) = nix::fcntl::fcntl(data.file.as_raw_fd(), nix::fcntl::FcntlArg::F_SETLK(&op)) {
bail!("unable to get shared lock - {}", err);
}
}
data.writers += 1;
Ok(SharedLock { locker: locker.clone() })
}
pub fn try_exclusive_lock(locker: Arc<Mutex<Self>>) -> Result<ExclusiveLock, Error> {
let mut data = locker.lock().unwrap();
if data.exclusive {
bail!("already locked exclusively");
}
let op = libc::flock {
l_type: libc::F_WRLCK as i16,
l_whence: libc::SEEK_SET as i16,
l_start: 0,
l_len: 0,
l_pid: 0,
};
if let Err(err) = nix::fcntl::fcntl(data.file.as_raw_fd(), nix::fcntl::FcntlArg::F_SETLK(&op)) {
bail!("unable to get exclusive lock - {}", err);
}
data.exclusive = true;
return Ok(ExclusiveLock { locker: locker.clone() });
}
}
fn run_test() -> Result<(), Error>
{
let tid = std::thread::current().id();
let pid = std::process::id();
let locker = ProcessLocker::new("test.flock")?;
println!("{:?}:{:?}: try to get shared lock", pid, tid);
let l1 = ProcessLocker::try_shared_lock(locker.clone())?;
println!("{:?}:{:?}: got shared lock", pid, tid);
println!("{:?}:{:?}: try to get exclusive lock", pid, tid);
let l2 = ProcessLocker::try_exclusive_lock(locker.clone())?;
println!("{:?}:{:?}: got exclusive lock", pid, tid);
println!("{:?}:{:?}: try to get shared lock", pid, tid);
let l3 = ProcessLocker::try_shared_lock(locker.clone())?;
println!("{:?}:{:?}: got shared lock", pid, tid);
Ok(())
}
fn main() -> Result<(), Error>
{
if let Err(err) = run_test() {
println!("ERROR: {}", err);
}
let tid = std::thread::current().id();
let pid = std::process::id();
println!("{:?}:{:?}: Exit", pid, tid);
Ok(())
}

View File

@ -1,47 +0,0 @@
use failure::*;
use crate::tools;
use lazy_static::lazy_static;
use regex::Regex;
pub struct ProcFsPidStat {
pub status: u8,
pub utime: u64,
pub stime: u64,
pub starttime: u64,
pub vsize: u64,
pub rss: i64,
}
pub fn read_proc_pid_stat(pid: nix::unistd::Pid) -> Result<ProcFsPidStat, Error> {
let statstr = tools::file_read_firstline(format!("/proc/{}/stat", pid))?;
lazy_static! {
static ref REGEX: Regex = Regex::new(r"^(?P<pid>\d+) \(?:.*\) (?P<status>\S) -?\d+ -?\d+ -?\d+ -?\d+ -?\d+ \d+ \d+ \d+ \d+ \d+ (?P<utime>\d+) (?P<stime>\d+) -?\d+ -?\d+ -?\d+ -?\d+ -?\d+ 0 (?P<starttime>\d+) (?P<vsize>\d+) (?P<rss>-?\d+) \d+ \d+ \d+ \d+ \d+ \d+ \d+ \d+ \d+ \d+ \d+ \d+ \d+ -?\d+ -?\d+ \d+ \d+ \d+").unwrap();
}
if let Some(cap) = REGEX.captures(&statstr) {
if pid != nix::unistd::Pid::from_raw(cap["pid"].parse::<i32>().unwrap()) {
bail!("unable to read pid stat for process '{}' - got wrong pid", pid);
}
return Ok(ProcFsPidStat {
status: cap["status"].parse::<u8>().unwrap(),
utime: cap["utime"].parse::<u64>().unwrap(),
stime: cap["stime"].parse::<u64>().unwrap(),
starttime: cap["starttime"].parse::<u64>().unwrap(),
vsize: cap["vsize"].parse::<u64>().unwrap(),
rss: cap["rss"].parse::<i64>().unwrap() * 4096,
});
}
bail!("unable to read pid stat for process '{}'", pid);
}
pub fn read_proc_starttime(pid: nix::unistd::Pid) -> Result<u64, Error> {
let info = read_proc_pid_stat(pid)?;
Ok(info.starttime)
}