From owner-freebsd-fs@freebsd.org Tue Jan 5 03:53:08 2016 Return-Path: Delivered-To: freebsd-fs@mailman.ysv.freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2001:1900:2254:206a::19:1]) by mailman.ysv.freebsd.org (Postfix) with ESMTP id 3B7BDA61BB4 for ; Tue, 5 Jan 2016 03:53:08 +0000 (UTC) (envelope-from bakul@bitblocks.com) Received: from mail.bitblocks.com (ns1.bitblocks.com [173.228.5.8]) by mx1.freebsd.org (Postfix) with ESMTP id 2716314FF for ; Tue, 5 Jan 2016 03:53:07 +0000 (UTC) (envelope-from bakul@bitblocks.com) Received: from bitblocks.com (localhost [127.0.0.1]) by mail.bitblocks.com (Postfix) with ESMTP id B650FB827 for ; Mon, 4 Jan 2016 19:43:27 -0800 (PST) To: freebsd-fs@freebsd.org Subject: Re: Monitoring FS changes In-reply-to: Your message of "Mon, 04 Jan 2016 21:22:19 EST." <416747176.149128068.1451960539354.JavaMail.zimbra@uoguelph.ca> References: <201601041959.u04JxWGn053360@kithrup.com> <416747176.149128068.1451960539354.JavaMail.zimbra@uoguelph.ca> Comments: In-reply-to Rick Macklem message dated "Mon, 04 Jan 2016 21:22:19 -0500." Date: Mon, 04 Jan 2016 19:43:27 -0800 From: Bakul Shah Message-Id: <20160105034327.B650FB827@mail.bitblocks.com> X-BeenThere: freebsd-fs@freebsd.org X-Mailman-Version: 2.1.20 Precedence: list List-Id: Filesystems List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Tue, 05 Jan 2016 03:53:08 -0000 Why not do this (at least at first) in a user mode program? Intercept FS system calls and write relevant info to a user program's memory. You still need to add a syscall to watch files/dirs for various events and to validate requests. This will allow you to experiment with various implementations before commiting to a complicated new mechanism in the kernel. Something like: For the client: fd = new_watcher(); watch(fd, path, flags); // can add multiple watches count = read(fd, buf, sizeof buf); flag = 0 => remove watchpoint. flag = recursive => watch everything underneath a tree (on the same fs) other flag decide the events you want to watch. read returns one or more events. For the watcher: fd = register_watcher(buf, length); fd1 = get_watcher(fd, &path, &flag); The watcher mmaps a bunch of space and the kernel uses it as a circular buffer. The watcher can create a map of inode-id to subscribers: a list of or a ptr to a list. The indirection should make recursion cheaper to handle: objects will point to parent dir in a recursive watch. You'd still need to spend something like 8 bytes per file or dir (on a 4GB addr space system). flag = 0 => unsubscribe fd from watching the path. close the fd when the number of watches is 0. On a client disappearing path is NULL. On a watcher disappearing all clients get one final event. Hard links are not a problem: such a file will just have N items on its list, one per watched dir. Multiple watchers, each handling a different set of clients, should be possible with a little extra cost. Basically what we are doing is outsourcing most of the actual work to the watcher but the kernel still have to tell all the watchers when something changes. Very likely the same mechanism can be used to report process deaths or dead network connections etc. Undoubtedly I have missed a bunch of things here!