2016-11-25 66 views
-1

我想检测USB连接并挂载其相应的分区。 我试过使用udev.I能够在/ dev/bus/usb/001或/ 002中找到设备。但是从此我无法找到它使用的分区。因此,使用udev我搜索了块分区并挂载,如果添加了一个分区.eg/dev/sda1.But这是一个临时解决方案。 我想要的是使用udev或其他东西来检测USB连接,并找到它正在装载的分区。尝试在Linux中使用cpp程序挂载USB分区

我的代码:

#include <libudev.h> 
#include <stdio.h> 
#include "dmutil.h" 
#include <pthread.h> 

#include <unistd.h> 

/* 
Thread which detects devices. 
*/ 
void * udev_listener(void * i) 
{ 

    struct udev *udev; 
    udev = udev_new(); 
    if (!udev) { 
     printf("Can't create udev\n"); 
     exit(1); 
    } 

    std::string mount_path_for_udev_listner = DEFAULT_MOUNT_PATH; 
    printf("\n\n **********\nUdev_listner is asked to mount usb to %s ....",mount_path_for_udev_listner.c_str()); 

    struct udev_device *dev; 
    struct udev_monitor *mon; 
    mon = udev_monitor_new_from_netlink(udev, "udev"); 
    assert(mon != NULL); 
    /* int udev_monitor_filter_add_match_subsystem_devtype(struct udev_monitor *udev_monitor,const char *subsystem, const char *devtype); 
     filters to select messages that get delivered to a listener. 
     On Success it returns an integer greater than, or equal to, 0. On failure, a negative error code is returned. 
    */ 
    assert(udev_monitor_filter_add_match_subsystem_devtype(mon, "block", NULL) >=0); 
    udev_monitor_enable_receiving(mon); 
    /* Get the file descriptor (fd) for the monitor. 
     This fd will get passed to select() */ 

    int fd = udev_monitor_get_fd(mon); 
    /* Begin polling for udev events. Events occur when devices attached to the system are added, removed, or change state. 
     udev_monitor_receive_device() will return a device object representing the device which changed and what type of change occured. 

     The select() system call is used to ensure that the call to udev_monitor_receive_device() will not block. 

     This section will run continuously, calling usleep() at the end of each pass. This is to use udev_monitor in a non-blocking way. */ 
    while (1) 
    { 
     /* 
      int select(int nfds, fd_set *readfds, fd_set *writefds,fd_set *exceptfds, struct timeval *timeout); 

      select() allows a program to monitor multiple file descriptors, waiting until one or more of the file descriptors 
      become "ready" for some class of I/O operation. 

      Set up the call to select(). In this case, select() will only operate on a single file descriptor, the one associated 
      with our udev_monitor. Note that the timeval object is set to 0, which will cause select() to not block. */ 
     fd_set fds; 
     struct timeval tv; 
     int ret; 

     FD_ZERO(&fds); //clear fds 
     FD_SET(fd, &fds);// Add fd to fds 
     /* 
      The timeout argument specifies the interval that select() should block waiting for a file descriptor to become ready. 
      This interval will be rounded up to the system clock granularity, and kernel scheduling delays mean that the 
      blocking interval may overrun by a small amount. If both fields of the timeval structure are zero, then select() 
      returns immediately. (This is useful for polling.)If timeout is NULL (no timeout), select() can block indefinitely. 
     */ 
     tv.tv_sec = 0; 
     tv.tv_usec = 0; 
     /* 
      nfds specifies how big the list of file descriptors is because the total number can be vast. 
      So, if you want to monitor file descriptors 24-31, you'd set nfds to 32. 
      man - nfds is the highest-numbered file descriptor in any of the three sets, plus 1. 
     */ 
     ret = select(fd+1, &fds, NULL, NULL, &tv); 

     /* Check if our file descriptor has received data. */ 
     if (ret > 0 && FD_ISSET(fd, &fds)) { 
      printf("\nselect() says there should be data\n"); 

      /* Make the call to receive the device. 
       select() ensured that this will not block. */ 
      dev = udev_monitor_receive_device(mon); 
      if (dev) { 
       printf("Got Device\n"); 
       printf(" Node: %s\n", udev_device_get_devnode(dev)); 
       printf(" Subsystem: %s\n", udev_device_get_subsystem(dev)); 
       printf(" Devtype: %s\n", udev_device_get_devtype(dev)); 
       printf(" syspath:%s\n",udev_device_get_syspath(dev)); 
       printf(" sysname:%s\n",udev_device_get_sysname(dev)); 
       printf(" devpath:%s\n",udev_device_get_devpath(dev)); 
       printf(" subsystem:%s\n",udev_device_get_subsystem(dev)); 
       printf(" Action: %s\n", udev_device_get_action(dev)); 
       std::string devtype=udev_device_get_devtype(dev); 
       std::string action=udev_device_get_action(dev); 
       std::string devnode=udev_device_get_devnode(dev); 
       if(devtype.compare("partition")==0 && action.compare("add") == 0) 
       { 
        printf("A new partition detected at %s\nTrying to mount to %s",devnode.c_str(),mount_path_for_udev_listner.c_str()); 
        int ret = mount_disk(devnode,mount_path_for_udev_listner); 
        if(ret == 0) 
        { 
         printf("\nSystem returns %d, Mounting success\n",ret); 
        } 
        else{ 
          printf("\n*****Error no %d\n",errno); 
        } 
       } 
       if(devtype.compare("partition")==0 && action.compare("remove") == 0) 
       { 
        printf("Partition removal detected, trying to unmount...\n"); 
        int ret=umount_disk(); 
        if(ret==0){ 
         printf("\nSystem returns %d\n",ret); 
         printf("unmount successfull\n"); 
        } 
        else{ 
         printf("\nThe partition unmounting FAILED:\n "); 
        } 
       } 
       udev_device_unref(dev); 
      } 
      else { 
       printf("No Device from receive_device(). An error occured.\n"); 
      }     
     } 
     usleep(250*1000); 
     printf("."); 
     fflush(stdout); 
    } 
    pthread_exit(NULL); 
} 

回答

0

我得到了答案。我只需要为usb-device增加一个过滤器。如果我以usb和block的形式获得设备,我可以使用该分区并挂载它。

assert(udev_monitor_filter_add_match_subsystem_devtype(mon, "block", NULL)>=0); 
assert(udev_monitor_filter_add_match_subsystem_devtype(mon, "usb","usb-device") >=0); 
-1

我复制这从https://askubuntu.com/questions/285539/detect-and-mount-devices

sudo lsusb会告诉你Linux的检测什么USB设备。 USB存储设备是安装还是被检测到,都是单独的问题。sudo lsusb -v将给出详细输出,如果操作系统确实无法识别设备,可能会提供比您想要的更多的信息。

或者,你可以在/dev之前,并在插入USB设备比较后设备的列表。有很多方法可以做到这一点;我可能只是使用:

ls -l /dev/* | wc -l

这会给你一些公认的设备。在插入设备之前和之后进行操作会告诉您操作系统是否分配了设备/dev/

另一种选择是在插入USB设备时查看dmesg中发生的情况。dmesg可能会告诉你一些设备失败的情况。

如果您在安装时遇到问题的USB设备位于lsusb列表中,那么您可以尝试安装设备。此时,最好知道文件系统类型。sudo fdisk -l会以ID的形式告诉你文件系统的类型。您可能需要查看身份证号码。网上有很多参考资料。一旦知道了设备列表,即/dev/hda1和文件系统类型,您可以尝试使用mount命令装入设备manualy。

sudo mount /dev/hda1 /home/user/Desktop/whereEver

您可能必须确保的位置要安装在设备上存在。如果操作系统识别文件系统,那么如果文件系统不是本机文件系统类型,挂载可能会正常工作;您可能必须指定安装标志。

回来后从dmesg(不是全部,只是从周围当USB设备插入),和sudo lsusb你的输出。

您可能会发现的Linux/UNIX:如果试图确定设备类型设备文件很有帮助。

我写这个假设你所有的无法识别的设备都是块类型的设备。有许多方法可以解决这类问题和许多可能的解决方案。需要更具体的信息来提供解决方案。

也有很多GUI应用程序可以做同样的事情。您可以尝试在“磁盘工具”中查找插入的硬件。

的另一种方法来检测连接的USB设备是的DBus或HAL(但哈尔被认为是不建议使用),请参阅本How to detect inserted USBlinux hotplugging

相关问题