if (mnt_update_already_done(cxt->update, cxt->lock)) {
DBG(CXT, ul_debugobj(cxt, "don't update: error evaluate or already updated"));
- goto end;
+ goto emit;
}
} else if (cxt->helper) {
DBG(CXT, ul_debugobj(cxt, "don't update: external helper"));
}
rc = mnt_update_table(cxt->update, cxt->lock);
-
+emit:
+ if (rc == 0 && !mnt_context_within_helper(cxt))
+ mnt_update_emit_event(cxt->update);
end:
if (!mnt_context_switch_ns(cxt, ns_old))
return -MNT_ERR_NAMESPACE;
assert(me->path);
/*
- * libmount uses rename(2) to atomically update utab, monitor
- * rename changes is too tricky. It seems better to monitor utab
- * lockfile close.
+ * libmount uses utab.event file to monitor and control utab updates
*/
- if (asprintf(&filename, "%s.lock", me->path) <= 0) {
+ if (asprintf(&filename, "%s.event", me->path) <= 0) {
rc = -errno;
goto done;
}
- /* try lock file if already exists */
+ /* try event file if already exists */
errno = 0;
- wd = inotify_add_watch(me->fd, filename, IN_CLOSE_NOWRITE);
+ wd = inotify_add_watch(me->fd, filename, IN_CLOSE_WRITE);
if (wd >= 0) {
DBG(MONITOR, ul_debug(" added inotify watch for %s [fd=%d]", filename, wd));
rc = 0;
if (!*filename)
break;
- /* try directory where is the lock file */
+ /* try directory where is the event file */
errno = 0;
wd = inotify_add_watch(me->fd, filename, IN_CREATE|IN_ISDIR);
if (wd >= 0) {
e = (const struct inotify_event *) p;
DBG(MONITOR, ul_debugobj(mn, " inotify event 0x%x [%s]\n", e->mask, e->len ? e->name : ""));
- if (e->mask & IN_CLOSE_NOWRITE)
+ if (e->mask & IN_CLOSE_WRITE)
status = 1;
else {
- /* event on lock file */
+ /* add watch for the event file */
userspace_add_watch(me, &status, &fd);
if (fd != e->wd) {
extern struct libmnt_optlist *mnt_context_get_optlist(struct libmnt_context *cxt);
/* tab_update.c */
+extern int mnt_update_emit_event(struct libmnt_update *upd);
extern int mnt_update_set_filename(struct libmnt_update *upd, const char *filename);
extern int mnt_update_already_done(struct libmnt_update *upd,
struct libmnt_lock *lc);
return rc;
}
+int mnt_update_emit_event(struct libmnt_update *upd)
+{
+ char *filename;
+ int fd;
+
+ if (!upd || !upd->filename)
+ return -EINVAL;
+
+ if (asprintf(&filename, "%s.event", upd->filename) <= 0)
+ return -errno;
+
+ fd = open(filename, O_WRONLY|O_CREAT|O_CLOEXEC,
+ S_IWUSR|S_IRUSR|S_IRGRP|S_IROTH);
+ free(filename);
+ if (fd < 0)
+ return -errno;
+ close(fd);
+ return 0;
+}
#ifdef TEST_PROGRAM