From 726e40673efdab1ea82cb12468f4c3f20701a7d6 Mon Sep 17 00:00:00 2001 From: Lon Hohberger Date: Wed, 13 Jan 2010 09:26:32 -0500 Subject: [PATCH] Static map support and permissions reporting Signed-off-by: Lon Hohberger --- client/main.c | 23 ++++++++++++++++++++--- client/mcast.c | 6 +----- client/serial.c | 4 +--- include/xvm.h | 5 +++++ server/Makefile.in | 2 +- server/libvirt.c | 2 +- server/mcast.c | 2 +- server/serial.c | 40 ++++++++++++++++++++++++++++++---------- server/static_map.c | 3 +++ server/virt-sockets.c | 20 ++++++++++++++++++++ server/virt-sockets.h | 3 +++ 11 files changed, 86 insertions(+), 24 deletions(-) diff --git a/client/main.c b/client/main.c index f975b80..956020a 100644 --- a/client/main.c +++ b/client/main.c @@ -52,6 +52,7 @@ main(int argc, char **argv) { fence_virt_args_t args; const char *my_options; + int ret = 0; args_init(&args); if (!strcmp(basename(argv[0]), "fence_xvm")) { @@ -110,12 +111,28 @@ main(int argc, char **argv) switch(args.mode) { case MODE_MULTICAST: - return mcast_fence_virt(&args); + ret = mcast_fence_virt(&args); + break; case MODE_SERIAL: - return serial_fence_virt(&args); + ret = serial_fence_virt(&args); + break; default: + return 1; + } + + switch(ret) { + case 0: + break; + case RESP_FAIL: + printf("Operation failed\n"); + break; + case RESP_PERM: + printf("Permission denied\n"); + break; + default: + printf("Unknown response (%d)\n", ret); break; } - return 1; + return ret; } diff --git a/client/mcast.c b/client/mcast.c index 2e602ce..4aaa4e4 100644 --- a/client/mcast.c +++ b/client/mcast.c @@ -163,17 +163,13 @@ tcp_exchange(int fd, fence_auth_type_t auth, void *key, if (_read_retry(fd, &ret, 1, &tv) < 0) ret = 1; - if (ret == (char)253) /* hostlist */ { + if (ret == (char)RESP_HOSTLIST) /* hostlist */ { do_read_hostlist(fd, timeout); ret = 0; } close(fd); - if (ret == 0) - printf("Remote: Operation was successful\n"); - else - printf("Remote: Operation failed\n"); return ret; } diff --git a/client/serial.c b/client/serial.c index 1a8bbf2..866a945 100644 --- a/client/serial.c +++ b/client/serial.c @@ -265,7 +265,7 @@ serial_fence_virt(fence_virt_args_t *args) if (resp.magic != SERIAL_MAGIC) return -1; ret = resp.response; - if (resp.response == 253) /* hostlist */ { + if (resp.response == RESP_HOSTLIST) /* hostlist */ { /* ok read hostlist */ do_read_hostlist(fd, args->timeout); ret = 0; @@ -273,7 +273,5 @@ serial_fence_virt(fence_virt_args_t *args) close(fd); - printf("Response: %d\n", ret); - return ret; } diff --git a/include/xvm.h b/include/xvm.h index a46f030..835f961 100644 --- a/include/xvm.h +++ b/include/xvm.h @@ -111,5 +111,10 @@ typedef struct __attribute__((packed)) _serial_fense_resp { uint8_t response; } serial_resp_t; +#define RESP_SUCCESS 0 +#define RESP_FAIL 1 +#define RESP_PERM 2 +#define RESP_HOSTLIST 253 + #endif diff --git a/server/Makefile.in b/server/Makefile.in index b954935..40c7cf8 100644 --- a/server/Makefile.in +++ b/server/Makefile.in @@ -43,7 +43,7 @@ libvirt_qpid_so_SOURCES = uuid-test.c libvirt_qpid_cxx_so_SOURCES = libvirt-qpid.cpp multicast_so_SOURCES = mcast.c history.c checkpoint_so_SOURCES = virt.c vm_states.c history.c checkpoint.c cpg.c -serial_so_SOURCES = virt-serial.c uuid-test.c virt-sockets.c serial.c history.c +serial_so_SOURCES = virt-serial.c static_map.c virt-sockets.c serial.c history.c ################################ diff --git a/server/libvirt.c b/server/libvirt.c index 3415ed6..a4ada37 100644 --- a/server/libvirt.c +++ b/server/libvirt.c @@ -278,7 +278,7 @@ libvirt_status(const char *vm_name, void *priv) if (!vdp || ((virDomainGetInfo(vdp, &vdi) == 0) && (vdi.state == VIR_DOMAIN_SHUTOFF))) { - ret = 1; + ret = RESP_OFF; } if (vdp) diff --git a/server/mcast.c b/server/mcast.c index da689f4..d5e98c1 100644 --- a/server/mcast.c +++ b/server/mcast.c @@ -202,7 +202,7 @@ static int mcast_hostlist_begin(int fd) { struct timeval tv; - char val = (char)253; + char val = (char)RESP_HOSTLIST; tv.tv_sec = 1; tv.tv_usec = 0; diff --git a/server/serial.c b/server/serial.c index d890d39..70938a4 100644 --- a/server/serial.c +++ b/server/serial.c @@ -72,6 +72,7 @@ typedef struct _serial_info { void *priv; char *uri; history_info_t *history; + void *maps; } serial_info; @@ -102,7 +103,7 @@ check_history(void *a, void *b) { static int serial_hostlist(const char *vm_name, const char *vm_uuid, - int state, void *priv) + int state, void *priv) { struct serial_hostlist_arg *arg = (struct serial_hostlist_arg *)priv; host_state_t hinfo; @@ -116,7 +117,6 @@ serial_hostlist(const char *vm_name, const char *vm_uuid, tv.tv_sec = 1; tv.tv_usec = 0; - printf("%d\n", arg->fd); ret = _write_retry(arg->fd, &hinfo, sizeof(hinfo), &tv); if (ret == sizeof(hinfo)) return 0; @@ -131,7 +131,7 @@ serial_hostlist_begin(int fd) serial_resp_t resp; resp.magic = SERIAL_MAGIC; - resp.response = 253; + resp.response = RESP_HOSTLIST; tv.tv_sec = 1; tv.tv_usec = 0; @@ -146,7 +146,7 @@ serial_hostlist_end(int fd) struct timeval tv; int ret; - printf("Sending terminator packet\n"); + //printf("Sending terminator packet\n"); memset(&hinfo, 0, sizeof(hinfo)); @@ -160,9 +160,9 @@ serial_hostlist_end(int fd) static int -do_fence_request(int fd, serial_req_t *req, serial_info *info) +do_fence_request(int fd, const char *src, serial_req_t *req, serial_info *info) { - char response = 1; + char response = RESP_FAIL; struct serial_hostlist_arg arg; serial_resp_t resp; @@ -173,14 +173,26 @@ do_fence_request(int fd, serial_req_t *req, serial_info *info) response = info->cb->null((char *)req->domain, info->priv); break; case FENCE_ON: + if (static_map_check(info->maps, src, req->domain) == 0) { + response = RESP_PERM; + break; + } response = info->cb->on((char *)req->domain, req->seqno, info->priv); break; case FENCE_OFF: + if (static_map_check(info->maps, src, req->domain) == 0) { + response = RESP_PERM; + break; + } response = info->cb->off((char *)req->domain, req->seqno, info->priv); break; case FENCE_REBOOT: + if (static_map_check(info->maps, src, req->domain) == 0) { + response = RESP_PERM; + break; + } response = info->cb->reboot((char *)req->domain, req->seqno, info->priv); break; @@ -219,6 +231,7 @@ do_fence_request(int fd, serial_req_t *req, serial_info *info) static int serial_dispatch(listener_context_t c, struct timeval *timeout) { + char src_domain[MAX_DOMAINNAME_LENGTH]; serial_info *info; serial_req_t data; fd_set rfds; @@ -250,8 +263,9 @@ serial_dispatch(listener_context_t c, struct timeval *timeout) if (FD_ISSET(x, &rfds)) { tv.tv_sec = 1; tv.tv_usec = 0; + ret = _read_retry(x, &data, sizeof(data), &tv); - printf("the read...%d\n",ret); + if (ret != sizeof(data)) { if (--n) continue; @@ -263,15 +277,19 @@ serial_dispatch(listener_context_t c, struct timeval *timeout) } } - printf("Sock %d Request %d seqno %d domain %s\n", x, data.request, data.seqno, - data.domain); + src_domain[0] = 0; + domain_sock_name(x, src_domain, sizeof(src_domain)); + + printf("Sock %d Request %d seqno %d src %s target %s\n", x, + data.request, data.seqno, src_domain, data.domain); if (history_check(info->history, &data) == 1) { printf("We just did this request; dropping packet\n"); return 0; } - do_fence_request(x, &data, info); + do_fence_request(x, src_domain[0] == 0 ? NULL : src_domain, + &data, info); return 0; } @@ -322,6 +340,8 @@ serial_init(listener_context_t *c, const fence_callbacks_t *cb, return -1; } + static_map_init(config, &info->maps); + info->magic = SERIAL_PLUG_MAGIC; info->history = history_init(check_history, 10, sizeof(fence_req_t)); *c = (listener_context_t)info; diff --git a/server/static_map.c b/server/static_map.c index 496db55..ee336be 100644 --- a/server/static_map.c +++ b/server/static_map.c @@ -48,6 +48,9 @@ static_map_check(void *info, const char *value1, const char *value2) struct perm_entry *left, *tmp; int x, y; + if (!info) + return 1; /* no maps == wide open */ + list_for(&groups, group, x) { left = NULL; diff --git a/server/virt-sockets.c b/server/virt-sockets.c index bca2df6..88abb83 100644 --- a/server/virt-sockets.c +++ b/server/virt-sockets.c @@ -126,3 +126,23 @@ domain_sock_fdset(fd_set *fds, int *max) return x; } + +int +domain_sock_name(int fd, char *outbuf, size_t buflen) +{ + struct socket_list *node = NULL; + int ret = 1, x = 0; + + pthread_mutex_lock(&sock_list_mutex); + list_for(&socks, node, x) { + if (node->socket_fd == fd) { + snprintf(outbuf, buflen, "%s", node->domain_name); + ret = 0; + break; + } + } + pthread_mutex_unlock(&sock_list_mutex); + + return ret; +} + diff --git a/server/virt-sockets.h b/server/virt-sockets.h index 82bed8f..fcfa473 100644 --- a/server/virt-sockets.h +++ b/server/virt-sockets.h @@ -7,4 +7,7 @@ int domain_sock_setup(const char *domain, const char *socket_path); int domain_sock_close(const char *domain); int domain_sock_fdset(fd_set *set, int *max); +/* Find the domain name associated with a FD */ +int domain_sock_name(int fd, char *outbuf, size_t buflen); + #endif