unofficial mirror of meta@public-inbox.org
 help / color / mirror / Atom feed
From: Eric Wong <e@80x24.org>
To: Louis DeLosSantos <louis.delos@gmail.com>
Cc: meta@public-inbox.org
Subject: [PATCH] inotify: wrap with informative error message
Date: Tue, 28 Mar 2023 11:12:36 +0000	[thread overview]
Message-ID: <20230328111236.M627198@dcvr> (raw)
In-Reply-To: <CAE6jdTo8iQfNM9Yuk0Dwi-ARMxmQxX-onL8buXcQ9Ze3r0hKrg@mail.gmail.com>

Louis DeLosSantos <louis.delos@gmail.com> wrote:
> > Thats a lot of tail processes....
> Ugh, sorry to waste your time.

Not at all.  Thank you for sharing your experience with us as it
will benefit future users, especially since lei is still in its
early days.  I think the patch below can help future users.

> All the tails were from a run away UI program I'm working on.
> Once I killed them, `let` runs just fine as non-root.

If you're adminning your own system (which it sounds like),
increasing the fs.inotify.max_user_instances should let you
run as many `tail' processes as you desire :>

Perhaps distros and/or kernel developers may raise limits
some day for single-user systems.

My distro uses /etc/sysctl.d/*.conf and /etc/sysctl.conf
to make those knobs persistent across reboots; but distros
vary/change a lot.

> Thanks for the free tech support, hope I didn't steal your attention
> from something valuable :-D.

No problem, and thank you for being one of the brave, early lei users :>
User feedback is valuable :>

------8<------
Subject: [PATCH] inotify: wrap with informative error message

As encountered by Louis DeLosSantos, Linux inotify is capped by
a lesser-known limit than the standard RLIMIT_NOFILE (`ulimit -n`)
value.  Give the user a hint about the fs.inotify.max_user_instances
sysctl knob on EMFILE, since EMFILE alone may mislead users into
thinking they've hit the (typically higher) RLIMIT_NOFILE limit.

I can test this on my system using:

  perl -I lib -MPublicInbox::Inotify -E \
   'my @x = map { PublicInbox::Inotify->new } (1..128)'

But I hesitate to include it in the test suite since triggering
the limit can cause unrelated processes to fail.

Link: https://public-inbox.org/meta/CAE6jdTo8iQfNM9Yuk0Dwi-ARMxmQxX-onL8buXcQ9Ze3r0hKrg@mail.gmail.com/
Reported-by: Louis DeLosSantos <louis.delos@gmail.com>
---
 MANIFEST                     |  1 +
 lib/PublicInbox/DirIdle.pm   |  4 ++--
 lib/PublicInbox/InboxIdle.pm |  4 ++--
 lib/PublicInbox/Inotify.pm   | 30 ++++++++++++++++++++++++++++++
 4 files changed, 35 insertions(+), 4 deletions(-)
 create mode 100644 lib/PublicInbox/Inotify.pm

diff --git a/MANIFEST b/MANIFEST
index 40535233..3c421645 100644
--- a/MANIFEST
+++ b/MANIFEST
@@ -217,6 +217,7 @@ lib/PublicInbox/In2Tie.pm
 lib/PublicInbox/Inbox.pm
 lib/PublicInbox/InboxIdle.pm
 lib/PublicInbox/InboxWritable.pm
+lib/PublicInbox/Inotify.pm
 lib/PublicInbox/InputPipe.pm
 lib/PublicInbox/Isearch.pm
 lib/PublicInbox/KQNotify.pm
diff --git a/lib/PublicInbox/DirIdle.pm b/lib/PublicInbox/DirIdle.pm
index 55c3982f..af99811c 100644
--- a/lib/PublicInbox/DirIdle.pm
+++ b/lib/PublicInbox/DirIdle.pm
@@ -9,14 +9,14 @@ use PublicInbox::Syscall qw(EPOLLIN);
 use PublicInbox::In2Tie;
 
 my ($MAIL_IN, $MAIL_GONE, $ino_cls);
-if ($^O eq 'linux' && eval { require Linux::Inotify2; 1 }) {
+if ($^O eq 'linux' && eval { require PublicInbox::Inotify; 1 }) {
 	$MAIL_IN = Linux::Inotify2::IN_MOVED_TO() |
 		Linux::Inotify2::IN_CREATE();
 	$MAIL_GONE = Linux::Inotify2::IN_DELETE() |
 			Linux::Inotify2::IN_DELETE_SELF() |
 			Linux::Inotify2::IN_MOVE_SELF() |
 			Linux::Inotify2::IN_MOVED_FROM();
-	$ino_cls = 'Linux::Inotify2';
+	$ino_cls = 'PublicInbox::Inotify';
 # Perl 5.22+ is needed for fileno(DIRHANDLE) support:
 } elsif ($^V ge v5.22 && eval { require PublicInbox::KQNotify }) {
 	$MAIL_IN = PublicInbox::KQNotify::MOVED_TO_OR_CREATE();
diff --git a/lib/PublicInbox/InboxIdle.pm b/lib/PublicInbox/InboxIdle.pm
index f0d8a972..4231c0a0 100644
--- a/lib/PublicInbox/InboxIdle.pm
+++ b/lib/PublicInbox/InboxIdle.pm
@@ -10,9 +10,9 @@ use parent qw(PublicInbox::DS);
 use PublicInbox::Syscall qw(EPOLLIN);
 my $IN_MODIFY = 0x02; # match Linux inotify
 my $ino_cls;
-if ($^O eq 'linux' && eval { require Linux::Inotify2; 1 }) {
+if ($^O eq 'linux' && eval { require PublicInbox::Inotify }) {
 	$IN_MODIFY = Linux::Inotify2::IN_MODIFY();
-	$ino_cls = 'Linux::Inotify2';
+	$ino_cls = 'PublicInbox::Inotify';
 } elsif (eval { require PublicInbox::KQNotify }) {
 	$IN_MODIFY = PublicInbox::KQNotify::NOTE_WRITE();
 	$ino_cls = 'PublicInbox::KQNotify';
diff --git a/lib/PublicInbox/Inotify.pm b/lib/PublicInbox/Inotify.pm
new file mode 100644
index 00000000..3ef271c8
--- /dev/null
+++ b/lib/PublicInbox/Inotify.pm
@@ -0,0 +1,30 @@
+# Copyright (C) all contributors <meta@public-inbox.org>
+# License: AGPL-3.0+ <https://www.gnu.org/licenses/agpl-3.0.txt>
+
+# wrap Linux::Inotify2 XS module, support pure Perl via `syscall' someday
+package PublicInbox::Inotify;
+use v5.12;
+our @ISA;
+BEGIN {
+	eval { require Linux::Inotify2 };
+	if ($@) { # TODO: get rid of XS dependency
+		die "W: Linux::Inotify2 missing: $@\n";
+	} else {
+		push @ISA, 'Linux::Inotify2';
+	}
+};
+
+sub new {
+	$_[0]->SUPER::new // do {
+		my $msg = $!{EMFILE} ? <<EOM : "$_[0]->new: $!\n";
+inotify_init/inotify_init1: $!
+You may need to raise the `fs.inotify.max_user_instances' sysctl limit.
+Consult your OS documentation and/or sysctl(8) + sysctl.conf(5) manpages.
+EOM
+		$msg =~ s/^/E: /smg;
+		require Carp;
+		Carp::croak($msg);
+	}
+}
+
+1;

      reply	other threads:[~2023-03-28 11:12 UTC|newest]

Thread overview: 9+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2023-03-28  1:00 Issues with `lei` as non-root Louis DeLosSantos
2023-03-28  1:32 ` Eric Wong
2023-03-28  1:36   ` public-inbox.org downtime expected in the next 6-8 hours Eric Wong
2023-03-28  2:30   ` Issues with `lei` as non-root Louis DeLosSantos
2023-03-28  2:52     ` Eric Wong
2023-03-28  3:05       ` Louis DeLosSantos
2023-03-28  3:38         ` Eric Wong
2023-03-28  4:08           ` Louis DeLosSantos
2023-03-28 11:12             ` Eric Wong [this message]

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

  List information: https://public-inbox.org/README

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20230328111236.M627198@dcvr \
    --to=e@80x24.org \
    --cc=louis.delos@gmail.com \
    --cc=meta@public-inbox.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).