mirror of
https://github.com/xen-project/xen.git
synced 2026-10-28 02:01:24 +01:00
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:
1 parent
20960a081a
commit
8398ec706f
3 files changed
+61
-1
No files matched your search
@@ -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
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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");
|
||||
|
||||