📌  相关文章
📜  已达到 inotify 监视总数的用户限制;增加 fs.inotify.max_user_watches sysctl\n' - Shell-Bash (1)

📅  最后修改于: 2023-12-03 14:53:59.550000             🧑  作者: Mango

已达到 inotify 监视总数的用户限制;增加 fs.inotify.max_user_watches sysctl

介绍

如果您是一个 Linux 程序员,并且曾经遇到过 "已达到 inotify 监视总数的用户限制" 的错误,那么您需要了解如何增加在任何给定时间内可以使用的 inotify 实例的总数。在这篇文章中,我们将讨论如何通过增加 fs.inotify.max_user_watches sysctl 参数来解决这个问题。

什么是 inotify?

首先,让我们看看什么是 inotify。 inotify 是一种文件系统通知机制,它能够让你的程序监听文件和目录的特定事件(例如创建、删除、修改、移动等),并在发生这些事件时做出相应的反应。

如何使用 inotify?

要使用 inotify,您需要使用 inotify_init() 函数来初始化一个 inotify 实例。然后,您可以使用 inotify_add_watch() 函数将特定的文件或目录添加到 inotify 实例的监听列表中,并监听特定事件。最后,您可以使用 read() 函数从 inotify 文件描述符中读取事件。这些事件由 struct inotify_event 结构体表示。

以下是一个简单的使用 inotify 的示例:

#include <stdio.h>
#include <stdlib.h>
#include <stdint.h>
#include <errno.h>
#include <string.h>
#include <unistd.h>
#include <sys/inotify.h>

#define BUFFER_SIZE  (10 * (sizeof(struct inotify_event) + NAME_MAX + 1))

int main() {
    int fd, wd;
    char buffer[BUFFER_SIZE];

    fd = inotify_init();
    if (fd == -1) {
        perror("inotify_init() fail");
        exit(EXIT_FAILURE);
    }

    wd = inotify_add_watch(fd, "/tmp", IN_CREATE | IN_DELETE);
    if (wd == -1) {
        perror("inotify_add_watch() fail");
        exit(EXIT_FAILURE);
    }

    while (1) {
        ssize_t num_read = read(fd, buffer, BUFFER_SIZE);
        if (num_read == 0) {
            printf("Inotify instance closed.\n");
            exit(EXIT_SUCCESS);
        }

        if (num_read == -1) {
            if (errno == EINTR) {
                continue;
            } else {
                perror("read() fail");
                exit(EXIT_FAILURE);
            }
        }

        printf("Read %ld bytes from inotify file descriptor.\n", (long) num_read);
        struct inotify_event *event;

        for (char *p = buffer; p < buffer + num_read; ) {
            event = (struct inotify_event *) p;
            printf("Name: '%s', ", event->name);
            printf("Mask: %08x\n", event->mask);
            p += sizeof(struct inotify_event) + event->len;
        }
    }

    exit(EXIT_SUCCESS);
}
问题

Linux 内核中的 inotify 实例数量具有默认限制。在许多情况下,这个限制可能很快就被达到。当您的程序达到这个限制时,您将看到以下错误:

inotify_add_watch() fail: 
Cannot allocate memory

或者

inotify_add_watch() fail: 
Too many open files

这是因为您的 inotify 实例数量已经达到了内核中允许的最大数量。

解决方案

为了解决这个问题,我们需要通过设置内核参数 fs.inotify.max_user_watches 来增加系统中可以使用的 inotify 实例数量。

检查当前的 inotify 实例数量

在执行任何修改操作之前,我们需要检查当前系统上的 inotify 实例数限制。要检查此值,请运行以下命令:

$ cat /proc/sys/fs/inotify/max_user_watches

默认情况下,此值在许多 Linux 发行版(例如 CentOS、Debian、Ubuntu 等)中设置为 8192。

增加 inotify 实例数量

要增加系统中可以使用的 inotify 实例数量,请执行以下步骤:

  1. 使用任何文本编辑器打开 /etc/sysctl.conf 文件。

  2. 在文件末尾添加以下行:

    fs.inotify.max_user_watches=65536
    

    这将把 fs.inotify.max_user_watches 参数设置为 65536,从而增加系统中可以使用的 inotify 实例数量。

  3. 保存文件并关闭文本编辑器。

  4. 运行以下命令使更改生效:

    $ sudo sysctl --system
    

    这将重新加载系统的 Sysctl 配置文件,使更改生效。

验证更改是否生效

要验证更改是否生效,请再次运行以下命令:

$ cat /proc/sys/fs/inotify/max_user_watches

您应该会看到上面添加的新值(65536)。 如果未看到新值,则说明更改未成功应用。

结论

通过更改内核限制中 fs.inotify.max_user_watches 参数的值,您可以增加系统中可以使用的 inotify 实例数量。然后,您可以使用更多的 inotify 实例,使程序能够正确处理更广泛的文件系统事件。