Linux通过libudev获取挂载路径、监控U盘热拔插事件、U盘文件系统类型

文章目录

  • 获取挂载路径
  • 监控U盘热拔插事件
    • libusb
  • 文件系统类型
  • 通过挂载点获取挂载路径
  • 添libudev加库

获取挂载路径

#include 
#include 
#include 

int main() {
    struct udev *udev;
    struct udev_enumerate *enumerate;
    struct udev_list_entry *devices, *entry;

    // 创建udev上下文和设备枚举器
    udev = udev_new();
    if (!udev) {
        printf("Failed to create udev context\n");
        return 1;
    }

    enumerate = udev_enumerate_new(udev);
    if (!enumerate) {
        printf("Failed to create udev enumerate\n");
        udev_unref(udev);
        return 1;
    }

    // 添加匹配过滤器以选择块设备(U盘)
    udev_enumerate_add_match_subsystem(enumerate, "block");
    udev_enumerate_scan_devices(enumerate);
    devices = udev_enumerate_get_list_entry(enumerate);

    // 遍历设备列表并获取设备信息
    udev_list_entry_foreach(entry, devices) {
        const char *sys_path = udev_list_entry_get_name(entry);
        struct udev_device *dev = udev_device_new_from_syspath(udev, sys_path);
        const char *devnode = udev_device_get_devnode(dev);

        printf("Device node path: %s\n", udev_device_get_devnode(dev));
#if 0
        // 检查设备是否是U盘,可以根据需求添加其他判断条件
        if (udev_device_get_devtype(dev) && strcmp(udev_device_get_devtype(dev), "disk") == 0) {
            printf("U盘挂载路径:%s\n", devnode);
        }
#endif
        udev_device_unref(dev);
    }
    
  

    // 清理资源
    udev_enumerate_unref(enumerate);
    udev_unref(udev);

    return 0;
}

编译指令

gcc your_code.c -o your_executable -ludev

Linux通过libudev获取挂载路径、监控U盘热拔插事件、U盘文件系统类型_第1张图片
Linux通过libudev获取挂载路径、监控U盘热拔插事件、U盘文件系统类型_第2张图片

监控U盘热拔插事件

#include 
#include 
#include 

int main() {
    struct udev *udev;
    struct udev_enumerate *enumerate;
    struct udev_list_entry *devices, *entry;

    // 创建udev上下文和设备枚举器
    udev = udev_new();
    if (!udev) {
        printf("Failed to create udev context\n");
        return 1;
    }

struct udev_monitor *mon = udev_monitor_new_from_netlink(udev, "udev");
int fd = udev_monitor_get_fd(mon);

udev_monitor_filter_add_match_subsystem_devtype(mon, "block", NULL);
udev_monitor_enable_receiving(mon);

while (1) {
    fd_set fds;
    FD_ZERO(&fds);
    FD_SET(fd, &fds);

    // 使用select函数等待设备事件
    if (select(fd+1, &fds, NULL, NULL, NULL) > 0) {
        if (FD_ISSET(fd, &fds)) {
            struct udev_device *dev = udev_monitor_receive_device(mon);
            if (dev) {
                const char *action = udev_device_get_action(dev);

                // 判断事件类型,处理U盘插入和移除事件
                if (strcmp(action, "add") == 0) {
                    printf("U盘插入\n");
                } else if (strcmp(action, "remove") == 0) {
                    printf("U盘移除\n");
                }

                udev_device_unref(dev);
            }
        }
    }
}

    // 清理资源
    udev_enumerate_unref(enumerate);
    udev_unref(udev);

    return 0;
}

Linux通过libudev获取挂载路径、监控U盘热拔插事件、U盘文件系统类型_第3张图片

libusb

#include 
#include "/home/hty/Project/oneway_qt5/ui/oneway/onewaysendui_socket.new/libusb.h"
#include 

#define VENDOR_ID        LIBUSB_HOTPLUG_MATCH_ANY  // U盘的厂商ID
#define PRODUCT_ID       LIBUSB_HOTPLUG_MATCH_ANY  // U盘的产品ID

#if 1
static int LIBUSB_CALL  usb_callback(libusb_context *ctx, libusb_device *dev, libusb_hotplug_event event, void *user_data) 
{
   printf("\n\n12345235235\n\n");
   if (event == LIBUSB_HOTPLUG_EVENT_DEVICE_ARRIVED) {
            printf("U盘已插入\n");
            // 在这里执行U盘插入时的操作
        } else if (event == LIBUSB_HOTPLUG_EVENT_DEVICE_LEFT) {
            printf("U盘已拔出\n");
            // 在这里执行U盘拔出时的操作
        }
}


static int LIBUSB_CALL  usb_callback_in(libusb_context *ctx, libusb_device *dev, libusb_hotplug_event event, void *user_data)
{
   printf("\n\n12___________\n\n");

            printf("U盘已插入\n");
            // 在这里执行U盘插入时的操作
	fflush(stdout);
}

static int LIBUSB_CALL  usb_callback_out(libusb_context *ctx, libusb_device *dev, libusb_hotplug_event event, void *user_data)
{
   printf("\n\n12----------\n\n");

            printf("U盘已拔出\n");
            // 在这里执行U盘拔出
	fflush(stdout);
}

libusb_hotplug_callback_fn fn = usb_callback;
int main(void) 
{
    libusb_context *ctx = NULL;
    libusb_context *context = NULL;
    int rc = 0;

    rc = libusb_init(&ctx);

    assert(rc == 0);

    rc = libusb_has_capability( LIBUSB_CAP_HAS_HOTPLUG);

    if(rc!=0)
    {
     printf("capability\n");
    }
    //libusb_hotplug_callback_handle handle;
    //rc=libusb_hotplug_register_callback(ctx,  LIBUSB_HOTPLUG_EVENT_DEVICE_ARRIVED |LIBUSB_HOTPLUG_EVENT_DEVICE_LEFT, LIBUSB_HOTPLUG_ENUMERATE,VENDOR_ID, PRODUCT_ID, LIBUSB_HOTPLUG_MATCH_ANY, (libusb_hotplug_callback_fn)usb_callback, NULL, &handle);
    //rc=libusb_hotplug_register_callback(ctx,  LIBUSB_HOTPLUG_EVENT_DEVICE_ARRIVED |LIBUSB_HOTPLUG_EVENT_DEVICE_LEFT, LIBUSB_HOTPLUG_ENUMERATE,VENDOR_ID, PRODUCT_ID, 0, (libusb_hotplug_callback_fn)usb_callback, NULL, &handle);
      
      libusb_hotplug_callback_handle handle_in;
      libusb_hotplug_callback_handle handle_out;
      rc=libusb_hotplug_register_callback(ctx,  LIBUSB_HOTPLUG_EVENT_DEVICE_ARRIVED, LIBUSB_HOTPLUG_NO_FLAGS,LIBUSB_HOTPLUG_MATCH_ANY,LIBUSB_HOTPLUG_MATCH_ANY, LIBUSB_HOTPLUG_MATCH_ANY, (libusb_hotplug_callback_fn)usb_callback_in, NULL, &handle_in);
      rc=libusb_hotplug_register_callback(ctx,  LIBUSB_HOTPLUG_EVENT_DEVICE_LEFT, LIBUSB_HOTPLUG_NO_FLAGS, LIBUSB_HOTPLUG_MATCH_ANY, LIBUSB_HOTPLUG_MATCH_ANY, LIBUSB_HOTPLUG_MATCH_ANY, (libusb_hotplug_callback_fn)usb_callback_out, NULL, &handle_out);
//    libusb_exit(context);
    //    rc = libusb_hotplug_register_callback(handle);
    if (rc != 0) {
        fprintf(stderr, "Failed to register hotplug callback\n");
        libusb_exit(ctx);
        return rc;
    }
    printf("正在监听 U盘插拔事件...\n");

    while (1) 
    {
	rc =  libusb_handle_events(ctx);
	if (rc != LIBUSB_SUCCESS) 
	{
            fprintf(stderr, "libusb_handle_events() 出错:%s\n", libusb_strerror(rc));
            break;
        }
	printf("新事件产生了...\n");
     }
     //libusb_hotplug_deregister_callback(NULL,handle);
     libusb_hotplug_deregister_callback(NULL,handle_in);
     libusb_hotplug_deregister_callback(NULL,handle_out);
    return 0;
}

#else

static int LIBUSB_CALL hotplug_callback(libusb_context *ctx, libusb_device *dev, libusb_hotplug_event event, void *user_data)
{
        printf("device insert  \n");
}
int main(int argc, char **argv)
{
        libusb_hotplug_callback_handle hp;
        libusb_init (NULL);
        libusb_hotplug_register_callback (NULL, LIBUSB_HOTPLUG_EVENT_DEVICE_ARRIVED, LIBUSB_HOTPLUG_ENUMERATE, LIBUSB_HOTPLUG_MATCH_ANY,
                LIBUSB_HOTPLUG_MATCH_ANY, 0, hotplug_callback, NULL, &hp);
        while(1)
        {
                libusb_handle_events(NULL);
        }
        libusb_hotplug_deregister_callback(NULL,hp);
}

#endif

文件系统类型

#include 
#include 
#include 
#include 

int main() {
    struct udev *udev = udev_new();
    if (!udev) {
        printf("Failed to initialize udev\n");
        return 1;
    }

    struct udev_enumerate *enumerate = udev_enumerate_new(udev);
    udev_enumerate_add_match_subsystem(enumerate, "block");
    udev_enumerate_scan_devices(enumerate);

    struct udev_list_entry *devices = udev_enumerate_get_list_entry(enumerate);
    struct udev_list_entry *entry;
    udev_list_entry_foreach(entry, devices) {
        const char *path = udev_list_entry_get_name(entry);
        struct udev_device *dev = udev_device_new_from_syspath(udev, path);
        const char *devnode = udev_device_get_devnode(dev);
/*********************************************************************************/
        const char *fs_type = udev_device_get_property_value(dev, "ID_FS_TYPE");

        // Output the device node and file system type
        if (devnode && fs_type) {
            printf("Device: %s\n", devnode);
            printf("File System Type: %s\n", fs_type);
        }
/**********************************************************************************/
        udev_device_unref(dev);
    }

    udev_enumerate_unref(enumerate);
    udev_unref(udev);

    return 0;
}

Linux通过libudev获取挂载路径、监控U盘热拔插事件、U盘文件系统类型_第4张图片Linux通过libudev获取挂载路径、监控U盘热拔插事件、U盘文件系统类型_第5张图片

这段代码使用 libudev 库,通过遍历 U 盘设备列表获取设备节点和文件系统类型。首先,使用 udev_new()函数初始化 udev 上下文,然后创建一个 udev_enumerate 对象,并设置匹配子系统为 “block”。接下来,使用 udev_enumerate_scan_devices() 函数扫描设备。然后,获取设备列表,并使用 udev_list_entry_foreach() 函数遍历列表。在遍历过程中,通过调用 udev_device_new_from_syspath() 函数根据设备的 syspath 创建一个 udev_device 对象。然后,使用 udev_device_get_devnode() 函数获取设备节点和 udev_device_get_property_value() 函数获取文件系统类型。最后,输出设备节点和文件系统类型。

通过挂载点获取挂载路径

#include 
#include 
#include 

#define MAX_PATH 256

char* get_usb_device_path(const char* mount_point) {
    FILE* fp;
    char* line = NULL;
    size_t len = 0;
    ssize_t read;
    char* device_path = NULL;

    // 打开 /proc/mounts 文件
    fp = fopen("/proc/mounts", "r");
    if (fp == NULL) {
        printf("Failed to open /proc/mounts\n");
        return NULL;
    }

    // 逐行读取 /proc/mounts 文件
    while ((read = getline(&line, &len, fp)) != -1) {
        char* token;
        char* saveptr = NULL;
        char* mount;
        char* device;

        // 解析挂载点和设备路径
        token = strtok_r(line, " ", &saveptr);
        mount = token;
        
        token = strtok_r(NULL, " ", &saveptr);
        device = token;

        // 如果挂载点匹配,保存设备路径
        if (strcmp(mount, mount_point) == 0) {
            device_path = strdup(device); // 保存设备路径的副本
            break;
        }
    }

    // 关闭文件和释放资源
    fclose(fp);
    if (line) {
        free(line);
    }

    return device_path;
}

int main() {
    const char* mount_point = "/dev/sdb1"; // 替换为你的挂载点

    char* device_path = get_usb_device_path(mount_point);

    if (device_path) {
        printf("USB Device Path: %s\n", device_path);
        free(device_path);
    } else {
        printf("USB device not found\n");
    }

    return 0;
}

在这里插入图片描述

添libudev加库

sudo apt-get install libudev-dev

你可能感兴趣的:(linux,运维,服务器)