diff options
-rw-r--r-- | pkg/sentry/syscalls/linux/sys_file.go | 8 | ||||
-rw-r--r-- | test/syscalls/linux/inotify.cc | 21 |
2 files changed, 28 insertions, 1 deletions
diff --git a/pkg/sentry/syscalls/linux/sys_file.go b/pkg/sentry/syscalls/linux/sys_file.go index 3193718b5..5a874d935 100644 --- a/pkg/sentry/syscalls/linux/sys_file.go +++ b/pkg/sentry/syscalls/linux/sys_file.go @@ -1698,7 +1698,13 @@ func utimes(t *kernel.Task, dirFD kdefs.FD, addr usermem.Addr, ts fs.TimeSpec, r } } - return d.Inode.SetTimestamps(t, d, ts) + if err := d.Inode.SetTimestamps(t, d, ts); err != nil { + return err + } + + // File attribute changed, generate notification. + d.InotifyEvent(linux.IN_ATTRIB, 0) + return nil } // From utimes.c: diff --git a/test/syscalls/linux/inotify.cc b/test/syscalls/linux/inotify.cc index 88997094c..b99d339e5 100644 --- a/test/syscalls/linux/inotify.cc +++ b/test/syscalls/linux/inotify.cc @@ -18,6 +18,7 @@ #include <sys/epoll.h> #include <sys/inotify.h> #include <sys/ioctl.h> +#include <sys/time.h> #include <atomic> #include <list> @@ -1232,6 +1233,26 @@ TEST(Inotify, LinkGeneratesAttribAndCreateEvents) { Event(IN_CREATE, root_wd, Basename(link1.path()))})); } +TEST(Inotify, UtimesGeneratesAttribEvent) { + const TempPath root = ASSERT_NO_ERRNO_AND_VALUE(TempPath::CreateDir()); + const FileDescriptor fd = + ASSERT_NO_ERRNO_AND_VALUE(InotifyInit1(IN_NONBLOCK)); + const TempPath file1 = + ASSERT_NO_ERRNO_AND_VALUE(TempPath::CreateFileIn(root.path())); + + const FileDescriptor file1_fd = + ASSERT_NO_ERRNO_AND_VALUE(Open(file1.path(), O_RDWR)); + const int wd = ASSERT_NO_ERRNO_AND_VALUE( + InotifyAddWatch(fd.get(), root.path(), IN_ALL_EVENTS)); + + struct timeval times[2] = {{1, 0}, {2, 0}}; + EXPECT_THAT(futimes(file1_fd.get(), times), SyscallSucceeds()); + + const std::vector<Event> events = + ASSERT_NO_ERRNO_AND_VALUE(DrainEvents(fd.get())); + ASSERT_THAT(events, Are({Event(IN_ATTRIB, wd, Basename(file1.path()))})); +} + TEST(Inotify, HardlinksReuseSameWatch) { const TempPath root = ASSERT_NO_ERRNO_AND_VALUE(TempPath::CreateDir()); TempPath file1 = |