On Tue, Jan 18, 2011 at 6:26 AM, M. Mohan Kumar <mo...@in.ibm.com> wrote: > Add both server and client side interfaces to create special files > (directory, device nodes, links and symbolic links) > > Signed-off-by: M. Mohan Kumar <mo...@in.ibm.com> > --- > hw/9pfs/virtio-9p-chroot.c | 84 ++++++++++++++++++++++++++- > hw/9pfs/virtio-9p-chroot.h | 2 + > hw/9pfs/virtio-9p-local.c | 141 > ++++++++++++++++++++++++++++++++++---------- > 3 files changed, 195 insertions(+), 32 deletions(-) > > diff --git a/hw/9pfs/virtio-9p-chroot.c b/hw/9pfs/virtio-9p-chroot.c > index e7f85e2..92a4917 100644 > --- a/hw/9pfs/virtio-9p-chroot.c > +++ b/hw/9pfs/virtio-9p-chroot.c > @@ -193,6 +193,29 @@ static void chroot_do_open(V9fsFileObjectRequest > *request, FdInfo *fd_info) > } > } > > +int v9fs_create_special(FsContext *fs_ctx, > + V9fsFileObjectRequest *request, int *error) > +{ > + int retval; > + > + pthread_mutex_lock(&fs_ctx->chroot_mutex); > + > + *error = 0; > + v9fs_write_request(fs_ctx->chroot_socket, request); > + retval = qemu_read_full(fs_ctx->chroot_socket, error, sizeof(*error)); > + if (retval != sizeof(*error)) { > + error_report("reading from socket failed: %s", strerror(errno)); > + exit(1); > + } > + > + pthread_mutex_unlock(&fs_ctx->chroot_mutex); > + if (*error) { > + return -1; > + } else { > + return 0; > + } > +} > + > /* > * Helper routine to create a file and return the file descriptor and > * error status in FdInfo structure. > @@ -229,6 +252,56 @@ unset_uid: > setfsuid(cur_uid); > } > > +/* > + * Create directory, symbolic link, link, device node and regular files > + * Similar to create, but it does not return the fd of created object > + * Returns 0 on success, returns errno on failure > + */ > +static int chroot_do_create_special(V9fsFileObjectRequest *request) > +{ > + int cur_uid, cur_gid;
uid_t cur_uid; gid_t cur_gid; > + int retval, error; > + > + cur_uid = geteuid(); > + cur_gid = getegid(); > + > + if (setfsuid(request->data.uid) < 0) { > + return errno; > + } > + if (setfsgid(request->data.gid) < 0) { > + error = errno; > + goto unset_uid; > + } > + > + switch (request->data.type) { > + case T_MKDIR: > + retval = mkdir(request->path.path, request->data.mode); > + break; > + case T_SYMLINK: > + retval = symlink(request->path.old_path, request->path.path); > + break; > + case T_LINK: > + retval = link(request->path.old_path, request->path.path); > + break; > + default: > + retval = mknod(request->path.path, request->data.mode, > + request->data.dev); > + break; > + } > + > + if (retval < 0) { > + error = errno; > + } else { > + error = 0; > + } > + > + setfsgid(cur_gid); > +unset_uid: > + setfsuid(cur_uid); > + > + return error; > +} > + > static int chroot_daemonize(int chroot_sock) > { > sigset_t sigset; > @@ -263,7 +336,7 @@ static int chroot_daemonize(int chroot_sock) > */ > int v9fs_chroot(FsContext *fs_ctx) > { > - int fd_pair[2], pid, chroot_sock, error; > + int fd_pair[2], pid, chroot_sock, error, retval; > V9fsFileObjectRequest request; > FdInfo fd_info; > > @@ -318,6 +391,15 @@ int v9fs_chroot(FsContext *fs_ctx) > error = -2; > } > break; > + case T_MKDIR: > + case T_SYMLINK: > + case T_LINK: > + case T_MKNOD: > + retval = chroot_do_create_special(&request); > + if (qemu_write_full(chroot_sock, &retval, sizeof(retval)) < 0) { > + error = -2; > + } > + break; > default: > break; > } > diff --git a/hw/9pfs/virtio-9p-chroot.h b/hw/9pfs/virtio-9p-chroot.h > index f5a2ca0..9a0ba88 100644 > --- a/hw/9pfs/virtio-9p-chroot.h > +++ b/hw/9pfs/virtio-9p-chroot.h > @@ -36,5 +36,7 @@ typedef struct V9fsFileObjectRequest > > int v9fs_chroot(FsContext *fs_ctx); > int v9fs_request(FsContext *fs_ctx, V9fsFileObjectRequest *or, int *error); > +int v9fs_create_special(FsContext *fs_ctx, > + V9fsFileObjectRequest *request, int *error); > > #endif /* _QEMU_VIRTIO_9P_CHROOT_H */ > diff --git a/hw/9pfs/virtio-9p-local.c b/hw/9pfs/virtio-9p-local.c > index 7f39b40..08fd67f 100644 > --- a/hw/9pfs/virtio-9p-local.c > +++ b/hw/9pfs/virtio-9p-local.c > @@ -69,6 +69,78 @@ static int __create(FsContext *fs_ctx, const char *path, > int flags, > return fd; > } > > +static int __mknod(FsContext *fs_ctx, const char *path, FsCred *credp) underscores