From 84a87cc4cc77f9e6829e20726f00646afe12deed Mon Sep 17 00:00:00 2001 From: "M. Mohan Kumar" Date: Wed, 14 Dec 2011 13:58:47 +0530 Subject: hw/9pfs: Add support to use named socket for proxy FS 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 Signed-off-by: Aneesh Kumar K.V --- fsdev/virtfs-proxy-helper.c | 86 +++++++++++++++++++++++++++++++++++++++++++-- 1 file changed, 83 insertions(+), 3 deletions(-) (limited to 'fsdev/virtfs-proxy-helper.c') diff --git a/fsdev/virtfs-proxy-helper.c b/fsdev/virtfs-proxy-helper.c index 52d748d93a..7f8def5b5d 100644 --- a/fsdev/virtfs-proxy-helper.c +++ b/fsdev/virtfs-proxy-helper.c @@ -57,6 +57,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'}, }; static bool is_daemon; @@ -695,11 +698,61 @@ err_out: return ret; } +/* 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 9p path to export\n" " {-f|--fd } socket file descriptor to be used\n" + " {-s|--socket socket file used for communication\n" + " \t-u|--uid -g|--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)); } @@ -939,7 +992,10 @@ err_out: int main(int argc, char **argv) { int sock; + uid_t own_u; + gid_t own_g; char *rpath = NULL; + char *sock_name = NULL; struct stat stbuf; int c, option_index; #ifdef FS_IOC_GETVERSION @@ -949,9 +1005,10 @@ int main(int argc, char **argv) is_daemon = true; 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; @@ -966,6 +1023,15 @@ int main(int argc, char **argv) case 'f': sock = atoi(optarg); break; + case 's': + sock_name = strdup(optarg); + break; + case 'u': + own_u = atoi(optarg); + break; + case 'g': + own_g = atoi(optarg); + break; case '?': case 'h': default: @@ -975,8 +1041,16 @@ int main(int argc, char **argv) } /* Parameter validation */ - if (sock == -1 || rpath == NULL) { - fprintf(stderr, "socket descriptor or path not specified\n"); + if ((sock_name == NULL && sock == -1) || rpath == NULL) { + 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 uid:gid specifies who can access the socket file\n"); usage(argv[0]); exit(EXIT_FAILURE); } @@ -1001,6 +1075,12 @@ int main(int argc, char **argv) } do_log(LOG_INFO, "Started\n"); + if (*sock_name) { + sock = proxy_socket(sock_name, own_u, own_g); + if (sock < 0) { + goto error; + } + } get_version = false; #ifdef FS_IOC_GETVERSION -- cgit v1.2.1