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 <mohan@in.ibm.com>
Signed-off-by: Aneesh Kumar K.V <aneesh.kumar@linux.vnet.ibm.com>
This commit is contained in:
M. Mohan Kumar 2011-12-14 13:58:47 +05:30 committed by Aneesh Kumar K.V
parent a2d8f1beb1
commit 84a87cc4cc
7 changed files with 159 additions and 17 deletions

View file

@ -57,6 +57,8 @@ typedef struct extended_ops {
*/
#define V9FS_SM_NONE 0x00000010
#define V9FS_RDONLY 0x00000020
#define V9FS_PROXY_SOCK_FD 0x00000040
#define V9FS_PROXY_SOCK_NAME 0x00000080
#define V9FS_SEC_MASK 0x0000001C

View file

@ -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 <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));
}
@ -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

View file

@ -46,6 +46,10 @@ Path to export for proxy filesystem driver
Use given file descriptor as socket descriptor for communicating with
qemu proxy fs drier. Usually a helper like libvirt will create
socketpair and pass one of the fds as parameter to -f|--fd
@item -s|--socket socket-file
Creates named socket file for communicating with qemu proxy fs driver
@item -u|--uid uid -g|--gid gid
uid:gid combination to give access to named socket file
@item -n|--nodaemon
Run as a normal program. By default program will run in daemon mode
@end table