Skip to contentSkip to conversation

virtio-9p: fix build on !CONFIG_UTIMENSAT

PATCH Superseded Hidetoshi Seto 3 participants 7 messages Nov 18, 2010 KVM

v4 of 5 Superseded Latest is v5 →

lore
Share & tools
lore
#0 lore raw

PATCH v4 1/1 virtio-9p: fix build on !CONFIG_UTIMENSAT

This patch introduce a fallback mechanism for old systems that do not support utimensat(). This fix build failure with following warnings:

hw/virtio-9p-local.c: In function 'local_utimensat':
hw/virtio-9p-local.c:479: warning: implicit declaration of function 'utimensat' hw/virtio-9p-local.c:479: warning: nested extern declaration of 'utimensat'

and:

hw/virtio-9p.c: In function 'v9fs_setattr_post_chmod':
hw/virtio-9p.c:1410: error: 'UTIME_NOW' undeclared (first use in this function) hw/virtio-9p.c:1410: error: (Each undeclared identifier is reported only once hw/virtio-9p.c:1410: error: for each function it appears in.) hw/virtio-9p.c:1413: error: 'UTIME_OMIT' undeclared (first use in this function) hw/virtio-9p.c: In function 'v9fs_wstat_post_chmod':
hw/virtio-9p.c:2905: error: 'UTIME_OMIT' undeclared (first use in this function)

v4:
- Use tv_now.tv_usec
- Rebased on latest qemu.git
v3:
- Use better alternative handling for UTIME_NOW/OMIT
- Move qemu_utimensat() to cutils.c
V2:
- Introduce qemu_utimensat()

---
 cutils.c             |   44 ++++++++++++++++++++++++++++++++++++++++++++
 hw/virtio-9p-local.c |    4 ++--
 qemu-common.h        |   10 ++++++++++
 3 files changed, 56 insertions(+), 2 deletions(-)
cutils.c +44 -0
index 28089aa..dbeb3f2 100644
@@ -371,3 +371,47 @@ fail:
 
     return retval;
 }
+
+int qemu_utimensat(int dirfd, const char *path, const struct timespec *times,
+                   int flags)
+{
+#ifdef CONFIG_UTIMENSAT
+    return utimensat(dirfd, path, times, flags);
+#else
+    /* Fallback: use utimes() instead of utimensat() */
+    struct timeval tv[2], tv_now;
+    struct stat st;
+    int i;
+
+    /* happy if special cases */
+    if (times[0].tv_nsec == UTIME_OMIT && times[1].tv_nsec == UTIME_OMIT) {
+        return 0;
+    }
+    if (times[0].tv_nsec == UTIME_NOW && times[1].tv_nsec == UTIME_NOW) {
+        return utimes(path, NULL);
+    }
+
+    /* prepare for hard cases */
+    if (times[0].tv_nsec == UTIME_NOW || times[1].tv_nsec == UTIME_NOW) {
+        gettimeofday(&tv_now, NULL);
+    }
+    if (times[0].tv_nsec == UTIME_OMIT || times[1].tv_nsec == UTIME_OMIT) {
+        stat(path, &st);
+    }
+
+    for (i = 0; i < 2; i++) {
+        if (times[i].tv_nsec == UTIME_NOW) {
+            tv[i].tv_sec = tv_now.tv_sec;
+            tv[i].tv_usec = tv_now.tv_usec;
+        } else if (times[i].tv_nsec == UTIME_OMIT) {
+            tv[i].tv_sec = (i == 0) ? st.st_atime : st.st_mtime;
+            tv[i].tv_usec = 0;
+        } else {
+            tv[i].tv_sec = times[i].tv_sec;
+            tv[i].tv_usec = times[i].tv_nsec / 1000;
+        }
+    }
+
+    return utimes(path, &tv[0]);
+#endif
+}
hw/virtio-9p-local.c +2 -2
index 0d52020..41603ea 100644
@@ -480,9 +480,9 @@ static int local_chown(FsContext *fs_ctx, const char *path, FsCred *credp)
 }
 
 static int local_utimensat(FsContext *s, const char *path,
-		       const struct timespec *buf)
+                           const struct timespec *buf)
 {
-    return utimensat(AT_FDCWD, rpath(s, path), buf, AT_SYMLINK_NOFOLLOW);
+    return qemu_utimensat(AT_FDCWD, rpath(s, path), buf, AT_SYMLINK_NOFOLLOW);
 }
 
 static int local_remove(FsContext *ctx, const char *path)
qemu-common.h +10 -0
index b3957f1..f0b2c9d 100644
@@ -150,6 +150,16 @@ int qemu_fls(int i);
 int qemu_fdatasync(int fd);
 int fcntl_setfl(int fd, int flag);
 ssize_t strtosz(const char *nptr, char **end);
+#ifndef CONFIG_UTIMENSAT
+#ifndef UTIME_NOW
+# define UTIME_NOW     ((1l << 30) - 1l)
+#endif
+#ifndef UTIME_OMIT
+# define UTIME_OMIT    ((1l << 30) - 2l)
+#endif
+#endif
+int qemu_utimensat(int dirfd, const char *path, const struct timespec *times,
+    int flags);
 
 /* path.c */
 void init_paths(const char *prefix);
Signature · 1 line
1.7.3.1
#1 lore raw
Quoted 26 lines · Hidetoshi Seto

This patch introduce a fallback mechanism for old systems that do not support utimensat(). This fix build failure with following warnings:

hw/virtio-9p-local.c: In function 'local_utimensat':
hw/virtio-9p-local.c:479: warning: implicit declaration of function 'utimensat' hw/virtio-9p-local.c:479: warning: nested extern declaration of 'utimensat'

and:

hw/virtio-9p.c: In function 'v9fs_setattr_post_chmod':
hw/virtio-9p.c:1410: error: 'UTIME_NOW' undeclared (first use in this function) hw/virtio-9p.c:1410: error: (Each undeclared identifier is reported only once hw/virtio-9p.c:1410: error: for each function it appears in.) hw/virtio-9p.c:1413: error: 'UTIME_OMIT' undeclared (first use in this function) hw/virtio-9p.c: In function 'v9fs_wstat_post_chmod':
hw/virtio-9p.c:2905: error: 'UTIME_OMIT' undeclared (first use in this function)

v4:
- Use tv_now.tv_usec
- Rebased on latest qemu.git
v3:
- Use better alternative handling for UTIME_NOW/OMIT
- Move qemu_utimensat() to cutils.c
V2:
- Introduce qemu_utimensat()

Quoted 3 lines

Hi Hidetoshi,

I think the idea of the patch is good, but please move qemu_utimensat() to oslib-posix.c and provide a wrapper for oslib-win32.c. It is emulation for a system library function, so it doesn't belong in cutils.c, but rather in the oslib group.

Thanks,
Jes

#2 lore raw
Quoted 31 lines · Jes Sorensen
Quoted 26 lines · Hidetoshi Seto

This patch introduce a fallback mechanism for old systems that do not support utimensat(). This fix build failure with following warnings:

hw/virtio-9p-local.c: In function 'local_utimensat':
hw/virtio-9p-local.c:479: warning: implicit declaration of function 'utimensat' hw/virtio-9p-local.c:479: warning: nested extern declaration of 'utimensat'

and:

hw/virtio-9p.c: In function 'v9fs_setattr_post_chmod':
hw/virtio-9p.c:1410: error: 'UTIME_NOW' undeclared (first use in this function) hw/virtio-9p.c:1410: error: (Each undeclared identifier is reported only once hw/virtio-9p.c:1410: error: for each function it appears in.) hw/virtio-9p.c:1413: error: 'UTIME_OMIT' undeclared (first use in this function) hw/virtio-9p.c: In function 'v9fs_wstat_post_chmod':
hw/virtio-9p.c:2905: error: 'UTIME_OMIT' undeclared (first use in this function)

v4:
- Use tv_now.tv_usec
- Rebased on latest qemu.git
v3:
- Use better alternative handling for UTIME_NOW/OMIT
- Move qemu_utimensat() to cutils.c
V2:
- Introduce qemu_utimensat()

Quoted 3 lines
Quoted 6 lines

Hi Hidetoshi,

I think the idea of the patch is good, but please move qemu_utimensat() to oslib-posix.c and provide a wrapper for oslib-win32.c. It is emulation for a system library function, so it doesn't belong in cutils.c, but rather in the oslib group.

Unfortunately one fact is that I'm not familiar with win32 codes so I don't have any idea how the wrapper for win32 will be...
If someone could kindly tell me about the win32 part, I could update this patch to v5, but even though I have no test environment for the new part :-<

Could we wait an incremental patch on this v4?
Can somebody help me? Volunteers?

Thanks,
H.Seto

#3 lore raw
Quoted 8 lines · Hidetoshi Seto
Quoted 6 lines · Jes Sorensen

Hi Hidetoshi,

I think the idea of the patch is good, but please move qemu_utimensat() to oslib-posix.c and provide a wrapper for oslib-win32.c. It is emulation for a system library function, so it doesn't belong in cutils.c, but rather in the oslib group.

Quoted 7 lines

Unfortunately one fact is that I'm not familiar with win32 codes so I don't have any idea how the wrapper for win32 will be...
If someone could kindly tell me about the win32 part, I could update this patch to v5, but even though I have no test environment for the new part :-<

Could we wait an incremental patch on this v4?
Can somebody help me? Volunteers?

Hi Hidetoshi,

I don't actually know much about win32 myself, the only thing I do is to try and cross-compile for it using mingw32 to make sure the build doesn't break. One option is to leave it open, or put in a dummy wrapper which asserts in the win32 part of the code, so that someone who is interested in win32 can fix it up.

That should be pretty easy to do, and I think thats a fine starting point.

Cheers,
Jes

#4 lore raw
In reply to Hidetoshi Seto

Hello,

Am Donnerstag 18 November 2010 01:41:39 schrieb Hidetoshi Seto:

cutils.c fail: · line 381

Quoted 7 lines

This patch introduce a fallback mechanism for old systems that do not support utimensat(). This fix build failure with following warnings:

cutils.c +4 -0
+#ifdef CONFIG_UTIMENSAT
+    return utimensat(dirfd, path, times, flags);
+#else
+    /* Fallback: use utimes() instead of utimensat() */

Since we also had a problem with utimestat() some time ago with Samba
<http://lists.samba.org/archive/samba-technical/2010-November/074613.html>
I'd like to comment on that:

Your have to be careful about compile-time-detection and runtime-detection: If you later run your utimestat()-enabled binary on an older kernel not supporting that syscall, you get -1 as the return-value and errno=ENOSYS. So even if you detected utimesatat() during compile-time, please always provide a fallback for run-time.
This is less important for people compiling there own version of kvm, but is essential for Linux distributions, since people often run newer kvm versions on older kernels.

Sincerely
Philipp Hahn

Signature · 4 lines
Philipp Hahn           Open Source Software Engineer      [email protected]   
Univention GmbH        Linux for Your Business        fon: +49 421 22 232- 0
Mary-Somerville-Str.1  28359 Bremen                   fax: +49 421 22 232-99
                                                    http://www.univention.de
#5 lore raw
Quoted 15 lines · Philipp Hahn

Hello,

Am Donnerstag 18 November 2010 01:41:39 schrieb Hidetoshi Seto:

cutils.c fail: · line 381

Quoted 7 lines

This patch introduce a fallback mechanism for old systems that do not support utimensat(). This fix build failure with following warnings:

cutils.c +4 -0
+#ifdef CONFIG_UTIMENSAT
+    return utimensat(dirfd, path, times, flags);
+#else
+    /* Fallback: use utimes() instead of utimensat() */

Since we also had a problem with utimestat() some time ago with Samba
<http://lists.samba.org/archive/samba-technical/2010-November/074613.html>
I'd like to comment on that:

Quoted 8 lines

Your have to be careful about compile-time-detection and runtime-detection: If you later run your utimestat()-enabled binary on an older kernel not supporting that syscall, you get -1 as the return-value and errno=ENOSYS. So even if you detected utimesatat() during compile-time, please always provide a fallback for run-time.
This is less important for people compiling there own version of kvm, but is essential for Linux distributions, since people often run newer kvm versions on older kernels.

Hum, you have a good point.

Well, then I'll change it like:

-#ifdef CONFIG_UTIMENSAT
- return utimensat(dirfd, path, times, flags);
-#else
+ {
+ int ret = utimensat(dirfd, path, times, flags);
+ if (ret != -1 || errno != ENOSYS) {
+ return ret;
+ }
+ }

Thanks,
H.Seto

#6 lore raw

Hello,

Am Donnerstag 18 November 2010 10:05:59 schrieb Hidetoshi Seto:

Quoted 2 lines
Quoted 2 lines

Your have to be careful about compile-time-detection and runtime-detection:

...

Review

Quoted 9 lines
(quoted diff) +6 -3
-#ifdef CONFIG_UTIMENSAT
-    return utimensat(dirfd, path, times, flags);
-#else
+    {
+        int ret = utimensat(dirfd, path, times, flags);
+        if (ret != -1 || errno != ENOSYS) {
+            return ret;
+        }
+    }

You might still want to do the compile-time-check, something like:

#ifdef CONFIG_UTIMENSAT
    {
        int ret = utimensat(dirfd, path, times, flags);
        if (ret != -1 || errno != ENOSYS) {
            return ret;
        }
    }

#endif
// fallback

Sincerely
Philipp Hahn

Signature · 4 lines
Philipp Hahn           Open Source Software Engineer      [email protected]   
Univention GmbH        Linux for Your Business        fon: +49 421 22 232- 0
Mary-Somerville-Str.1  28359 Bremen                   fax: +49 421 22 232-99
                                                    http://www.univention.de