xenconsole: Ensure exclusive access to console using locks

If more than one instance of xenconsole is run against the same DOMID
then each instance will only get some data. This change ensures
exclusive access to the console by obtaining an exclusive lock on
<XEN_LOCK_DIR>/xenconsole.<DOMID>.

The locking strategy used is based on
tools/libxl/libxl_internal.c:libxl__lock_domain_userdata().

Signed-off-by: Martin Lucina <martin@lucina.net>
Cc: Ian Jackson <ian.jackson@eu.citrix.com>
Cc: Stefano Stabellini <stefano.stabellini@eu.citrix.com>
Cc: Ian Campbell <ian.campbell@citrix.com>
Cc: Wei Liu <wei.liu2@citrix.com>
Acked-by: Ian Jackson <ian.jackson@eu.citrix.com>
This commit is contained in:
Martin Lucina authored and Ian Campbell committed 2015-07-27 14:54:55 +01:00
1 parent 20960a081a
commit 8398ec706f
3 files changed
+61 -1

No files matched your search

+1
View File
@@ -100,6 +100,7 @@ tools/blktap2/vhd/vhd-update
tools/blktap2/vhd/vhd-util
tools/console/xenconsole
tools/console/xenconsoled
tools/console/client/_paths.h
tools/debugger/gdb/gdb-6.2.1-linux-i386-xen/*
tools/debugger/gdb/gdb-6.2.1/*
tools/debugger/gdb/gdb-6.2.1.tar.bz2
+5 -1
View File
@@ -21,6 +21,7 @@ all: $(BIN)
clean:
$(RM) *.a *.so *.o *.rpm $(BIN) $(DEPS)
$(RM) client/*.o daemon/*.o
$(RM) client/_paths.h
.PHONY: distclean
distclean: clean
@@ -28,9 +29,12 @@ distclean: clean
xenconsoled: $(patsubst %.c,%.o,$(wildcard daemon/*.c))
$(CC) $(LDFLAGS) $^ -o $@ $(LDLIBS) $(LDLIBS_xenconsoled) $(APPEND_LDFLAGS)
xenconsole: $(patsubst %.c,%.o,$(wildcard client/*.c))
xenconsole: client/_paths.h $(patsubst %.c,%.o,$(wildcard client/*.c))
$(CC) $(LDFLAGS) $^ -o $@ $(LDLIBS) $(LDLIBS_xenconsole) $(APPEND_LDFLAGS)
genpath-target = $(call buildmakevars2header,client/_paths.h)
$(eval $(genpath-target))
.PHONY: install
install: $(BIN)
$(INSTALL_DIR) $(DESTDIR)/$(sbindir)
+55
View File
@@ -18,7 +18,9 @@
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
\*/
#include <sys/file.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <sys/socket.h>
#include <sys/un.h>
#include <stdio.h>
@@ -40,10 +42,13 @@
#include <xenstore.h>
#include "xenctrl.h"
#include "_paths.h"
#define ESCAPE_CHARACTER 0x1d
static volatile sig_atomic_t received_signal = 0;
static char lockfile[sizeof (XEN_LOCK_DIR "/xenconsole.") + 8] = { 0 };
static int lockfd = -1;
static void sighandler(int signum)
{
@@ -267,6 +272,53 @@ static void restore_term_stdin(void)
restore_term(STDIN_FILENO, &stdin_old_attr);
}
/* The following locking strategy is based on that from
* libxl__domain_userdata_lock(), with the difference that we want to fail if we
* cannot acquire the lock rather than wait indefinitely.
*/
static void console_lock(int domid)
{
struct stat stab, fstab;
int fd;
snprintf(lockfile, sizeof lockfile, "%s%d", XEN_LOCK_DIR "/xenconsole.", domid);
while (true) {
fd = open(lockfile, O_RDWR | O_CREAT, S_IRUSR | S_IWUSR);
if (fd < 0)
err(errno, "Could not open %s", lockfile);
while (flock(fd, LOCK_EX | LOCK_NB)) {
if (errno == EINTR)
continue;
else
err(errno, "Could not lock %s", lockfile);
}
if (fstat(fd, &fstab))
err(errno, "Could not fstat %s", lockfile);
if (stat(lockfile, &stab)) {
if (errno != ENOENT)
err(errno, "Could not stat %s", lockfile);
} else {
if (stab.st_dev == fstab.st_dev && stab.st_ino == fstab.st_ino)
break;
}
close(fd);
}
lockfd = fd;
return;
}
static void console_unlock(void)
{
if (lockfile[0] && lockfd != -1) {
unlink(lockfile);
close(lockfd);
}
}
int main(int argc, char **argv)
{
struct termios attr;
@@ -382,6 +434,9 @@ int main(int argc, char **argv)
exit(EINVAL);
}
console_lock(domid);
atexit(console_unlock);
/* Set a watch on this domain's console pty */
if (!xs_watch(xs, path, ""))
err(errno, "Can't set watch for console pty");
Reference in new issue
Block a user
Blocking a user prevents them from interacting with repositories, such as opening or commenting on pull requests or issues. Learn more about blocking a user.