Patchwork [V12,14/15] hw/9pfs: readlink in chroot environment

login
register
mail settings
Submitter Mohan Kumar M
Date Sept. 5, 2011, 4:18 p.m.
Message ID <1315239516-4451-15-git-send-email-mohan@in.ibm.com>
Download mbox | patch
Permalink /patch/113408/
State New
Headers show

Comments

Mohan Kumar M - Sept. 5, 2011, 4:18 p.m.
Signed-off-by: M. Mohan Kumar <mohan@in.ibm.com>
---
 hw/9pfs/virtio-9p-chroot-worker.c |   17 ++++++++++++++---
 hw/9pfs/virtio-9p-chroot.h        |    1 +
 hw/9pfs/virtio-9p-local.c         |   14 ++++++++++++--
 3 files changed, 27 insertions(+), 5 deletions(-)

Patch

diff --git a/hw/9pfs/virtio-9p-chroot-worker.c b/hw/9pfs/virtio-9p-chroot-worker.c
index a2f6dcd..3040d98 100644
--- a/hw/9pfs/virtio-9p-chroot-worker.c
+++ b/hw/9pfs/virtio-9p-chroot-worker.c
@@ -367,9 +367,6 @@  int v9fs_chroot(FsContext *fs_ctx)
         case T_CHOWN:
             retval = chroot_do_chown(&request);
             break;
-        default:
-            retval = -1;
-            break;
         case T_LSTAT:
             buff = g_malloc(request.data.size);
             retval = lstat(request.path.path, (struct stat *)buff);
@@ -377,6 +374,19 @@  int v9fs_chroot(FsContext *fs_ctx)
                 retval = -errno;
             }
             break;
+        case T_READLINK:
+            buff = g_malloc(request.data.size);
+            retval = readlink(request.path.path, buff, request.data.size);
+            if (retval < 0) {
+                retval = -errno;
+            } else {
+                buff[retval] = '\0';
+                retval = 0;
+            }
+            break;
+        default:
+            retval = -1;
+            break;
         }
 
         /* Send the results */
@@ -394,6 +404,7 @@  int v9fs_chroot(FsContext *fs_ctx)
             chroot_sendfd(chroot_sock, retval, valid_fd);
             break;
         case T_LSTAT:
+        case T_READLINK:
             chroot_sendspecial(chroot_sock, buff, request.data.size, retval);
             g_free(buff);
             break;
diff --git a/hw/9pfs/virtio-9p-chroot.h b/hw/9pfs/virtio-9p-chroot.h
index 9ed3f4d..ebf04b5 100644
--- a/hw/9pfs/virtio-9p-chroot.h
+++ b/hw/9pfs/virtio-9p-chroot.h
@@ -14,6 +14,7 @@ 
 #define T_CHMOD     9
 #define T_CHOWN     10
 #define T_LSTAT     11
+#define T_READLINK  12
 
 #define V9FS_FD_VALID INT_MAX
 
diff --git a/hw/9pfs/virtio-9p-local.c b/hw/9pfs/virtio-9p-local.c
index 13c93a5..ffef8a2 100644
--- a/hw/9pfs/virtio-9p-local.c
+++ b/hw/9pfs/virtio-9p-local.c
@@ -99,6 +99,12 @@  static int passthrough_special_request(FsContext *fs_ctx, const char *path,
     request.data.size = size;
     if (type == T_LSTAT) {
         retval = v9fs_special(fs_ctx, &request, buff, size);
+    } else if (type == T_READLINK) {
+        retval = v9fs_special(fs_ctx, &request, buff, size);
+        /* readlink needs to return the number of bytes placed in buff */
+        if (retval >= 0) {
+            retval = strlen(buff);
+        }
     } else {
             return -1;
     }
@@ -206,6 +212,11 @@  static ssize_t local_readlink(FsContext *fs_ctx, V9fsPath *fs_path,
     char buffer[PATH_MAX];
     char *path = fs_path->data;
 
+    if (fs_ctx->fs_sm == SM_PASSTHROUGH) {
+        return passthrough_special_request(fs_ctx, path, buf, bufsz,
+                        T_READLINK);
+    }
+
     if (fs_ctx->fs_sm == SM_MAPPED) {
         int fd;
         fd = open(rpath(fs_ctx, path, buffer), O_RDONLY);
@@ -217,8 +228,7 @@  static ssize_t local_readlink(FsContext *fs_ctx, V9fsPath *fs_path,
         } while (tsize == -1 && errno == EINTR);
         close(fd);
         return tsize;
-    } else if ((fs_ctx->fs_sm == SM_PASSTHROUGH) ||
-               (fs_ctx->fs_sm == SM_NONE)) {
+    } else if (fs_ctx->fs_sm == SM_NONE) {
         tsize = readlink(rpath(fs_ctx, path, buffer), buf, bufsz);
     }
     return tsize;