尝试使用CPP程序将USB分区安装在Linux中



我想检测一个USB连接并安装其相应的分区。我尝试使用udev.i可以在/dev/bus/usb/001或/002中找到设备。但是从中我找不到它使用的分区。因此,如果添加了分区,则使用UDEV搜索块分区和安装。EG/DEV/SDA1。但这是一个临时解决方案。我想要的是使用UDEV或其他东西检测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 udevn");
        exit(1);
    }
    std::string mount_path_for_udev_listner = DEFAULT_MOUNT_PATH;
    printf("nn **********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 datan");
            /* Make the call to receive the device.
               select() ensured that this will not block. */
            dev = udev_monitor_receive_device(mon);
            if (dev) {
                printf("Got Devicen");
                printf("   Node: %sn", udev_device_get_devnode(dev));
                printf("   Subsystem: %sn", udev_device_get_subsystem(dev));
                printf("   Devtype: %sn", udev_device_get_devtype(dev));
                printf("   syspath:%sn",udev_device_get_syspath(dev));
                printf("   sysname:%sn",udev_device_get_sysname(dev));
                printf("   devpath:%sn",udev_device_get_devpath(dev));
                printf("   subsystem:%sn",udev_device_get_subsystem(dev));
                printf("   Action: %sn", 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 %snTrying 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 successn",ret);
                    }
                    else{
                            printf("n*****Error no %dn",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 %dn",ret);
                        printf("unmount successfulln");
                    }
                    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);
}

我得到了答案。我只需要为USB设备添加一个过滤器即可。如果我获得了一个设备作为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);

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

复制了此文件。

sudo lsusb 将告诉您USB设备Linux检测到了哪些。是USB存储设备安装还是被检测到的是单独的问题。 sudo lsusb -v 将提供冗长的输出,如果OS真正不识别设备,则可能比您想要的更多信息。

另外,您可以在插入USB设备之前和之后比较 /dev 中的设备列表。有很多方法可以做到。我可能只会使用:

ls -l /dev/* | wc -l

这将为您提供许多公认的设备。在插入设备之前和之后进行操作会告诉您是否在 /dev/中分配了该设备。

另一个选项是查看DMESG插入USB设备时发生的事情。 dmesg 可能会告诉您诸如设备如何失败之类的事情。

如果您无法安装的USB设备在LSUSB列表上,则可以尝试安装设备。在这一点上,很高兴知道文件系统类型。 sudo fdisk -l 将以ID的形式告诉您文件系统类型。您可能必须查找ID号。在线有很多参考文献。一旦知道设备列表,即 /dev/hda1 和文件系统类型,您可以尝试使用MAINT命令安装设备手动。

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

您可能必须确保将设备安装在存在的位置。如果操作系统识别文件系统,则如果文件系统不是本机文件系统类型,则MOUNT可能会工作。您可能必须指定安装的标志。

dmesg 中发布输出(并非全部,仅在插入USB设备时从周围出发)和 sudo lsusb

您可以找到Linux/unix:如果尝试确定设备类型时,设备文件很有帮助。

我正在写这篇文章,假设您所有未识别的设备都是块类型设备。有很多方法可以解决此类问题和许多可能的解决方案。需要更具体的信息来提供解决方案。

也有许多GUI应用程序可以做同样的事情。您可以尝试在"磁盘实用程序"中寻找插入的硬件。

检测附件USB设备的另一种方法是DBUS或HAL(但是HAL被认为是弃用的),请参阅此方法如何检测插入的USB和Linux热插图

最新更新