From: "M. Mohan Kumar" <mohan@in.ibm.com>
To: qemu-devel@nongnu.org, aneesh.kumar@linux.vnet.ibm.com
Cc: "M. Mohan Kumar" <mohan@in.ibm.com>
Subject: [Qemu-devel] [PATCH 05/13] hw/9pfs: Add support to use named socket for proxy FS
Date: Tue, 1 Nov 2011 02:23:24 +0530 [thread overview]
Message-ID: <1320094412-19091-6-git-send-email-mohan@in.ibm.com> (raw)
In-Reply-To: <1320094412-19091-1-git-send-email-mohan@in.ibm.com>
From: "M. Mohan Kumar" <mohan@in.ibm.com>
Add option to use named socket for communicating between proxy helper
and qemu proxy FS. Access to socket can be given by using command line
options -u and -g.
Signed-off-by: M. Mohan Kumar <mohan@in.ibm.com>
---
hw/9pfs/virtfs-proxy-helper.c | 89 ++++++++++++++++++++++++++++++++++++++--
hw/9pfs/virtio-9p-proxy.c | 56 ++++++++++++++++++++++---
qemu-config.c | 6 +++
vl.c | 6 ++-
4 files changed, 144 insertions(+), 13 deletions(-)
diff --git a/hw/9pfs/virtfs-proxy-helper.c b/hw/9pfs/virtfs-proxy-helper.c
index 8e82ca7..9d925e0 100644
--- a/hw/9pfs/virtfs-proxy-helper.c
+++ b/hw/9pfs/virtfs-proxy-helper.c
@@ -26,6 +26,9 @@ static struct option helper_opts[] = {
{"fd", required_argument, NULL, 'f'},
{"path", required_argument, NULL, 'p'},
{"nodaemon", no_argument, NULL, 'n'},
+ {"socket", required_argument, NULL, 's'},
+ {"uid", required_argument, NULL, 'u'},
+ {"gid", required_argument, NULL, 'g'},
};
int is_daemon;
@@ -153,11 +156,61 @@ static int read_request(int sockfd, struct iovec *iovec)
} while (1);
}
+/* create unix domain socket and return the descriptor */
+static int proxy_socket(const char *path, uid_t uid, gid_t gid)
+{
+ int sock, client;
+ struct sockaddr_un proxy, qemu;
+ socklen_t size;
+
+ /* requested socket already exists, refuse to start */
+ if (!access(path, F_OK)) {
+ do_log(LOG_CRIT, "socket already exists\n");
+ return -1;
+ }
+
+ sock = socket(AF_UNIX, SOCK_STREAM, 0);
+ if (sock < 0) {
+ do_perror("socket");
+ return -1;
+ }
+
+ /* mask other part of mode bits */
+ umask(7);
+
+ proxy.sun_family = AF_UNIX;
+ strcpy(proxy.sun_path, path);
+ if (bind(sock, (struct sockaddr *)&proxy,
+ sizeof(struct sockaddr_un)) < 0) {
+ do_perror("bind");
+ return -1;
+ }
+ if (chown(proxy.sun_path, uid, gid) < 0) {
+ do_perror("chown");
+ return -1;
+ }
+ if (listen(sock, 1) < 0) {
+ do_perror("listen");
+ return -1;
+ }
+
+ client = accept(sock, (struct sockaddr *)&qemu, &size);
+ if (client < 0) {
+ do_perror("accept");
+ return -1;
+ }
+ return client;
+}
+
static void usage(char *prog)
{
fprintf(stderr, "usage: %s\n"
" -p|--path <path> 9p path to export\n"
" {-f|--fd <socket-descriptor>} socket file descriptor to be used\n"
+ " {-s|--socket <socketname> socket file used for communication\n"
+ " \t-u|--uid <uid> -g|--gid <gid>} - uid:gid combination to give "
+ " access to this socket\n"
+ " \tNote: -s & -f can not be used together\n"
" [-n|--nodaemon] Run as a normal program\n",
basename(prog));
}
@@ -184,16 +237,20 @@ error:
int main(int argc, char **argv)
{
int sock;
+ char sock_name[PATH_MAX];
char rpath[PATH_MAX];
struct stat stbuf;
int c, option_index;
+ uid_t own_u;
+ gid_t own_g;
is_daemon = 1;
- rpath[0] = '\0';
+ sock_name[0] = rpath[0] = '\0';
sock = -1;
+ own_u = own_g = -1;
while (1) {
option_index = 0;
- c = getopt_long(argc, argv, "p:nh?f:", helper_opts,
+ c = getopt_long(argc, argv, "p:nh?f:s:u:g:", helper_opts,
&option_index);
if (c == -1) {
break;
@@ -205,9 +262,18 @@ int main(int argc, char **argv)
case 'n':
is_daemon = 0;
break;
- case 'f':
+ case 'f':
sock = atoi(optarg);
break;
+ case 's':
+ strcpy(sock_name, optarg);
+ break;
+ case 'u':
+ own_u = atoi(optarg);
+ break;
+ case 'g':
+ own_g = atoi(optarg);
+ break;
case '?':
case 'h':
default:
@@ -218,8 +284,15 @@ int main(int argc, char **argv)
}
/* Parameter validation */
- if (sock == -1 || rpath[0] == '\0') {
- fprintf(stderr, "socket descriptor or path not specified\n");
+ if ((sock_name[0] == '\0' && sock == -1) || rpath[0] == '\0') {
+ fprintf(stderr, "socket, socket descriptor or path not specified\n");
+ usage(argv[0]);
+ return -1;
+ }
+
+ if (*sock_name && (own_u == -1 || own_g == -1)) {
+ fprintf(stderr, "owner uid:gid not specified, ");
+ fprintf(stderr, "owner specifies who can access the socket file\n");
usage(argv[0]);
return -1;
}
@@ -243,6 +316,12 @@ int main(int argc, char **argv)
}
do_log(LOG_INFO, "Started");
+ if (*sock_name) {
+ sock = proxy_socket(sock_name, own_u, own_g);
+ if (sock < 0) {
+ goto error;
+ }
+ }
if (chroot(rpath) < 0) {
do_perror("chroot");
diff --git a/hw/9pfs/virtio-9p-proxy.c b/hw/9pfs/virtio-9p-proxy.c
index c682e36..0ec686c 100644
--- a/hw/9pfs/virtio-9p-proxy.c
+++ b/hw/9pfs/virtio-9p-proxy.c
@@ -16,6 +16,10 @@
#include "fsdev/qemu-fsdev.h"
#include "proxy.h"
+/* FS specific flags */
+#define V9FS_PROXY_SOCK_FD (1 << 9)
+#define V9FS_PROXY_SOCK_NAME (1 << 10)
+
typedef struct V9fsProxy {
int sockfd;
QemuMutex mutex;
@@ -301,15 +305,49 @@ static int proxy_unlinkat(FsContext *ctx, V9fsPath *dir,
return ret;
}
+static int connect_namedsocket(const char *path)
+{
+ int sockfd, size;
+ struct sockaddr_un helper;
+
+ sockfd = socket(AF_UNIX, SOCK_STREAM, 0);
+ if (sockfd < 0) {
+ fprintf(stderr, "socket %s\n", strerror(errno));
+ return -1;
+ }
+ strcpy(helper.sun_path, path);
+ helper.sun_family = AF_UNIX;
+ size = strlen(helper.sun_path) + sizeof(helper.sun_family);
+ if (connect(sockfd, (struct sockaddr *)&helper, size) < 0) {
+ fprintf(stderr, "socket error\n");
+ return -1;
+ }
+
+ /* remove the socket for security reasons */
+ unlink(path);
+ return sockfd;
+}
+
static int proxy_parse_opts(QemuOpts *opts, struct FsDriverEntry *fs)
{
+ const char *socket = qemu_opt_get(opts, "socket");
const char *sock_fd = qemu_opt_get(opts, "sock_fd");
- if (sock_fd) {
- fprintf(stderr, "sock_fd option not specified\n");
+ if (!socket && !sock_fd) {
+ fprintf(stderr, "socket and sock_fd none of the option specified\n");
+ return -1;
+ }
+ if (socket && sock_fd) {
+ fprintf(stderr, "Both socket and sock_fd options specified\n");
return -1;
}
- fs->path = g_strdup(sock_fd);
+ if (socket) {
+ fs->path = g_strdup(socket);
+ fs->export_flags = V9FS_PROXY_SOCK_NAME;
+ } else {
+ fs->path = g_strdup(sock_fd);
+ fs->export_flags = V9FS_PROXY_SOCK_FD;
+ }
return 0;
}
@@ -318,10 +356,14 @@ static int proxy_init(FsContext *ctx)
V9fsProxy *proxy = g_malloc(sizeof(V9fsProxy));
int sock_id;
- sock_id = atoi(ctx->fs_root);
- if (sock_id < 0) {
- fprintf(stderr, "socket descriptor not initialized\n");
- return -1;
+ if (ctx->export_flags & V9FS_PROXY_SOCK_NAME) {
+ sock_id = connect_namedsocket(ctx->fs_root);
+ } else {
+ sock_id = atoi(ctx->fs_root);
+ if (sock_id < 0) {
+ fprintf(stderr, "socket descriptor not initialized\n");
+ return -1;
+ }
}
g_free(ctx->fs_root);
diff --git a/qemu-config.c b/qemu-config.c
index 5e63c14..6203e7b 100644
--- a/qemu-config.c
+++ b/qemu-config.c
@@ -187,6 +187,9 @@ QemuOptsList qemu_fsdev_opts = {
}, {
.name = "sock_fd",
.type = QEMU_OPT_NUMBER,
+ }, {
+ .name = "socket",
+ .type = QEMU_OPT_STRING,
},
{ /*End of list */ }
@@ -219,6 +222,9 @@ QemuOptsList qemu_virtfs_opts = {
}, {
.name = "sock_fd",
.type = QEMU_OPT_NUMBER,
+ }, {
+ .name = "socket",
+ .type = QEMU_OPT_STRING,
},
{ /*End of list */ }
diff --git a/vl.c b/vl.c
index 5a5ab7f..8fbf481 100644
--- a/vl.c
+++ b/vl.c
@@ -2663,7 +2663,7 @@ int main(int argc, char **argv, char **envp)
case QEMU_OPTION_virtfs: {
QemuOpts *fsdev;
QemuOpts *device;
- const char *writeout, *sock_fd;
+ const char *writeout, *sock_fd, *socket;
olist = qemu_find_opts("virtfs");
if (!olist) {
@@ -2703,6 +2703,10 @@ int main(int argc, char **argv, char **envp)
qemu_opt_set(fsdev, "path", qemu_opt_get(opts, "path"));
qemu_opt_set(fsdev, "security_model",
qemu_opt_get(opts, "security_model"));
+ socket = qemu_opt_get(opts, "socket");
+ if (socket) {
+ qemu_opt_set(fsdev, "socket", socket);
+ }
sock_fd = qemu_opt_get(opts, "sock_fd");
if (sock_fd) {
qemu_opt_set(fsdev, "sock_fd", sock_fd);
--
1.7.6
next prev parent reply other threads:[~2011-10-31 20:54 UTC|newest]
Thread overview: 13+ messages / expand[flat|nested] mbox.gz Atom feed top
2011-10-31 20:53 [Qemu-devel] [PATCH 00/13] Proxy FS driver for VirtFS M. Mohan Kumar
2011-10-31 20:53 ` [Qemu-devel] [PATCH 01/13] hw/9pfs: Move opt validation to FsDriver callback M. Mohan Kumar
2011-10-31 20:53 ` [Qemu-devel] [PATCH 02/13] hw/9pfs: Move pdu_marshal/unmarshal code to a seperate file M. Mohan Kumar
2011-10-31 20:53 ` [Qemu-devel] [PATCH 03/13] hw/9pfs: Add new proxy filesystem driver M. Mohan Kumar
2011-10-31 20:53 ` [Qemu-devel] [PATCH 04/13] hw/9pfs: File system helper process for qemu 9p proxy FS M. Mohan Kumar
2011-10-31 20:53 ` M. Mohan Kumar [this message]
2011-10-31 20:53 ` [Qemu-devel] [PATCH 06/13] hw/9pfs: Open and create files M. Mohan Kumar
2011-10-31 20:53 ` [Qemu-devel] [PATCH 07/13] hw/9pfs: Create other filesystem objects M. Mohan Kumar
2011-10-31 20:53 ` [Qemu-devel] [PATCH 08/13] hw/9pfs: Add stat/readlink/statfs for proxy FS M. Mohan Kumar
2011-10-31 20:53 ` [Qemu-devel] [PATCH 09/13] hw/9pfs: File ownership and others M. Mohan Kumar
2011-10-31 20:53 ` [Qemu-devel] [PATCH 10/13] hw/9pfs: xattr interfaces in proxy filesystem driver M. Mohan Kumar
2011-10-31 20:53 ` [Qemu-devel] [PATCH 12/13] hw/9pfs: Documentation changes related to proxy fs M. Mohan Kumar
2011-10-31 20:53 ` [Qemu-devel] [PATCH 13/13] hw/9pfs: man page for proxy helper M. Mohan Kumar
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=1320094412-19091-6-git-send-email-mohan@in.ibm.com \
--to=mohan@in.ibm.com \
--cc=aneesh.kumar@linux.vnet.ibm.com \
--cc=qemu-devel@nongnu.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.