LINUX.ORG.RU

Как узнать, что примонтирован новый диск\флэха

 ,


0

1

Привет посоны!

В общем, хочу сделать демон который бы следил за монтированием флэшек и копировал бы всё содержимое в определённую директорию на NAS. Вообще, было бы идеально если бы только при подключении в определённый USB, например, на лицевой панели начиналось бы копирование. Пока ни чего умнее чем по таймеру проверять новых файлов в /dev/ и чтения fstab не придумал. Есть ли какие системные механизмы, чтобы сделать красиво? Например, может есть возможность получать событие о подключении нового устройства через какой-нибудь callback? Заранее спасибо

★★★★

Последнее исправление: AntonyRF (всего исправлений: 1)

udevadm monitor
udisksctl monitor

Можно сразу правила к udev писать, можно написать программку, которая слушает события и реагирует. В зависимости от того, насколько глубоко хочешь закопать и закопаться.

i-rinat ★★★★★
()

Пока ни чего умнее чем по таймеру проверять новых файлов в /dev/

Болезный? В /dev/sd* устройства появляются, т.е. флешки с убитой ФС там тоже отображаются, как ты с них файлы копировать собираешься? Нет, конечно через dd ты можешь их образы писать, но они жирные (пустота и мусор оставшийся от старых файлов, которые удалили, тоже копируется), потом их сжимать надо, непрактично короче.

peregrine ★★★★★
()
Ответ на: комментарий от AntonyRF

Правильнее всего написать на чем ты демона делать собрался? Одно дело, если под демоном ты имеешь ввиду скрипт на bash/python в кроне и совсем другое дело, если ты пишешь демона на C/C++.

peregrine ★★★★★
()
Ответ на: комментарий от i-rinat

udisksctl monitor

Показывает подключение устройств и их монтирование, но если через libudev я отлавливаю изменения свойств, то событие о монтировании не приходит =\ udisksctl из какого пакета? Хотелось бы глянуть исходник. У меня получилось так:

extern crate libudev;
extern crate libc;

use std::io;
use std::ptr;
use std::thread;
use std::time::Duration;

use std::os::unix::io::AsRawFd;

use libc::{c_void, c_int, c_short, c_ulong};

#[repr(C)]
struct pollfd {
    fd: c_int,
    events: c_short,
    revents: c_short,
}

#[repr(C)]
struct sigset_t {
    __private: c_void,
}

#[allow(non_camel_case_types)]
type nfds_t = c_ulong;

const POLLIN: c_short = 0x0001;

extern "C" {
    fn ppoll(fds: *mut pollfd,
             nfds: nfds_t,
             timeout_ts: *mut libc::timespec,
             sigmask: *const sigset_t)
             -> c_int;
}

fn main() {
    let context = libudev::Context::new().unwrap();
    monitor(&context).unwrap();
}

fn monitor(context: &libudev::Context) -> io::Result<()> {
    let mut monitor = try!(libudev::Monitor::new(&context));

  //  try!(monitor.match_subsystem_devtype("usb", "usb_device"));
    let mut socket = try!(monitor.listen());

    let mut fds = vec![pollfd {
                           fd: socket.as_raw_fd(),
                           events: POLLIN,
                           revents: 0,
                       }];

    loop {
        let result = unsafe {
            ppoll((&mut fds[..]).as_mut_ptr(),
                  fds.len() as nfds_t,
                  ptr::null_mut(),
                  ptr::null())
        };

        if result < 0 {
            return Err(io::Error::last_os_error());
        }

        let event = match socket.receive_event() {
            Some(evt) => evt,
            None => {
                thread::sleep(Duration::from_millis(10));
                continue;
            }
        };

        println!("sequence  = {}", event.sequence_number());
        println!("type      = {}", event.event_type());
        println!("syspath   = {}", event.syspath().to_str().unwrap_or("---"));
        println!("devpath   = {}", event.devpath().to_str().unwrap_or("---"));
        println!("subsystem = {}",
                 event.subsystem().to_str().unwrap_or("---"));
        println!("sysname   = {}", event.sysname().to_str().unwrap_or("---"));

        match event.devtype() {
            Some(expr) => println!("devtype   = {}", expr.to_str().unwrap_or("---")),
            None => {}
        }

        for property in event.properties() {
            println!("{:?} = {:?}", property.name(), property.value());
        }

        for attribute in event.attributes() {
            println!("{:?} = {:?}", attribute.name(), attribute.value());
        }
    }
}

AntonyRF ★★★★
() автор топика

Таки проблема не решена =\

AntonyRF ★★★★
() автор топика

Можно подняться одним уровнем абстракции выше и заюзать DBus: у сервиса UDisks ловить событие «DeviceAdded» и брать пропертю DeviceMountPaths.

sh0ckfile
()
Вы не можете добавлять комментарии в эту тему. Тема перемещена в архив.