Bug #2216: Multiseat support. From various Debian and Ubuntu patches by

Aivils Stoss, Andreas Schuldei, Branden Robinson, and Daniel Stone.
This commit is contained in:
Adam Jackson 2005-07-04 18:41:04 +00:00
parent ba011dc77d
commit 7586ac6ede
8 changed files with 236 additions and 94 deletions

View File

@ -1657,6 +1657,20 @@ checkCoreInputDevices(serverLayoutPtr servlayoutp, Bool implicitLayout)
return TRUE;
}
typedef enum {
LAYOUT_ISOLATEDEVICE,
LAYOUT_SINGLECARD
} LayoutValues;
static OptionInfoRec LayoutOptions[] = {
{ LAYOUT_ISOLATEDEVICE, "IsolateDevice", OPTV_STRING,
{0}, FALSE },
{ LAYOUT_SINGLECARD, "SingleCard", OPTV_BOOLEAN,
{0}, FALSE },
{ -1, NULL, OPTV_NONE,
{0}, FALSE },
};
/*
* figure out which layout is active, which screens are used in that layout,
* which drivers and monitors are used in these screens
@ -2540,6 +2554,8 @@ xf86HandleConfigFile(Bool autoconfig)
const char *filename;
char *searchpath;
MessageType from = X_DEFAULT;
char *scanptr;
Bool singlecard = 0;
if (!autoconfig) {
if (getuid() == 0)
@ -2613,6 +2629,29 @@ xf86HandleConfigFile(Bool autoconfig)
}
}
xf86ProcessOptions(-1, xf86ConfigLayout.options, LayoutOptions);
if ((scanptr = xf86GetOptValString(LayoutOptions, LAYOUT_ISOLATEDEVICE))) {
; /* IsolateDevice specified; overrides SingleCard */
} else {
xf86GetOptValBool(LayoutOptions, LAYOUT_SINGLECARD, &singlecard);
if (singlecard)
scanptr = xf86ConfigLayout.screens->screen->device->busID;
}
if (scanptr) {
int bus, device, func, stroffset = 0;
if (strncmp(scanptr, "PCI:", 4) != 0) {
xf86Msg(X_WARNING, "Bus types other than PCI not yet isolable.\n"
"\tIgnoring IsolateDevice option.\n");
} else if (sscanf(scanptr, "PCI:%d:%d:%d", &bus, &device, &func) == 3) {
xf86IsolateDevice.bus = bus;
xf86IsolateDevice.device = device;
xf86IsolateDevice.func = func;
xf86Msg(X_INFO,
"Isolating PCI bus \"%d:%d:%d\"\n", bus, device, func);
}
}
/* Now process everything else */
if (!configFiles(xf86configptr->conf_files) ||

View File

@ -243,6 +243,7 @@ Bool xf86MiscModInDevAllowNonLocal = FALSE;
RootWinPropPtr *xf86RegisteredPropertiesTable = NULL;
Bool xf86inSuspend = FALSE;
Bool xorgHWAccess = FALSE;
PciBusId xf86IsolateDevice;
#ifdef DLOPEN_HACK
/*

View File

@ -1681,6 +1681,25 @@ ddxProcessArgument(int argc, char **argv, int i)
xf86AllowMouseOpenFail = TRUE;
return 1;
}
if (!strcmp(argv[i], "-isolateDevice"))
{
int bus, device, func;
if (++i >= argc)
return 0;
if (strncmp(argv[i], "PCI:", 4)) {
ErrorF("Bus types other than PCI not yet isolable\n");
return 0;
}
if (sscanf(argv[i], "PCI:%d:%d:%d", &bus, &device, &func) == 3) {
xf86IsolateDevice.bus = bus;
xf86IsolateDevice.device = device;
xf86IsolateDevice.func = func;
return 2;
} else {
ErrorF("Invalid isolated device specifiation\n");
return 0;
}
}
/* OS-specific processing */
return xf86ProcessArgument(argc, argv, i);
}
@ -1745,6 +1764,7 @@ ddxUseMsg()
#endif
ErrorF("-bestRefresh choose modes with the best refresh rate\n");
ErrorF("-ignoreABI make module ABI mismatches non-fatal\n");
ErrorF("-isolateDevice bus_id restrict device resets to bus_id (PCI only)\n");
ErrorF("-version show the server version\n");
/* OS-specific usage */
xf86UseMsg();

View File

@ -80,6 +80,7 @@ extern Bool xf86BestRefresh;
extern Gamma xf86Gamma;
extern char *xf86ServerName;
extern Bool xf86ShowUnresolved;
extern PciBusId xf86IsolateDevice;
/* Other parameters */

View File

@ -194,7 +194,10 @@ FindPCIVideoInfo(void)
int i = 0, j, k;
int num = 0;
pciVideoPtr info;
int DoIsolateDeviceCheck = 0;
if (xf86IsolateDevice.bus || xf86IsolateDevice.device || xf86IsolateDevice.func)
DoIsolateDeviceCheck = 1;
pcrpp = xf86PciInfo = xf86scanpci(0);
getPciClassFlags(pcrpp);
@ -216,7 +219,11 @@ FindPCIVideoInfo(void)
subclass = pcrp->pci_sub_class;
}
if (PCIINFOCLASSES(baseclass, subclass)) {
if (PCIINFOCLASSES(baseclass, subclass) &&
(DoIsolateDeviceCheck ?
(xf86IsolateDevice.bus == pcrp->busnum &&
xf86IsolateDevice.device == pcrp->devnum &&
xf86IsolateDevice.func == pcrp->funcnum) : 1)) {
num++;
xf86PciVideoInfo = xnfrealloc(xf86PciVideoInfo,
sizeof(pciVideoPtr) * (num + 1));

View File

@ -1,4 +1,4 @@
.\" $XdotOrg$
.\" $XdotOrg: xc/programs/Xserver/hw/xfree86/Xorg.man,v 1.2 2004/04/23 19:20:02 eich Exp $
.TH __xservername__ __appmansuffix__ __vendorversion__
.SH NAME
__xservername__ - X11R6 X server
@ -257,6 +257,19 @@ that the server does not have. When this option is specified, mismatches
like this are downgraded from fatal errors to warnings. This option
should be used with care.
.TP 8
.B \-isolateDevice \fIbus\-id\fP
Restrict device resets to the device at
.IR bus\-id .
The
.I bus\-id
string has the form
.IB bustype : bus : device : function
(e.g., \(oqPCI:1:0:0\(cq).
At present, only isolation of PCI devices is supported; i.e., this option
is ignored if
.I bustype
is anything other than \(oqPCI\(cq.
.TP 8
.B \-keeptty
Prevent the server from detaching its initial controlling terminal.
This option is only useful when debugging the server. Not all platforms

View File

@ -1,4 +1,4 @@
.\" $XdotOrg: xc/programs/Xserver/hw/xfree86/xorg.conf.man,v 1.2 2004/04/23 19:20:02 eich Exp $
.\" $XdotOrg: xc/programs/Xserver/hw/xfree86/xorg.conf.man,v 1.3 2005/03/22 21:30:43 ajax Exp $
.\" shorthand for double quote that works everywhere.
.ds q \N'34'
.TH __xconfigfile__ __filemansuffix__ __vendorversion__
@ -375,7 +375,7 @@ where
is the display number for the __xservername__ server.
..
.SH SERVERFLAGS SECTION
The
In addition to options specific to this section (described below), the
.B ServerFlags
section is used to specify some global
__xservername__ server options. All of the entries in this section are
@ -1779,12 +1779,30 @@ and core keyboard devices respectively.
.RE
.TP 7
.B Options
Any option permitted in the
In addition to the following, any option permitted in the
.B ServerFlags
section may also be specified here. When the same option appears in both
places, the value given here overrides the one given in the
.B ServerFlags
section.
.TP 7
.BI "Option \*qIsolateDevice\*q \*q" bus\-id \*q
Restrict device resets to the specified
.IR bus\-id .
See the
.B BusID
option (described in
.BR "DEVICE SECTION" ,
above) for the format of the
.I bus\-id
parameter. This option overrides
.BR SingleCard ,
if specified. At present, only PCI devices can be isolated in this manner.
.TP 7
.BI "Option \*qSingleCard\*q \*q" boolean \*q
As
.BR IsolateDevice ,
except that the bus ID of the first device in the layout is used.
.PP
Here is an example of a
.B ServerLayout

View File

@ -50,6 +50,8 @@ char *fb_dev_name;
static Bool KeepTty = FALSE;
static int VTnum = -1;
static Bool VTSwitch = TRUE;
static Bool ShareVTs = FALSE;
static int activeVT = -1;
static int vtPermSave[4];
@ -125,26 +127,37 @@ xf86OpenConsole(void)
"xf86OpenConsole: Cannot open /dev/tty0 (%s)\n",
strerror(errno));
if ((ioctl(fd, VT_OPENQRY, &xf86Info.vtno) < 0) ||
(xf86Info.vtno == -1)) {
FatalError("xf86OpenConsole: Cannot find a free VT: %s\n",
strerror(errno));
}
if (ShareVTs)
{
if (ioctl(fd, VT_GETSTATE, &vts) == 0)
xf86Info.vtno = vts.v_active;
else
FatalError("xf86OpenConsole: Cannot find the current"
" VT (%s)\n", strerror(errno));
} else {
if ((ioctl(fd, VT_OPENQRY, &xf86Info.vtno) < 0) ||
(xf86Info.vtno == -1))
FatalError("xf86OpenConsole: Cannot find a free VT: %s\n",
strerror(errno));
}
close(fd);
}
#ifdef USE_DEV_FB
fb_dev_name=getenv("FRAMEBUFFER");
if (!fb_dev_name)
fb_dev_name="/dev/fb0current";
if (!ShareVTs)
{
fb_dev_name=getenv("FRAMEBUFFER");
if (!fb_dev_name)
fb_dev_name="/dev/fb0current";
if ((fbfd = open(fb_dev_name, O_RDONLY)) < 0)
FatalError("xf86OpenConsole: Cannot open %s (%s)\n",
fb_dev_name, strerror(errno));
if ((fbfd = open(fb_dev_name, O_RDONLY)) < 0)
FatalError("xf86OpenConsole: Cannot open %s (%s)\n",
fb_dev_name, strerror(errno));
if (ioctl(fbfd, FBIOGET_VSCREENINFO, &var) < 0)
FatalError("xf86OpenConsole: Unable to get screen info %s\n",
strerror(errno));
if (ioctl(fbfd, FBIOGET_VSCREENINFO, &var) < 0)
FatalError("xf86OpenConsole: Unable to get screen info %s\n",
strerror(errno));
}
#endif
xf86Msg(from, "using VT number %d\n\n", xf86Info.vtno);
@ -180,28 +193,31 @@ xf86OpenConsole(void)
FatalError("xf86OpenConsole: Cannot open virtual console"
" %d (%s)\n", xf86Info.vtno, strerror(errno));
/*
* Grab the vt ownership before we overwrite it.
* Hard coded /dev/tty0 into this function as well for below.
*/
if (!saveVtPerms())
xf86Msg(X_WARNING,
"xf86OpenConsole: Could not save ownership of VT\n");
if (!ShareVTs)
{
/*
* Grab the vt ownership before we overwrite it.
* Hard coded /dev/tty0 into this function as well for below.
*/
if (!saveVtPerms())
xf86Msg(X_WARNING,
"xf86OpenConsole: Could not save ownership of VT\n");
/* change ownership of the vt */
if (chown(vtname, getuid(), getgid()) < 0)
xf86Msg(X_WARNING,"xf86OpenConsole: chown %s failed: %s\n",
vtname, strerror(errno));
/* change ownership of the vt */
if (chown(vtname, getuid(), getgid()) < 0)
xf86Msg(X_WARNING,"xf86OpenConsole: chown %s failed: %s\n",
vtname, strerror(errno));
/*
* the current VT device we're running on is not "console", we want
* to grab all consoles too
*
* Why is this needed??
*/
if (chown("/dev/tty0", getuid(), getgid()) < 0)
xf86Msg(X_WARNING,"xf86OpenConsole: chown /dev/tty0 failed: %s\n",
strerror(errno));
/*
* the current VT device we're running on is not "console", we want
* to grab all consoles too
*
* Why is this needed??
*/
if (chown("/dev/tty0", getuid(), getgid()) < 0)
xf86Msg(X_WARNING,"xf86OpenConsole: chown /dev/tty0 failed: %s\n",
strerror(errno));
}
/*
* Linux doesn't switch to an active vt after the last close of a vt,
@ -224,61 +240,69 @@ xf86OpenConsole(void)
}
}
#endif
if (!ShareVTs)
{
#if defined(DO_OS_FONTRESTORE)
lnx_savefont();
lnx_savefont();
#endif
/*
* now get the VT
*/
if (ioctl(xf86Info.consoleFd, VT_ACTIVATE, xf86Info.vtno) < 0)
xf86Msg(X_WARNING, "xf86OpenConsole: VT_ACTIVATE failed: %s\n",
/*
* now get the VT
*/
if (ioctl(xf86Info.consoleFd, VT_ACTIVATE, xf86Info.vtno) < 0)
xf86Msg(X_WARNING, "xf86OpenConsole: VT_ACTIVATE failed: %s\n",
strerror(errno));
if (ioctl(xf86Info.consoleFd, VT_WAITACTIVE, xf86Info.vtno) < 0)
xf86Msg(X_WARNING, "xf86OpenConsole: VT_WAITACTIVE failed: %s\n",
strerror(errno));
if (ioctl(xf86Info.consoleFd, VT_WAITACTIVE, xf86Info.vtno) < 0)
xf86Msg(X_WARNING, "xf86OpenConsole: VT_WAITACTIVE failed: %s\n",
if (ioctl(xf86Info.consoleFd, VT_GETMODE, &VT) < 0)
FatalError("xf86OpenConsole: VT_GETMODE failed %s\n",
strerror(errno));
signal(SIGUSR1, xf86VTRequest);
VT.mode = VT_PROCESS;
VT.relsig = SIGUSR1;
VT.acqsig = SIGUSR1;
if (ioctl(xf86Info.consoleFd, VT_SETMODE, &VT) < 0)
FatalError("xf86OpenConsole: VT_SETMODE VT_PROCESS failed: %s\n",
strerror(errno));
if (ioctl(xf86Info.consoleFd, VT_GETMODE, &VT) < 0)
FatalError("xf86OpenConsole: VT_GETMODE failed %s\n",
strerror(errno));
signal(SIGUSR1, xf86VTRequest);
VT.mode = VT_PROCESS;
VT.relsig = SIGUSR1;
VT.acqsig = SIGUSR1;
if (ioctl(xf86Info.consoleFd, VT_SETMODE, &VT) < 0)
FatalError("xf86OpenConsole: VT_SETMODE VT_PROCESS failed: %s\n",
strerror(errno));
if (ioctl(xf86Info.consoleFd, KDSETMODE, KD_GRAPHICS) < 0)
FatalError("xf86OpenConsole: KDSETMODE KD_GRAPHICS failed %s\n",
strerror(errno));
if (ioctl(xf86Info.consoleFd, KDSETMODE, KD_GRAPHICS) < 0)
FatalError("xf86OpenConsole: KDSETMODE KD_GRAPHICS failed %s\n",
strerror(errno));
/* we really should have a InitOSInputDevices() function instead
* of Init?$#*&Device(). So I just place it here */
/* we really should have a InitOSInputDevices() function instead
* of Init?$#*&Device(). So I just place it here */
#ifdef USE_DEV_FB
/* copy info to new console */
var.yoffset=0;
var.xoffset=0;
if (ioctl(fbfd, FBIOPUT_VSCREENINFO, &var))
FatalError("Unable to set screen info\n");
close(fbfd);
/* copy info to new console */
var.yoffset=0;
var.xoffset=0;
if (ioctl(fbfd, FBIOPUT_VSCREENINFO, &var))
FatalError("Unable to set screen info\n");
close(fbfd);
#endif
} else { /* ShareVTs */
close(xf86Info.consoleFd);
}
} else { /* serverGeneration != 1 */
/*
* now get the VT
*/
if (ioctl(xf86Info.consoleFd, VT_ACTIVATE, xf86Info.vtno) < 0)
xf86Msg(X_WARNING, "xf86OpenConsole: VT_ACTIVATE failed %s\n",
strerror(errno));
if (!ShareVTs && VTSwitch)
{
/*
* now get the VT
*/
if (ioctl(xf86Info.consoleFd, VT_ACTIVATE, xf86Info.vtno) < 0)
xf86Msg(X_WARNING, "xf86OpenConsole: VT_ACTIVATE failed %s\n",
strerror(errno));
}
if (ioctl(xf86Info.consoleFd, VT_WAITACTIVE, xf86Info.vtno) < 0)
xf86Msg(X_WARNING, "xf86OpenConsole: VT_WAITACTIVE failed %s\n",
strerror(errno));
if (ioctl(xf86Info.consoleFd, VT_WAITACTIVE, xf86Info.vtno) < 0)
xf86Msg(X_WARNING, "xf86OpenConsole: VT_WAITACTIVE failed %s\n",
strerror(errno));
}
return;
}
@ -290,7 +314,11 @@ xf86CloseConsole()
#if defined(DO_OS_FONTRESTORE)
struct vt_stat vts;
int vtno = -1;
#endif
if (ShareVTs) return;
#if defined(DO_OS_FONTRESTORE)
if (ioctl(xf86Info.consoleFd, VT_GETSTATE, &vts) < 0)
xf86Msg(X_WARNING, "xf86CloseConsole: VT_GETSTATE failed: %s\n",
strerror(errno));
@ -314,21 +342,24 @@ xf86CloseConsole()
strerror(errno));
}
/*
* Perform a switch back to the active VT when we were started
*/
if (activeVT >= 0) {
if (ioctl(xf86Info.consoleFd, VT_ACTIVATE, activeVT) < 0)
xf86Msg(X_WARNING, "xf86CloseConsole: VT_ACTIVATE failed: %s\n",
strerror(errno));
activeVT = -1;
}
if (VTSwitch)
{
/*
* Perform a switch back to the active VT when we were started
*/
if (activeVT >= 0) {
if (ioctl(xf86Info.consoleFd, VT_ACTIVATE, activeVT) < 0)
xf86Msg(X_WARNING, "xf86CloseConsole: VT_ACTIVATE failed: %s\n",
strerror(errno));
activeVT = -1;
}
#if defined(DO_OS_FONTRESTORE)
if (xf86Info.vtno == vtno) /* check if we are active */
lnx_restorefont();
lnx_freefontdata();
if (xf86Info.vtno == vtno) /* check if we are active */
lnx_restorefont();
lnx_freefontdata();
#endif
}
close(xf86Info.consoleFd); /* make the vt-manager happy */
restoreVtPerms(); /* restore the permissions */
@ -348,6 +379,16 @@ xf86ProcessArgument(int argc, char *argv[], int i)
KeepTty = TRUE;
return(1);
}
if (!strcmp(argv[i], "-novtswitch"))
{
VTSwitch = FALSE;
return(1);
}
if (!strcmp(argv[i], "-sharevts"))
{
ShareVTs = TRUE;
return(1);
}
if ((argv[i][0] == 'v') && (argv[i][1] == 't'))
{
if (sscanf(argv[i], "vt%2d", &VTnum) == 0)
@ -367,5 +408,7 @@ xf86UseMsg()
ErrorF("vtXX use the specified VT number\n");
ErrorF("-keeptty ");
ErrorF("don't detach controlling tty (for debugging only)\n");
ErrorF("-novtswitch don't immediately switch to new VT\n");
ErrorF("-sharevts share VTs with another X server\n");
return;
}