(root)/
util-linux-2.39/
libmount/
src/
monitor.c
       1  /* SPDX-License-Identifier: LGPL-2.1-or-later */
       2  /*
       3   * This file is part of libmount from util-linux project.
       4   *
       5   * Copyright (C) 2014-2018 Karel Zak <kzak@redhat.com>
       6   *
       7   * libmount is free software; you can redistribute it and/or modify it
       8   * under the terms of the GNU Lesser General Public License as published by
       9   * the Free Software Foundation; either version 2.1 of the License, or
      10   * (at your option) any later version.
      11   */
      12  
      13  /**
      14   * SECTION: monitor
      15   * @title: Monitor
      16   * @short_description: interface to monitor mount tables
      17   *
      18   * For example monitor VFS (/proc/self/mountinfo) for changes:
      19   *
      20   * <informalexample>
      21   *   <programlisting>
      22   * const char *filename;
      23   * struct libmount_monitor *mn = mnt_new_monitor();
      24   *
      25   * mnt_monitor_enable_kernel(mn, TRUE));
      26   *
      27   * printf("waiting for changes...\n");
      28   * while (mnt_monitor_wait(mn, -1) > 0) {
      29   *    while (mnt_monitor_next_change(mn, &filename, NULL) == 0)
      30   *       printf(" %s: change detected\n", filename);
      31   * }
      32   * mnt_unref_monitor(mn);
      33   *   </programlisting>
      34   * </informalexample>
      35   *
      36   */
      37  
      38  #include "fileutils.h"
      39  #include "mountP.h"
      40  #include "pathnames.h"
      41  
      42  #include <sys/inotify.h>
      43  #include <sys/epoll.h>
      44  
      45  
      46  struct monitor_opers;
      47  
      48  struct monitor_entry {
      49  	int			fd;		/* private entry file descriptor */
      50  	char			*path;		/* path to the monitored file */
      51  	int			type;		/* MNT_MONITOR_TYPE_* */
      52  	uint32_t		events;		/* wanted epoll events */
      53  
      54  	const struct monitor_opers *opers;
      55  
      56  	unsigned int		enable : 1,
      57  				changed : 1;
      58  
      59  	struct list_head	ents;
      60  };
      61  
      62  struct libmnt_monitor {
      63  	int			refcount;
      64  	int			fd;		/* public monitor file descriptor */
      65  
      66  	struct list_head	ents;
      67  };
      68  
      69  struct monitor_opers {
      70  	int (*op_get_fd)(struct libmnt_monitor *, struct monitor_entry *);
      71  	int (*op_close_fd)(struct libmnt_monitor *, struct monitor_entry *);
      72  	int (*op_event_verify)(struct libmnt_monitor *, struct monitor_entry *);
      73  };
      74  
      75  static int monitor_modify_epoll(struct libmnt_monitor *mn,
      76  				struct monitor_entry *me, int enable);
      77  
      78  /**
      79   * mnt_new_monitor:
      80   *
      81   * The initial refcount is 1, and needs to be decremented to
      82   * release the resources of the filesystem.
      83   *
      84   * Returns: newly allocated struct libmnt_monitor.
      85   */
      86  struct libmnt_monitor *mnt_new_monitor(void)
      87  {
      88  	struct libmnt_monitor *mn = calloc(1, sizeof(*mn));
      89  	if (!mn)
      90  		return NULL;
      91  
      92  	mn->refcount = 1;
      93  	mn->fd = -1;
      94  	INIT_LIST_HEAD(&mn->ents);
      95  
      96  	DBG(MONITOR, ul_debugobj(mn, "alloc"));
      97  	return mn;
      98  }
      99  
     100  /**
     101   * mnt_ref_monitor:
     102   * @mn: monitor pointer
     103   *
     104   * Increments reference counter.
     105   */
     106  void mnt_ref_monitor(struct libmnt_monitor *mn)
     107  {
     108  	if (mn)
     109  		mn->refcount++;
     110  }
     111  
     112  static void free_monitor_entry(struct monitor_entry *me)
     113  {
     114  	if (!me)
     115  		return;
     116  	list_del(&me->ents);
     117  	if (me->fd >= 0)
     118  		close(me->fd);
     119  	free(me->path);
     120  	free(me);
     121  }
     122  
     123  /**
     124   * mnt_unref_monitor:
     125   * @mn: monitor pointer
     126   *
     127   * Decrements the reference counter, on zero the @mn is automatically
     128   * deallocated.
     129   */
     130  void mnt_unref_monitor(struct libmnt_monitor *mn)
     131  {
     132  	if (!mn)
     133  		return;
     134  
     135  	mn->refcount--;
     136  	if (mn->refcount <= 0) {
     137  		mnt_monitor_close_fd(mn);	/* destroys all file descriptors */
     138  
     139  		while (!list_empty(&mn->ents)) {
     140  			struct monitor_entry *me = list_entry(mn->ents.next,
     141  						  struct monitor_entry, ents);
     142  			free_monitor_entry(me);
     143  		}
     144  
     145  		free(mn);
     146  	}
     147  }
     148  
     149  static struct monitor_entry *monitor_new_entry(struct libmnt_monitor *mn)
     150  {
     151  	struct monitor_entry *me;
     152  
     153  	assert(mn);
     154  
     155  	me = calloc(1, sizeof(*me));
     156  	if (!me)
     157  		return NULL;
     158          INIT_LIST_HEAD(&me->ents);
     159  	list_add_tail(&me->ents, &mn->ents);
     160  
     161  	me->fd = -1;
     162  
     163  	return me;
     164  }
     165  
     166  static int monitor_next_entry(struct libmnt_monitor *mn,
     167  			      struct libmnt_iter *itr,
     168  			      struct monitor_entry **me)
     169  {
     170  	int rc = 1;
     171  
     172  	assert(mn);
     173  	assert(itr);
     174  
     175  	if (me)
     176  		*me = NULL;
     177  
     178  	if (!itr->head)
     179  		MNT_ITER_INIT(itr, &mn->ents);
     180  	if (itr->p != itr->head) {
     181  		if (me)
     182  			*me = MNT_ITER_GET_ENTRY(itr, struct monitor_entry, ents);
     183  		MNT_ITER_ITERATE(itr);
     184  		rc = 0;
     185  	}
     186  
     187  	return rc;
     188  }
     189  
     190  /* returns entry by type */
     191  static struct monitor_entry *monitor_get_entry(struct libmnt_monitor *mn, int type)
     192  {
     193  	struct libmnt_iter itr;
     194  	struct monitor_entry *me;
     195  
     196  	mnt_reset_iter(&itr, MNT_ITER_FORWARD);
     197  	while (monitor_next_entry(mn, &itr, &me) == 0) {
     198  		if (me->type == type)
     199  			return me;
     200  	}
     201  	return NULL;
     202  }
     203  
     204  
     205  /*
     206   * Userspace monitor
     207   */
     208  
     209  static int userspace_monitor_close_fd(struct libmnt_monitor *mn __attribute__((__unused__)),
     210  				    struct monitor_entry *me)
     211  {
     212  	assert(me);
     213  
     214  	if (me->fd >= 0)
     215  		close(me->fd);
     216  	me->fd = -1;
     217  	return 0;
     218  }
     219  
     220  static int userspace_add_watch(struct monitor_entry *me, int *final, int *fd)
     221  {
     222  	char *filename = NULL;
     223  	int wd, rc = -EINVAL;
     224  
     225  	assert(me);
     226  	assert(me->path);
     227  
     228  	/*
     229  	 * libmount uses rename(2) to atomically update utab, monitor
     230  	 * rename changes is too tricky. It seems better to monitor utab
     231  	 * lockfile close.
     232  	 */
     233  	if (asprintf(&filename, "%s.lock", me->path) <= 0) {
     234  		rc = -errno;
     235  		goto done;
     236  	}
     237  
     238  	/* try lock file if already exists */
     239  	errno = 0;
     240  	wd = inotify_add_watch(me->fd, filename, IN_CLOSE_NOWRITE);
     241  	if (wd >= 0) {
     242  		DBG(MONITOR, ul_debug(" added inotify watch for %s [fd=%d]", filename, wd));
     243  		rc = 0;
     244  		if (final)
     245  			*final = 1;
     246  		if (fd)
     247  			*fd = wd;
     248  		goto done;
     249  	} else if (errno != ENOENT) {
     250  		rc = -errno;
     251  		goto done;
     252  	}
     253  
     254  	while (strchr(filename, '/')) {
     255  		stripoff_last_component(filename);
     256  		if (!*filename)
     257  			break;
     258  
     259  		/* try directory where is the lock file */
     260  		errno = 0;
     261  		wd = inotify_add_watch(me->fd, filename, IN_CREATE|IN_ISDIR);
     262  		if (wd >= 0) {
     263  			DBG(MONITOR, ul_debug(" added inotify watch for %s [fd=%d]", filename, wd));
     264  			rc = 0;
     265  			if (fd)
     266  				*fd = wd;
     267  			break;
     268  		}
     269  
     270  		if (errno != ENOENT) {
     271  			rc = -errno;
     272  			break;
     273  		}
     274  	}
     275  done:
     276  	free(filename);
     277  	return rc;
     278  }
     279  
     280  static int userspace_monitor_get_fd(struct libmnt_monitor *mn,
     281  				    struct monitor_entry *me)
     282  {
     283  	int rc;
     284  
     285  	if (!me || me->enable == 0)	/* not-initialized or disabled */
     286  		return -EINVAL;
     287  	if (me->fd >= 0)
     288  		return me->fd;		/* already initialized */
     289  
     290  	assert(me->path);
     291  	DBG(MONITOR, ul_debugobj(mn, " open userspace monitor for %s", me->path));
     292  
     293  	me->fd = inotify_init1(IN_NONBLOCK | IN_CLOEXEC);
     294  	if (me->fd < 0)
     295  		goto err;
     296  
     297  	if (userspace_add_watch(me, NULL, NULL) < 0)
     298  		goto err;
     299  
     300  	return me->fd;
     301  err:
     302  	rc = -errno;
     303  	if (me->fd >= 0)
     304  		close(me->fd);
     305  	me->fd = -1;
     306  	DBG(MONITOR, ul_debugobj(mn, "failed to create userspace monitor [rc=%d]", rc));
     307  	return rc;
     308  }
     309  
     310  /*
     311   * verify and drain inotify buffer
     312   */
     313  static int userspace_event_verify(struct libmnt_monitor *mn,
     314  					struct monitor_entry *me)
     315  {
     316  	char buf[sizeof(struct inotify_event) + NAME_MAX + 1];
     317  	int status = 0;
     318  
     319  	if (!me || me->fd < 0)
     320  		return 0;
     321  
     322  	DBG(MONITOR, ul_debugobj(mn, "drain and verify userspace monitor inotify"));
     323  
     324  	/* the me->fd is non-blocking */
     325  	do {
     326  		ssize_t len;
     327  		char *p;
     328  		const struct inotify_event *e;
     329  
     330  		len = read(me->fd, buf, sizeof(buf));
     331  		if (len < 0)
     332  			break;
     333  
     334  		for (p = buf; p < buf + len;
     335  		     p += sizeof(struct inotify_event) + e->len) {
     336  
     337  			int fd = -1;
     338  
     339  			e = (const struct inotify_event *) p;
     340  			DBG(MONITOR, ul_debugobj(mn, " inotify event 0x%x [%s]\n", e->mask, e->len ? e->name : ""));
     341  
     342  			if (e->mask & IN_CLOSE_NOWRITE)
     343  				status = 1;
     344  			else {
     345  				/* event on lock file */
     346  				userspace_add_watch(me, &status, &fd);
     347  
     348  				if (fd != e->wd) {
     349  					DBG(MONITOR, ul_debugobj(mn, " removing watch [fd=%d]", e->wd));
     350  					inotify_rm_watch(me->fd, e->wd);
     351  				}
     352  			}
     353  		}
     354  	} while (1);
     355  
     356  	DBG(MONITOR, ul_debugobj(mn, "%s", status == 1 ? " success" : " nothing"));
     357  	return status;
     358  }
     359  
     360  /*
     361   * userspace monitor operations
     362   */
     363  static const struct monitor_opers userspace_opers = {
     364  	.op_get_fd		= userspace_monitor_get_fd,
     365  	.op_close_fd		= userspace_monitor_close_fd,
     366  	.op_event_verify	= userspace_event_verify
     367  };
     368  
     369  /**
     370   * mnt_monitor_enable_userspace:
     371   * @mn: monitor
     372   * @enable: 0 or 1
     373   * @filename: overwrites default
     374   *
     375   * Enables or disables userspace monitoring. If the userspace monitor does not
     376   * exist and enable=1 then allocates new resources necessary for the monitor.
     377   *
     378   * If the top-level monitor has been already created (by mnt_monitor_get_fd()
     379   * or mnt_monitor_wait()) then it's updated according to @enable.
     380   *
     381   * The @filename is used only the first time when you enable the monitor. It's
     382   * impossible to have more than one userspace monitor. The recommended is to
     383   * use NULL as filename.
     384   *
     385   * The userspace monitor is unsupported for systems with classic regular
     386   * /etc/mtab file.
     387   *
     388   * Return: 0 on success and <0 on error
     389   */
     390  int mnt_monitor_enable_userspace(struct libmnt_monitor *mn, int enable, const char *filename)
     391  {
     392  	struct monitor_entry *me;
     393  	int rc = 0;
     394  
     395  	if (!mn)
     396  		return -EINVAL;
     397  
     398  	me = monitor_get_entry(mn, MNT_MONITOR_TYPE_USERSPACE);
     399  	if (me) {
     400  		rc = monitor_modify_epoll(mn, me, enable);
     401  		if (!enable)
     402  			userspace_monitor_close_fd(mn, me);
     403  		return rc;
     404  	}
     405  	if (!enable)
     406  		return 0;
     407  
     408  	DBG(MONITOR, ul_debugobj(mn, "allocate new userspace monitor"));
     409  
     410  	if (!filename)
     411  		filename = mnt_get_utab_path();		/* /run/mount/utab */
     412  	if (!filename) {
     413  		DBG(MONITOR, ul_debugobj(mn, "failed to get userspace mount table path"));
     414  		return -EINVAL;
     415  	}
     416  
     417  	me = monitor_new_entry(mn);
     418  	if (!me)
     419  		goto err;
     420  
     421  	me->type = MNT_MONITOR_TYPE_USERSPACE;
     422  	me->opers = &userspace_opers;
     423  	me->events = EPOLLIN;
     424  	me->path = strdup(filename);
     425  	if (!me->path)
     426  		goto err;
     427  
     428  	return monitor_modify_epoll(mn, me, TRUE);
     429  err:
     430  	rc = -errno;
     431  	free_monitor_entry(me);
     432  	DBG(MONITOR, ul_debugobj(mn, "failed to allocate userspace monitor [rc=%d]", rc));
     433  	return rc;
     434  }
     435  
     436  
     437  /*
     438   * Kernel monitor
     439   */
     440  
     441  static int kernel_monitor_close_fd(struct libmnt_monitor *mn __attribute__((__unused__)),
     442  				   struct monitor_entry *me)
     443  {
     444  	assert(me);
     445  
     446  	if (me->fd >= 0)
     447  		close(me->fd);
     448  	me->fd = -1;
     449  	return 0;
     450  }
     451  
     452  static int kernel_monitor_get_fd(struct libmnt_monitor *mn,
     453  				 struct monitor_entry *me)
     454  {
     455  	int rc;
     456  
     457  	if (!me || me->enable == 0)	/* not-initialized or disabled */
     458  		return -EINVAL;
     459  	if (me->fd >= 0)
     460  		return me->fd;		/* already initialized */
     461  
     462  	assert(me->path);
     463  	DBG(MONITOR, ul_debugobj(mn, " open kernel monitor for %s", me->path));
     464  
     465  	me->fd = open(me->path, O_RDONLY|O_CLOEXEC);
     466  	if (me->fd < 0)
     467  		goto err;
     468  
     469  	return me->fd;
     470  err:
     471  	rc = -errno;
     472  	DBG(MONITOR, ul_debugobj(mn, "failed to create kernel  monitor [rc=%d]", rc));
     473  	return rc;
     474  }
     475  
     476  /*
     477   * kernel monitor operations
     478   */
     479  static const struct monitor_opers kernel_opers = {
     480  	.op_get_fd		= kernel_monitor_get_fd,
     481  	.op_close_fd		= kernel_monitor_close_fd,
     482  };
     483  
     484  /**
     485   * mnt_monitor_enable_kernel:
     486   * @mn: monitor
     487   * @enable: 0 or 1
     488   *
     489   * Enables or disables kernel VFS monitoring. If the monitor does not exist and
     490   * enable=1 then allocates new resources necessary for the monitor.
     491   *
     492   * If the top-level monitor has been already created (by mnt_monitor_get_fd()
     493   * or mnt_monitor_wait()) then it's updated according to @enable.
     494   *
     495   * Return: 0 on success and <0 on error
     496   */
     497  int mnt_monitor_enable_kernel(struct libmnt_monitor *mn, int enable)
     498  {
     499  	struct monitor_entry *me;
     500  	int rc = 0;
     501  
     502  	if (!mn)
     503  		return -EINVAL;
     504  
     505  	me = monitor_get_entry(mn, MNT_MONITOR_TYPE_KERNEL);
     506  	if (me) {
     507  		rc = monitor_modify_epoll(mn, me, enable);
     508  		if (!enable)
     509  			kernel_monitor_close_fd(mn, me);
     510  		return rc;
     511  	}
     512  	if (!enable)
     513  		return 0;
     514  
     515  	DBG(MONITOR, ul_debugobj(mn, "allocate new kernel monitor"));
     516  
     517  	/* create a new entry */
     518  	me = monitor_new_entry(mn);
     519  	if (!me)
     520  		goto err;
     521  
     522  	/* If you want to use epoll FD in another epoll then top level
     523  	 * epoll_wait() will drain all events from low-level FD if the
     524  	 * low-level FD is not added with EPOLLIN. It means without EPOLLIN it
     525  	 * it's impossible to detect which low-level FD has been active.
     526  	 *
     527  	 * Unfortunately, use EPOLLIN for mountinfo is tricky because in this
     528  	 * case kernel returns events all time (we don't read from the FD).
     529  	 * The solution is to use also edge-triggered (EPOLLET) flag, then
     530  	 * kernel generate events on mountinfo changes only. The disadvantage is
     531  	 * that we have to drain initial event generated by EPOLLIN after
     532  	 * epoll_ctl(ADD). See monitor_modify_epoll().
     533  	 */
     534  	me->events = EPOLLIN | EPOLLET;
     535  
     536  	me->type = MNT_MONITOR_TYPE_KERNEL;
     537  	me->opers = &kernel_opers;
     538  	me->path = strdup(_PATH_PROC_MOUNTINFO);
     539  	if (!me->path)
     540  		goto err;
     541  
     542  	return monitor_modify_epoll(mn, me, TRUE);
     543  err:
     544  	rc = -errno;
     545  	free_monitor_entry(me);
     546  	DBG(MONITOR, ul_debugobj(mn, "failed to allocate kernel monitor [rc=%d]", rc));
     547  	return rc;
     548  }
     549  
     550  /*
     551   * Add/Remove monitor entry to/from monitor epoll.
     552   */
     553  static int monitor_modify_epoll(struct libmnt_monitor *mn,
     554  				struct monitor_entry *me, int enable)
     555  {
     556  	assert(mn);
     557  	assert(me);
     558  
     559  	me->enable = enable ? 1 : 0;
     560  	me->changed = 0;
     561  
     562  	if (mn->fd < 0)
     563  		return 0;	/* no epoll, ignore request */
     564  
     565  	if (enable) {
     566  		struct epoll_event ev = { .events = me->events };
     567  		int fd = me->opers->op_get_fd(mn, me);
     568  
     569  		if (fd < 0)
     570  			goto err;
     571  
     572  		DBG(MONITOR, ul_debugobj(mn, " add fd=%d (for %s)", fd, me->path));
     573  
     574  		ev.data.ptr = (void *) me;
     575  
     576  		if (epoll_ctl(mn->fd, EPOLL_CTL_ADD, fd, &ev) < 0) {
     577  			if (errno != EEXIST)
     578  				goto err;
     579  		}
     580  		if (me->events & (EPOLLIN | EPOLLET)) {
     581  			/* Drain initial events generated for /proc/self/mountinfo */
     582  			struct epoll_event events[1];
     583  			while (epoll_wait(mn->fd, events, 1, 0) > 0);
     584  		}
     585  	} else if (me->fd) {
     586  		DBG(MONITOR, ul_debugobj(mn, " remove fd=%d (for %s)", me->fd, me->path));
     587  		if (epoll_ctl(mn->fd, EPOLL_CTL_DEL, me->fd, NULL) < 0) {
     588  			if (errno != ENOENT)
     589  				goto err;
     590  		}
     591  	}
     592  
     593  	return 0;
     594  err:
     595  	return -errno;
     596  }
     597  
     598  /**
     599   * mnt_monitor_close_fd:
     600   * @mn: monitor
     601   *
     602   * Close monitor file descriptor. This is usually unnecessary, because
     603   * mnt_unref_monitor() cleanups all.
     604   *
     605   * The function is necessary only if you want to reset monitor setting. The
     606   * next mnt_monitor_get_fd() or mnt_monitor_wait() will use newly initialized
     607   * monitor.  This restart is unnecessary for mnt_monitor_enable_*() functions.
     608   *
     609   * Returns: 0 on success, <0 on error.
     610   */
     611  int mnt_monitor_close_fd(struct libmnt_monitor *mn)
     612  {
     613  	struct libmnt_iter itr;
     614  	struct monitor_entry *me;
     615  
     616  	if (!mn)
     617  		return -EINVAL;
     618  
     619  	mnt_reset_iter(&itr, MNT_ITER_FORWARD);
     620  
     621  	/* disable all monitor entries */
     622  	while (monitor_next_entry(mn, &itr, &me) == 0) {
     623  
     624  		/* remove entry from epoll */
     625  		if (mn->fd >= 0)
     626  			monitor_modify_epoll(mn, me, FALSE);
     627  
     628  		/* close entry FD */
     629  		me->opers->op_close_fd(mn, me);
     630  	}
     631  
     632  	if (mn->fd >= 0) {
     633  		DBG(MONITOR, ul_debugobj(mn, "closing top-level monitor fd"));
     634  		close(mn->fd);
     635  	}
     636  	mn->fd = -1;
     637  	return 0;
     638  }
     639  
     640  /**
     641   * mnt_monitor_get_fd:
     642   * @mn: monitor
     643   *
     644   * The file descriptor is associated with all monitored files and it's usable
     645   * for example for epoll. You have to call mnt_monitor_event_cleanup() or
     646   * mnt_monitor_next_change() after each event.
     647   *
     648   * Returns: >=0 (fd) on success, <0 on error
     649   */
     650  int mnt_monitor_get_fd(struct libmnt_monitor *mn)
     651  {
     652  	struct libmnt_iter itr;
     653  	struct monitor_entry *me;
     654  	int rc = 0;
     655  
     656  	if (!mn)
     657  		return -EINVAL;
     658  	if (mn->fd >= 0)
     659  		return mn->fd;
     660  
     661  	DBG(MONITOR, ul_debugobj(mn, "create top-level monitor fd"));
     662  	mn->fd = epoll_create1(EPOLL_CLOEXEC);
     663  	if (mn->fd < 0)
     664  		return -errno;
     665  
     666  	mnt_reset_iter(&itr, MNT_ITER_FORWARD);
     667  
     668  	DBG(MONITOR, ul_debugobj(mn, "adding monitor entries to epoll (fd=%d)", mn->fd));
     669  	while (monitor_next_entry(mn, &itr, &me) == 0) {
     670  		if (!me->enable)
     671  			continue;
     672  		rc = monitor_modify_epoll(mn, me, TRUE);
     673  		if (rc)
     674  			goto err;
     675  	}
     676  
     677  	DBG(MONITOR, ul_debugobj(mn, "successfully created monitor"));
     678  	return mn->fd;
     679  err:
     680  	rc = errno ? -errno : -EINVAL;
     681  	close(mn->fd);
     682  	mn->fd = -1;
     683  	DBG(MONITOR, ul_debugobj(mn, "failed to create monitor [rc=%d]", rc));
     684  	return rc;
     685  }
     686  
     687  /**
     688   * mnt_monitor_wait:
     689   * @mn: monitor
     690   * @timeout: number of milliseconds, -1 block indefinitely, 0 return immediately
     691   *
     692   * Waits for the next change, after the event it's recommended to use
     693   * mnt_monitor_next_change() to get more details about the change and to
     694   * avoid false positive events.
     695   *
     696   * Returns: 1 success (something changed), 0 timeout, <0 error.
     697   */
     698  int mnt_monitor_wait(struct libmnt_monitor *mn, int timeout)
     699  {
     700  	int rc;
     701  	struct monitor_entry *me;
     702  	struct epoll_event events[1];
     703  
     704  	if (!mn)
     705  		return -EINVAL;
     706  
     707  	if (mn->fd < 0) {
     708  		rc = mnt_monitor_get_fd(mn);
     709  		if (rc < 0)
     710  			return rc;
     711  	}
     712  
     713  	do {
     714  		DBG(MONITOR, ul_debugobj(mn, "calling epoll_wait(), timeout=%d", timeout));
     715  		rc = epoll_wait(mn->fd, events, 1, timeout);
     716  		if (rc < 0)
     717  			return -errno;		/* error */
     718  		if (rc == 0)
     719  			return 0;		/* timeout */
     720  
     721  		me = (struct monitor_entry *) events[0].data.ptr;
     722  		if (!me)
     723  			return -EINVAL;
     724  
     725  		if (me->opers->op_event_verify == NULL ||
     726  		    me->opers->op_event_verify(mn, me) == 1) {
     727  			me->changed = 1;
     728  			break;
     729  		}
     730  	} while (1);
     731  
     732  	return 1;			/* success */
     733  }
     734  
     735  
     736  static struct monitor_entry *get_changed(struct libmnt_monitor *mn)
     737  {
     738  	struct libmnt_iter itr;
     739  	struct monitor_entry *me;
     740  
     741  	mnt_reset_iter(&itr, MNT_ITER_FORWARD);
     742  	while (monitor_next_entry(mn, &itr, &me) == 0) {
     743  		if (me->changed)
     744  			return me;
     745  	}
     746  	return NULL;
     747  }
     748  
     749  /**
     750   * mnt_monitor_next_change:
     751   * @mn: monitor
     752   * @filename: returns changed file (optional argument)
     753   * @type: returns MNT_MONITOR_TYPE_* (optional argument)
     754   *
     755   * The function does not wait and it's designed to provide details about changes.
     756   * It's always recommended to use this function to avoid false positives.
     757   *
     758   * Returns: 0 on success, 1 no change, <0 on error
     759   */
     760  int mnt_monitor_next_change(struct libmnt_monitor *mn,
     761  			     const char **filename,
     762  			     int *type)
     763  {
     764  	int rc;
     765  	struct monitor_entry *me;
     766  
     767  	if (!mn || mn->fd < 0)
     768  		return -EINVAL;
     769  
     770  	/*
     771  	 * if we previously called epoll_wait() (e.g. mnt_monitor_wait()) then
     772  	 * info about unread change is already stored in monitor_entry.
     773  	 *
     774  	 * If we get nothing, then ask kernel.
     775  	 */
     776  	me = get_changed(mn);
     777  	while (!me) {
     778  		struct epoll_event events[1];
     779  
     780  		DBG(MONITOR, ul_debugobj(mn, "asking for next changed"));
     781  
     782  		rc = epoll_wait(mn->fd, events, 1, 0);	/* no timeout! */
     783  		if (rc < 0) {
     784  			DBG(MONITOR, ul_debugobj(mn, " *** error"));
     785  			return -errno;
     786  		}
     787  		if (rc == 0) {
     788  			DBG(MONITOR, ul_debugobj(mn, " *** nothing"));
     789  			return 1;
     790  		}
     791  
     792  		me = (struct monitor_entry *) events[0].data.ptr;
     793  		if (!me)
     794  			return -EINVAL;
     795  
     796  		if (me->opers->op_event_verify != NULL &&
     797  		    me->opers->op_event_verify(mn, me) != 1)
     798  			me = NULL;
     799  	}
     800  
     801  	me->changed = 0;
     802  
     803  	if (filename)
     804  		*filename = me->path;
     805  	if (type)
     806  		*type = me->type;
     807  
     808  	DBG(MONITOR, ul_debugobj(mn, " *** success [changed: %s]", me->path));
     809  	return 0;
     810  }
     811  
     812  /**
     813   * mnt_monitor_event_cleanup:
     814   * @mn: monitor
     815   *
     816   * This function cleanups (drain) internal buffers. It's necessary to call
     817   * this function after event if you do not call mnt_monitor_next_change().
     818   *
     819   * Returns: 0 on success, <0 on error
     820   */
     821  int mnt_monitor_event_cleanup(struct libmnt_monitor *mn)
     822  {
     823  	int rc;
     824  
     825  	if (!mn || mn->fd < 0)
     826  		return -EINVAL;
     827  
     828  	while ((rc = mnt_monitor_next_change(mn, NULL, NULL)) == 0);
     829  	return rc < 0 ? rc : 0;
     830  }
     831  
     832  #ifdef TEST_PROGRAM
     833  
     834  static struct libmnt_monitor *create_test_monitor(int argc, char *argv[])
     835  {
     836  	struct libmnt_monitor *mn;
     837  	int i;
     838  
     839  	mn = mnt_new_monitor();
     840  	if (!mn) {
     841  		warn("failed to allocate monitor");
     842  		goto err;
     843  	}
     844  
     845  	for (i = 1; i < argc; i++) {
     846  		if (strcmp(argv[i], "userspace") == 0) {
     847  			if (mnt_monitor_enable_userspace(mn, TRUE, NULL)) {
     848  				warn("failed to initialize userspace monitor");
     849  				goto err;
     850  			}
     851  
     852  		} else if (strcmp(argv[i], "kernel") == 0) {
     853  			if (mnt_monitor_enable_kernel(mn, TRUE)) {
     854  				warn("failed to initialize kernel monitor");
     855  				goto err;
     856  			}
     857  		}
     858  	}
     859  	if (i == 1) {
     860  		warnx("No monitor type specified");
     861  		goto err;
     862  	}
     863  
     864  	return mn;
     865  err:
     866  	mnt_unref_monitor(mn);
     867  	return NULL;
     868  }
     869  
     870  /*
     871   * create a monitor and add the monitor fd to epoll
     872   */
     873  static int __test_epoll(struct libmnt_test *ts, int argc, char *argv[], int cleanup)
     874  {
     875  	int fd, efd = -1, rc = -1;
     876  	struct epoll_event ev;
     877  	struct libmnt_monitor *mn = create_test_monitor(argc, argv);
     878  
     879  	if (!mn)
     880  		return -1;
     881  
     882  	fd = mnt_monitor_get_fd(mn);
     883  	if (fd < 0) {
     884  		warn("failed to initialize monitor fd");
     885  		goto done;
     886  	}
     887  
     888  	efd = epoll_create1(EPOLL_CLOEXEC);
     889  	if (efd < 0) {
     890  		warn("failed to create epoll");
     891  		goto done;
     892  	}
     893  
     894  	ev.events = EPOLLIN;
     895  	ev.data.fd = fd;
     896  
     897  	rc = epoll_ctl(efd, EPOLL_CTL_ADD, fd, &ev);
     898  	if (rc < 0) {
     899  		warn("failed to add fd to epoll");
     900  		goto done;
     901  	}
     902  
     903  	printf("waiting for changes...\n");
     904  	do {
     905  		const char *filename = NULL;
     906  		struct epoll_event events[1];
     907  		int n = epoll_wait(efd, events, 1, -1);
     908  
     909  		if (n < 0) {
     910  			rc = -errno;
     911  			warn("polling error");
     912  			goto done;
     913  		}
     914  		if (n == 0 || events[0].data.fd != fd)
     915  			continue;
     916  
     917  		printf(" top-level FD active\n");
     918  		if (cleanup)
     919  			mnt_monitor_event_cleanup(mn);
     920  		else {
     921  			while (mnt_monitor_next_change(mn, &filename, NULL) == 0)
     922  				printf("  %s: change detected\n", filename);
     923  		}
     924  	} while (1);
     925  
     926  	rc = 0;
     927  done:
     928  	if (efd >= 0)
     929  		close(efd);
     930  	mnt_unref_monitor(mn);
     931  	return rc;
     932  }
     933  
     934  /*
     935   * create a monitor and add the monitor fd to epoll
     936   */
     937  static int test_epoll(struct libmnt_test *ts, int argc, char *argv[])
     938  {
     939  	return __test_epoll(ts, argc, argv, 0);
     940  }
     941  
     942  static int test_epoll_cleanup(struct libmnt_test *ts, int argc, char *argv[])
     943  {
     944  	return __test_epoll(ts, argc, argv, 1);
     945  }
     946  
     947  /*
     948   * create a monitor and wait for a change
     949   */
     950  static int test_wait(struct libmnt_test *ts, int argc, char *argv[])
     951  {
     952  	const char *filename;
     953  	struct libmnt_monitor *mn = create_test_monitor(argc, argv);
     954  
     955  	if (!mn)
     956  		return -1;
     957  
     958  	printf("waiting for changes...\n");
     959  	while (mnt_monitor_wait(mn, -1) > 0) {
     960  		printf("notification detected\n");
     961  
     962  		while (mnt_monitor_next_change(mn, &filename, NULL) == 0)
     963  			printf(" %s: change detected\n", filename);
     964  
     965  	}
     966  	mnt_unref_monitor(mn);
     967  	return 0;
     968  }
     969  
     970  int main(int argc, char *argv[])
     971  {
     972  	struct libmnt_test tss[] = {
     973  		{ "--epoll", test_epoll, "<userspace kernel ...>  monitor in epoll" },
     974  		{ "--epoll-clean", test_epoll_cleanup, "<userspace kernel ...>  monitor in epoll and clean events" },
     975  		{ "--wait",  test_wait,  "<userspace kernel ...>  monitor wait function" },
     976  		{ NULL }
     977  	};
     978  
     979  	return mnt_run_test(tss, argc, argv);
     980  }
     981  
     982  #endif /* TEST_PROGRAM */