SUA Deprecated in Windows 8

The POSIX subsystem in Windows is headed for a slow death march, again. Not many people realize that Windows NT had a POSIX subsystem from the beginning which was enriched along the way to run a fork of OpenBSD called Interix. Originally the POSIX subsystem was bundled with Windows NT 3.1 and was a barely useful POSIX.1 environment to meet DoD purchasing requirements. Later, it was removed from the Windows core distribution, re-implemented by an ISV and called OpenNT and then Interix. Interix was acquired by Microsoft and sold for a while before being distributed free of charge. Later it was bundled with Services for UNIX 3.0 and 3.5 before being re-integrated into the Windows distribution as the Subsystem for UNIX-based Applications (SUA). At one time Interix actually ran Hotmail during the migration from a FreeBSD to NT backend.

After passing back to the Windows team and being rebranded SUA, Interix languished. The original developers scattered to other projects like Monad/PowerShell, left Microsoft or were never hired by Microsoft when it acquired the technology in the first place. Interix is maintained by a very small team at Microsoft India and these guys are focused primarily on just keeping it working through kernel updates. In practice, the quality of the product has been in decline. At one point, for example, it shipped with most of the .so shared libraries corrupt so that nothing that linked to those libraries would run. The toolkit that makes SUA useful lags many, many months behind the release of a new version of Windows and Microsoft required “premium” client SKUs (ultimate or enterprise) or server SKUs to access the technology which greatly limited its distribution. It is generally as unloved by the powers that be as anything could be, except perhaps IronPython and IronRuby which have already been killed.

The Windows 8 M3 developer preview shows that the other shoe has dropped:

Subsystem for UNIX-based Applications [DEPRECATED]

Subsystem for UNIX-based Applications (SUA) is a source-compatibility subsystem for compiling and running custom UNIX-based applications and scripts on a computer running Windows operating system. WARNING: SUA is deprecated starting with this release and will be completely removed from the next release. You should begin planning now to employ alternate methods for any applications, code, or usage that depends on this feature.

sua-deprecated

One obvious reason to deprecate SUA is that loading the extra subsystem makes Windows take a noticeably longer time to boot. The architecture is very much at odds with the instant boot goals of Windows 8.

There have been a number of developments over the last few years that makes Interix less compelling. Things like fast-CGI on IIS and an official PHP port from Zend, lots of dynamic languages with native Windows runtimes, mySQL and PostgreSQL for WIndows, C libraries like pthreads for win32 and msys which have made Interix less necessary. For perl-heads there is even Strawberry Perl which is supposed to be a lot more CPAN friendly than ActiveState perl. I think Hyper-V and PowerShell are the real strategic replacements for SUA, though. PowerShell integrates with COM and WMI and fits the object nature of Windows better than any POSIX shell could. Hyper-V lets you actually run your UNIX app on Windows on a supported Linux platform which I’m sure smells much less MacGuyver to CIOs than this weird Interix POSIX on Windows thing that nobody ever heard of.

From the time that Hyper-V officially supported RHEL with hast enlightened drivers and Jeffrey Snover decided that the new shell and automation for Windows would be based on .NET and pivoted to build Monad/PowerShell rather than putting KSH on every Windows machine, Interix’s days were numbered. Now it’s official, Interix will be gone from the world about 11 years when Windows 8 reaches end-of-life but if you are smart you will jump ship now because this product will have the minimum life support staff imaginable.

Advertisement

WONTFIX: select(2) in SUA 5.2 ignores timeout

With Windows Server 2003 R2, Microsoft incorporated Services for UNIX as a set of operating system components. The POSIX subsystem, Interix, is called the Subsystem for UNIX Applications (SUA) in Windows Server 2003 R2 and later.

Interix is the internal name of the Windows Posix Subsystem (PSXSS) that is based on OpenBSD and operates as an independent sister subsystem with the Windows subsystem (aka CSRSS or Client/Server Runtime Subsystem).

With the first version of SUA, aka Interix 5.2, Microsoft added a bunch of new UNIX APIs. Unfortunately the broke some things that were previously working in the previous edition which was called Interix 3.5 (aka Services for UNIX 3.5).

For example, select(2) is broken in SUA 5.2. It completely ignores the timeouts provided as arguments and returns immediately.

From the POSIX specification:

If the timeout parameter is not a null pointer, it specifies a maximum interval to wait for the selection to complete. If the specified time interval expires without any requested operation becoming ready, the function shall return. If the timeout parameter is a null pointer, then the call to pselect() or select() shall block indefinitely until at least one descriptor meets the specified criteria. To effect a poll, the timeout parameter should not be a null pointer, and should point to a zero-valued timespec structure.

Here is a little test program. What should happen is that select() should block for 10 seconds every time through the loop.

#include <stdio.h>;
#include <sys/time.h>

int main()
{
	printf("Testing select(2). Each pass through the loop should pause 10 seconds.\n\n");

	struct timeval time, pause;
	pause.tv_sec  = 10;
	pause.tv_usec = 0;
	int i;

	for( i=0; i&lt;10; i++ )
	{
		//insert a 10 second pause on every loop to test select().		
		gettimeofday(&amp;time, 0);
		printf(";Current time: %d\n", time.tv_sec);
		time.tv_sec += 10L;
		printf("Add 10 seconds: %d... And pause by calling select(2).\n", time.tv_sec);
		(void) select(0, 0, 0, 0, &pause);
	}
	return 0;
}

What actually happens is select() returns immediately.

% uname -svrm
Interix 5.2 SP-9.0.3790.4125 EM64T
% gcc selecttest.c -o selecttest 
% ./selecttest 
Testing select(2). Each pass through the loop should pause 10 seconds. 

Current time: 1142434664 
Add 10 seconds: 1142434674... And pause by calling select(2). 
Current time: 1142434664 
Add 10 seconds: 1142434674... And pause by calling select(2). 
Current time: 1142434664 
Add 10 seconds: 1142434674... And pause by calling select(2). 
Current time: 1142434664 
Add 10 seconds: 1142434674... And pause by calling select(2). 
Current time: 1142434664 
Add 10 seconds: 1142434674... And pause by calling select(2). 
Current time: 1142434664 
Add 10 seconds: 1142434674... And pause by calling select(2). 
Current time: 1142434664 
Add 10 seconds: 1142434674... And pause by calling select(2). 
Current time: 1142434664 
Add 10 seconds: 1142434674... And pause by calling select(2). 
Current time: 1142434664 
Add 10 seconds: 1142434674... And pause by calling select(2). 
Current time: 1142434664 
Add 10 seconds: 1142434674... And pause by calling select(2).
% 

The test run above should have taken 100 seconds but it actually completes in less than 1 second. This is a problem because many UNIX applications will use select() as a timing mechanism. Some will use select() as a timer even if they aren’t doing IO.

There is good news and bad news.

The bad news is that MSFT told me that the won’t fix this issue. Their official guidance is to use sleep(2) and usleep(2) to control timeouts in Interix 52.

The good news is that select(2) works properly on Interix 6.0 with Windows Vista and Windows Server 2008.

%d bloggers like this: