<?xml version='1.0' encoding='utf-8' ?>
<!--  If you are running a bot please visit this policy page outlining rules you must respect. https://www.livejournal.com/bots/  -->
<rss version='2.0'  xmlns:lj='http://www.livejournal.org/rss/lj/1.0/' xmlns:media='http://search.yahoo.com/mrss/' xmlns:atom10='http://www.w3.org/2005/Atom'>
<channel>
  <title>Ulrich Drepper</title>
  <link>https://udrepper.livejournal.com/</link>
  <description>Ulrich Drepper - LiveJournal.com</description>
  <lastBuildDate>Wed, 18 Dec 2013 04:34:12 GMT</lastBuildDate>
  <generator>LiveJournal / LiveJournal.com</generator>
  <lj:journal>udrepper</lj:journal>
  <lj:journalid>4163110</lj:journalid>
  <lj:journaltype>personal</lj:journaltype>
  <item>
  <guid isPermaLink='true'>https://udrepper.livejournal.com/22429.html</guid>
  <pubDate>Wed, 18 Dec 2013 04:34:12 GMT</pubDate>
  <title>Closing</title>
  <author>udrepper</author>
  <link>https://udrepper.livejournal.com/22429.html</link>
  <description>I will not use this blog anymore.  Instead I am hosting one on my own server with a much simpler (self-written) platform.  Use the RSS file &lt;a href=&quot;http://www.akkadia.org/drepper/blog/rss&quot; target=&quot;_blank&quot; rel=&quot;nofollow&quot;&gt;here&lt;/a&gt;.</description>
  <comments>https://udrepper.livejournal.com/22429.html?view=comments#comments</comments>
  <lj:security>public</lj:security>
  <lj:reply-count>0</lj:reply-count>
  </item>
  <item>
  <guid isPermaLink='true'>https://udrepper.livejournal.com/22255.html</guid>
  <pubDate>Fri, 01 Jun 2012 01:49:56 GMT</pubDate>
  <author>udrepper</author>
  <link>https://udrepper.livejournal.com/22255.html</link>
  <description>&lt;p&gt;The original plan was to have some program sI wrote to be added to the procps or util-linux package but the maintainers haven&apos;t been responsive.  Therefore here they are in a package on their own.&lt;/p&gt;

&lt;p&gt;I call the package &lt;q&gt;putils&lt;/q&gt; (available from my &lt;a href=&quot;http://www.akkadia.org/drepper/putils.src.rpm&quot; target=&quot;_blank&quot; rel=&quot;nofollow&quot;&gt;private server&lt;/a&gt;) and the following programs are available so far:&lt;/p&gt;

&lt;dl&gt;

&lt;dt&gt;&lt;b&gt;plimit&lt;/b&gt;&lt;dt&gt;&lt;dd&gt;Show or set the limits of a process&lt;/dd&gt;

&lt;dt&gt;&lt;b&gt;pfiles&lt;/b&gt;&lt;/dt&gt;&lt;dd&gt;Show information about the files open inside a process&lt;/dd&gt;

&lt;/dl&gt;

&lt;p&gt;These programs will be familiar to Solaris users.  There are likely a few more programs to follow.&lt;/p&gt;&lt;/dt&gt;&lt;/dt&gt;</description>
  <comments>https://udrepper.livejournal.com/22255.html?view=comments#comments</comments>
  <lj:security>public</lj:security>
  <lj:reply-count>0</lj:reply-count>
  </item>
  <item>
  <guid isPermaLink='true'>https://udrepper.livejournal.com/21828.html</guid>
  <pubDate>Thu, 31 May 2012 23:51:09 GMT</pubDate>
  <title>pagein</title>
  <author>udrepper</author>
  <link>https://udrepper.livejournal.com/21828.html</link>
  <description>&lt;p&gt;I&apos;ve updated the pagein tool to compile with a recent valgrind version.  The tarball also contains a .spec file.  I had to work around a bug in valgrind in Fedora 16 and 17.&lt;/p&gt;&lt;br /&gt;&lt;br /&gt;&lt;a href=&quot;http://www/akkadia.org/drepper/valgrind-pagein-1.1.tar.bz2&quot; target=&quot;_blank&quot; rel=&quot;nofollow&quot;&gt;The tarball&lt;/a&gt;</description>
  <comments>https://udrepper.livejournal.com/21828.html?view=comments#comments</comments>
  <lj:security>public</lj:security>
  <lj:reply-count>0</lj:reply-count>
  </item>
  <item>
  <guid isPermaLink='true'>https://udrepper.livejournal.com/21541.html</guid>
  <pubDate>Thu, 05 Aug 2010 01:38:07 GMT</pubDate>
  <title>Cancellation and C++ Exceptions</title>
  <author>udrepper</author>
  <link>https://udrepper.livejournal.com/21541.html</link>
  <description>&lt;h1&gt;Cancellation and C++ Exceptions&lt;/h1&gt;

&lt;p&gt;In NPTL thread cancellation is implemented using exceptions.  This does not in general conflict with the mixed use of cancellation and exceptions in C++ programs.  This works just fine.  Some people, though, write code which doesn&apos;t behave as they expect.  This is a short example:&lt;/p&gt;

&lt;pre&gt;
#include &amp;lt;cstdlib&amp;gt;
#include &amp;lt;iostream&amp;gt;
#include &amp;lt;pthread.h&amp;gt;

static pthread_mutex_t m = PTHREAD_MUTEX_INITIALIZER;
static pthread_cond_t c = PTHREAD_COND_INITIALIZER;

static void *tf (void *)
{
  try {
    ::pthread_mutex_lock(&amp;amp;m);
    ::pthread_cond_wait (&amp;amp;c, &amp;amp;m);
  } catch (...) {
    // do something
  }
}

int main ()
{
  pthread_t th;
  ::pthread_create (&amp;amp;th, NULL, tf, NULL);
  // do some work; simulate using sleep
  std::cout &amp;lt;&amp;lt; &quot;Wait a bit&quot; &amp;lt;&amp;lt; std::endl;
  sleep (1);
  // cancel the child thread
  ::pthread_cancel (th);
  // wait for it
  ::pthread_join (th, NULL);
}
&lt;/pre&gt;

&lt;p&gt;The problem is in function &lt;tt&gt;tf&lt;/tt&gt;.  This function contains a catch-all clause which does not rethrow the exception.  This is possible to expect but should really never happen in any code.  The rules C++ experts developed state that catch-all cases must rethrow.  If not then strange things can happen since one doesn&apos;t always know exactly what exceptions are thrown.  The code above is just one example.  Running it will produce a segfault:&lt;/p&gt;

&lt;pre&gt;
$ ./test
Wait a bit
FATAL: exception not rethrown
Aborted (core dumped)
&lt;/pre&gt;

&lt;p&gt;The exception used for cancellation is special, it cannot be ignored.  This is why the program aborts.&lt;/p&gt;

&lt;p&gt;Simply adding the rethrow will cure the problem:&lt;/p&gt;

&lt;pre&gt;
@@ -13,6 +13,7 @@
     ::pthread_cond_wait (&amp;amp;c, &amp;amp;m);
   } catch (...) {
     // do something
+    throw;
   }
 }
 
&lt;/pre&gt;

&lt;p&gt;But this code might not have the expected semantics.  Therefore the more general solution is to change the code as such:&lt;/p&gt;

&lt;pre&gt;
@@ -1,6 +1,7 @@
 #include &amp;lt;cstdlib&amp;gt;
 #include &amp;lt;iostream&amp;gt;
 #include &amp;lt;pthread.h&amp;gt;
+#include &amp;lt;cxxabi.h&amp;gt;
 
 static pthread_mutex_t m = PTHREAD_MUTEX_INITIALIZER;
 static pthread_cond_t c = PTHREAD_COND_INITIALIZER;
@@ -11,6 +12,8 @@
   try {
     ::pthread_mutex_lock(&amp;amp;m);
     ::pthread_cond_wait (&amp;amp;c, &amp;amp;m);
+  } catch (abi::__forced_unwind&amp;amp;) {
+    throw;
   } catch (...) {
     // do something
   }
&lt;/pre&gt;

&lt;p&gt;The header &lt;tt&gt;cxxabi.h&lt;/tt&gt; comes with gcc since, I think, gcc 4.3.  It defines a special tag which corresponds to the exception used in cancellation.  This exception is not catchable, as already said, which is why it is called &lt;tt&gt;__forced::unwind&lt;/tt&gt;.&lt;/p&gt;

&lt;p&gt;That&apos;s all.  That is needed.  This code can easily be added to existing code, maybe even with a single hidden use:&lt;/p&gt;

&lt;pre&gt;
#define CATCHALL catch (abi::__forced_unwind&amp;amp;) { throw; } catch (...)
&lt;/pre&gt;

&lt;p&gt;This macro can be defined predicated on the gcc version and the platform.&lt;/p&gt;

&lt;p&gt;I still think it is better to always rethrow the execption, though.&lt;/p&gt;</description>
  <comments>https://udrepper.livejournal.com/21541.html?view=comments#comments</comments>
  <category>linux nptl c++ cancellation exceptions</category>
  <lj:security>public</lj:security>
  <lj:reply-count>0</lj:reply-count>
  </item>
  <item>
  <guid isPermaLink='true'>https://udrepper.livejournal.com/21384.html</guid>
  <pubDate>Fri, 07 May 2010 05:47:15 GMT</pubDate>
  <title>IDN Support</title>
  <author>udrepper</author>
  <link>https://udrepper.livejournal.com/21384.html</link>
  <description>glibc has IDN support for &lt;tt&gt;getaddrinfo&lt;/tt&gt; and &lt;tt&gt;getnameinfo&lt;/tt&gt; for quite some time.  It has to be explicitly enabled in the calls, though.  Now that I can actually test this I’ve enabled IDN support in the &lt;tt&gt;getent&lt;/tt&gt; program which comes with glibc.   This screenshot shows &lt;tt&gt;getent&lt;/tt&gt; in action.  Apparently the site doesn’t use an IDN CNAME yet.&lt;br /&gt;&lt;br /&gt;&lt;img src=&quot;https://imgprx.livejournal.net/d4a001282a5637b76110f56d3b524d3bb52af8477785e07a1954852c57852f05/P2WlxyVijxKghGBq98xWWUMdsf-ah7h0z0uNV75WwcLW9xDVgY-mB0dpBFVyDl10pA1SmSnbbRcIFFYC0wg1-AQS:3yl8YEpcDxI7ajIOS6r0yw&quot; width=&quot;494&quot; height=&quot;352&quot; title=&quot;getent with IDN&quot; fetchpriority=&quot;high&quot; /&gt;&lt;br /&gt;&lt;br /&gt;The changes are minimal and pushed into the git archive.  IDN is enabled by default, non-IDN names still continue to work.  In case there is some sort of problem the &lt;tt&gt;--no-idn&lt;/tt&gt; option can be used to disable IDN support.&lt;br /&gt;&lt;br /&gt;It is quite easy for other programs to enable IDN as well.  Whether it all should just work automatically is another question.  There is the problem of look-alike characters in the Unicode range which might undermine the certificate system.</description>
  <comments>https://udrepper.livejournal.com/21384.html?view=comments#comments</comments>
  <lj:security>public</lj:security>
  <lj:reply-count>1</lj:reply-count>
  </item>
  <item>
  <guid isPermaLink='true'>https://udrepper.livejournal.com/21140.html</guid>
  <pubDate>Tue, 04 May 2010 16:27:06 GMT</pubDate>
  <title>Fedora and USB Mobile Broadband</title>
  <author>udrepper</author>
  <link>https://udrepper.livejournal.com/21140.html</link>
  <description>Outside the US I use a USB stick for Internet access.  It is a Huawei E161, similar enough to other sticks like E160 etc.&lt;br /&gt;&lt;br /&gt;Inserting it into a standard Fedora 12 system causes only the simulated CDROM to be mounted.  This dual-mode is the root of the problem.&lt;br /&gt;&lt;br /&gt;Looking for a solution one comes across many different &lt;q&gt;solutions&lt;/q&gt;.  The provider I use, Fonic, has something to download for Linux  (a plus, even though they don’t provide any support for it).  This seems to be an NDIS driver.  There are several other ways (including wvdial and some KDE programs) which are documented.&lt;br /&gt;&lt;br /&gt;It’s all much simpler with recent Fedora distributions.  Just make sure you have the &lt;tt&gt;usb_modeswitch&lt;/tt&gt; and the accompanying &lt;tt&gt;usb_modeswitch-data&lt;/tt&gt; package installed.  Version 1.1.2-3 is what I use.  Make sure you reboot before trying to use it.&lt;br /&gt;&lt;br /&gt;The &lt;tt&gt;usb_modeswitch&lt;/tt&gt; package contains a program which switches the USB stick from mass storage mode into modem mode.  It also contains appropriate &lt;tt&gt;udev&lt;/tt&gt; rules to make this automatic if the device is known in the config files.  If it is not known it’s quite simple to add.&lt;br /&gt;&lt;br /&gt;Anyway, when inserting the stick the mode should then automatically be switched and then &lt;tt&gt;NetworkManager&lt;/tt&gt; takes over.  It recognizes the modem and the built-in rules for wireless broadband providers guide you through the rest of the installation process.  You only need to know the provider and possibly the plan.  That’s it.&lt;br /&gt;&lt;br /&gt;Now when I insert the stick all I get asked is the PIN which has to be provided every time.  Why, I don’t know, it should IMO be stored in the keyring just like all the other access information.&lt;br /&gt;&lt;br /&gt;Anyway, for everybody with wireless broadband devices on Fedora, make sure &lt;tt&gt;usb_modeswitch&lt;/tt&gt; is installed.  There is an open bug in the Red Hat bugzilla to make &lt;tt&gt;NetworkManager&lt;/tt&gt; depend on this package so that everything &lt;q&gt;just works&lt;/q&gt; for more people.</description>
  <comments>https://udrepper.livejournal.com/21140.html?view=comments#comments</comments>
  <lj:security>public</lj:security>
  <lj:reply-count>3</lj:reply-count>
  </item>
  <item>
  <guid isPermaLink='true'>https://udrepper.livejournal.com/20948.html</guid>
  <pubDate>Sat, 18 Apr 2009 00:42:54 GMT</pubDate>
  <title>glibc 2.10 news</title>
  <author>udrepper</author>
  <link>https://udrepper.livejournal.com/20948.html</link>
  <description>&lt;p&gt;I might need a bit more space to explain the new features in glibc 2.10 than can reasonably be written down in the release notes.  Therefore I’ll take some time to describe them here.&lt;/p&gt;

&lt;h2&gt;POSIX 2008&lt;/h2&gt;

&lt;p&gt;We (= Austin Group) have finished work on the 2008 revision of POSIX some time ago.  In glibc 2.10 I’ve added the necessary feature select macros and more to glibc to support POSIX 2008.  Most of it, at least.  This was quite easy.  A large part of the work which went into POSIX 2008 was to add functions which have been in glibc to POSIX.  The Unix world catches up with Linux.&lt;/p&gt;

&lt;p&gt;I had to implement one new function: &lt;tt&gt;psiginfo&lt;/tt&gt;.  This function is similar to &lt;tt&gt;psignal&lt;/tt&gt; but instead of printing information for a simple signal it prints information for a &lt;q&gt;real-time&lt;/q&gt; signal context.&lt;/p&gt;

&lt;p&gt;A few things are left to be done.  What I know right now is the implementation of the &lt;tt&gt;O_SEARCH&lt;/tt&gt; and &lt;tt&gt;O_EXEC&lt;/tt&gt; flags.  This needs kernel support.&lt;/p&gt;

&lt;h2&gt;C++ compliance&lt;/h2&gt;

&lt;p&gt;The C standard defines functions like &lt;tt&gt;strchr&lt;/tt&gt; in a pretty weak way because C has no function overloading:&lt;/p&gt;

&lt;pre&gt;char *strchr(const char *, int)&lt;/pre&gt;

&lt;p&gt;The string parameter and the return value type are as weak as possible.  Non-constant strings can be passed as parameters and the result can be assigned to a constant string variable.&lt;/p&gt;

&lt;p&gt;The problem of this is that the const-ness of the parameter is not preserved and reflected in the return value.  This would be the right thing to do since the return value, if not &lt;tt&gt;NULL&lt;/tt&gt;, is pointing somewhere in the parameter string.&lt;/p&gt;

&lt;p&gt;C++ with its function overloading can do better.  This is why C++ 1998 actually defines two functions:&lt;/p&gt;

&lt;pre&gt;char *strchr(char *, int)
const char *strchr(const char *, int)&lt;/pre&gt;

&lt;p&gt;These functions do preserve the const-ness.  This is possible because these functions actually have different names after mangling.  Actually, in glibc we use a neat trick of gcc to avoid defining any function with C++ binding but this is irrelevant here.&lt;/p&gt;

&lt;p&gt;Anyway, the result of this change is that some incorrect C++ programs, which worked before, will now fail to compile.&lt;/p&gt;

&lt;pre&gt;const char *in = “some string”;
char *i = strchr(in, ‘i’);&lt;/pre&gt;

&lt;p&gt;This code will fail because the &lt;tt&gt;strchr&lt;/tt&gt; version selected by the compiler is the second one which returns a constant string pointer.  It is an error (not only a source of a warning) in C++ when a const pointer is assigned to a non-const pointer.&lt;/p&gt;

&lt;p&gt;As I wrote, this is incorrect C++ code.  But it might trip up some people.&lt;/p&gt;


&lt;h2&gt;C++ 201x support&lt;/h2&gt;

&lt;p&gt;There is one interface in the upcoming C++ revision which needs support in the C library, at least to be efficient.  C++ 201x defines yet another set of interface to terminate a process and to register handlers which are run when this happens:&lt;/p&gt;

&lt;pre&gt;int at_quick_exit(void (*)(void))
void quick_exit(int)&lt;/pre&gt;

&lt;p&gt;The handlers installed with &lt;tt&gt;at_quick_exit&lt;/tt&gt; will only be run when &lt;tt&gt;quick_exit&lt;/tt&gt; is used and not when &lt;tt&gt;exit&lt;/tt&gt; is used.  No global destructors are run either.  That’s the whole purpose of this new interface.  If the process is in a state where the global destructors cannot be run anymore and the process would crash, &lt;tt&gt;quick_exit&lt;/tt&gt; should be used.&lt;/p&gt;


&lt;h2&gt;DNS NSS improvement&lt;/h2&gt;

&lt;p&gt;In glibc 2.9 I already implemented an improvement to the DNS NSS module which optimizes the lookup of IPv4 and IPv6 addresses for the same host.  This can improve the response time of the lookup due to parallelism.  It also fixes a bug in name lookup where the IPv4 and IPv6 addresses could be returned for different hosts.&lt;/p&gt;

&lt;p&gt;The problem with this change was that there are broken DNS servers and broken firewall configurations which prevented the two results from being received successfully.  Some broken DNS servers (especially those in cable modems etc) only send one reply.  For this reason Fedora had this change disabled in F10.&lt;/p&gt;

&lt;p&gt;For F11 I’ve added a work-around for broken servers.  The default behavior is the same as described above.  I.e., we get the improved performance for working DNS servers.  In case the program detects a broken DNS server or firewall because it received only one reply the resolver switches into a mode where the second request is sent only after the first reply has been received.  We still get the benefit of the bug fix described above, though.&lt;/p&gt;

&lt;p&gt;The drawback is that a timeout is needed to detect the broken servers or firewalls.  This delay is experienced once per process start and could be noticeable.  But the broken setups of the few people affected must not prevent the far larger group of people with working setups to experience the advantage of the parallel lookup.&lt;/p&gt;

&lt;p&gt;There are also ways to avoid the delays, some old, some new:&lt;/p&gt;

&lt;ul&gt;

&lt;li&gt;Install a caching name server on this machine or somewhere on the local network.  bind is known to work correctly.&lt;/li&gt;

&lt;li&gt;Run nscd on the local machine. In this case the delay is incurred once per system start (i.e., at the first lookup nscd performs).&lt;/li&gt;

&lt;li&gt;Add “single-request” to the options in /etc/resolv.conf.  This selects the compatibility mode from the start.&lt;/li&gt;

&lt;/ul&gt;

&lt;p&gt;All of these work-arounds are easy to implement.  Therefore there is no reason to not have the fast mode the default which in any case will work for 99% of the people.&lt;/p&gt;


&lt;h2&gt;Use NSS in libcrypt&lt;/h2&gt;

&lt;p&gt;The NSS I refer to here is the Network Security Services packages.  It provides libraries with implementations of crypto and hash functions, among other things.  In RHEL the NSS package is certified and part of the EAL feature set.&lt;/p&gt;

&lt;p&gt;To get compliance for the whole system every implementation of the crypto and hash functions would have to be certified.  This is an expensive and time-consuming process.  The alternative is to use everywhere the same implementation.  This is what a change to libcrypt now allows.&lt;/p&gt;

&lt;p&gt;Since NSS is already certified we can just use the implementation of the hash functions from the NSS libraries in the implementation of crypt(3) in libcrypt.  &lt;a href=&quot;mailto:rrelyea@redhat.com&quot; target=&quot;_blank&quot; rel=&quot;nofollow&quot;&gt;Bob Relyea&lt;/a&gt; implemented a set of new interfaces in the libfreebl3 library to allow the necessary low-level access and freed libfreebl3 from dependencies on NSPR.&lt;/p&gt;

&lt;p&gt;By default libcrypt is built as before.  Only with the appropriate configure option is libfreebl3 used.  There are no visible changes (except the dependency on libfreebl3) so users should not have to worry at all.&lt;/p&gt;

&lt;p&gt;Combine this with the &lt;a href=&quot;http://people.redhat.com/drepper/sha-crypt.html&quot; target=&quot;_blank&quot; rel=&quot;nofollow&quot;&gt;new password hashing&lt;/a&gt; I’ve developed almost two years ago and we have now fully certified password handling.&lt;/p&gt;


&lt;h2&gt;printf hooks&lt;/h2&gt;

&lt;p&gt;Certain special interest groups subverted the standardization process (again) and pressed through changes to introduce in the C programming language extensions to support decimal floating point computations. 99.99% of all the people will never use this stuff and still we have to live with it.&lt;/p&gt;

&lt;p&gt;I refuse to add support for this to glibc because these extensions are not (yet) in the official language standard.  And maybe even after that we’ll have it separately.&lt;/p&gt;

&lt;p&gt;But the DFP extension call for support in &lt;tt&gt;printf&lt;/tt&gt;.  The normal floating-point formats cannot be used.  New modifiers are needed.&lt;/p&gt;

&lt;p&gt;The &lt;tt&gt;printf&lt;/tt&gt; in glibc has for the longest time a way to extend it.  One can install handlers for additional format specifiers.  Unfortunately, this extension mechanism isn’t generic enough for the purpose of supporting DFP.&lt;/p&gt;

&lt;p&gt;After a couple of versions of a patch from Ryan Arnold I finally finished the work and added a generic framework which allows installing additional modifiers and format specifiers.&lt;/p&gt;

&lt;pre&gt;int register_printf_specifier (int, printf_function,
                                        printf_arginfo_size_function)
int register_printf_modifier (wchar_t *)
int register_printf_type (printf_va_arg_function)&lt;/pre&gt;

&lt;p&gt;With these interfaces DFP printing functions can live outside glibc and still work as if the support were built in.  For an example see my code &lt;a href=&quot;http://sources.redhat.com/bugzilla/attachment.cgi?id=3874&amp;amp;action=view&quot; target=&quot;_blank&quot; rel=&quot;nofollow&quot;&gt;to print XMM values&lt;/a&gt;.&lt;/p&gt;


&lt;h2&gt;&lt;tt&gt;malloc&lt;/tt&gt; scalability&lt;/h2&gt;

&lt;p&gt;A change which is rather small in the number of lines it touches went in to make &lt;tt&gt;malloc&lt;/tt&gt; more scalable.  Before, &lt;tt&gt;malloc&lt;/tt&gt;tried to emulate a per-core memory pool.  Every time when contention for all existing memory pools was detected a new pool is created.  Threads stay with the last used pool if possible.&lt;/p&gt;

&lt;p&gt;This never worked 100% because a thread can be descheduled while executing a &lt;tt&gt;malloc&lt;/tt&gt; call.  When some other thread tries to use the memory pool used in the call it would detect contention.  A second problem is that if multiple threads on multiple core/sockets happily use &lt;tt&gt;malloc&lt;/tt&gt; without contention memory from the same pool is used by different cores/on different sockets.  This can lead to false sharing and definitely additional cross traffic because of the meta information updates.  There are more potential problems not worth going into here in detail.&lt;/p&gt;

&lt;p&gt;The changes which are in glibc now create per-thread memory pools.  This can eliminate false sharing in most cases.  The meta data is usually accessed only in one thread (which hopefully doesn’t get migrated off its assigned core).  To prevent the memory handling from blowing up the address space use too much the number of memory pools is capped.  By default we create up to two memory pools per core on 32-bit machines and up to eight memory per core on 64-bit machines.  The code delays testing for the number of cores (which is not cheap, we have to read &lt;tt&gt;/proc/stat&lt;/tt&gt;) until there are already two or eight memory pools allocated, respectively.&lt;/p&gt;

&lt;p&gt;Using environment variables the implementation can be changed.  If &lt;tt&gt;MALLOC_ARENA_TEST_&lt;/tt&gt; is set the test for the number of cores is only performed once the number of memory pools in use reaches the value specified by this envvar.  If &lt;tt&gt;MALLOC_ARENA_MAX_&lt;/tt&gt; is used it sets the maximum number of memory pools used, regardless of the number of cores.&lt;/p&gt;

&lt;p&gt;While these changes might increase the number of memory pools which are created (and thus increase the address space they use) the number can be controlled.  Because using the old mechanism there could be a new pool being created whenever there are collisions the total number could in theory be higher.  Unlikely but true, so the new mechanism is more predictable.&lt;/p&gt;

&lt;p&gt;The important thing to realize, though, is when the old mechanism was developed.  My machine at the time when I added Wolfram’s dlmalloc to glibc back in 1995 (I think) had 64MB of memory.  We’ve come a long way since then.  Memory use is not that much of a premium anymore and most of the memory pool doesn’t actually require memory until it is used, only address space.  We have plenty of that on 64-bit machines.  32-bit machines are a different story.  But this is why I limit the number of memory pools on 32-bit machines so drastically to two per core.&lt;/p&gt;

&lt;p&gt;The changes include a second improvement which allow the &lt;tt&gt;free&lt;/tt&gt; function to avoid locking the memory pool in certain situations.&lt;/p&gt;

&lt;p&gt;We have done internally some measurements of the effects of the new implementation and they can be quite dramatic.&lt;/p&gt;


&lt;h2&gt;Information about &lt;tt&gt;malloc&lt;/tt&gt;&lt;/h2&gt;

&lt;p&gt;There is an obscure SysV interface in glibc called &lt;tt&gt;mallinfo&lt;/tt&gt;.  It allows the caller to get some information about the state of the &lt;tt&gt;malloc&lt;/tt&gt; implementation.  Data like total memory allocated, total address space, etc.  There are multiple problems with this interface, though.&lt;/p&gt;

&lt;p&gt;The first problem is that it is completely unsuitable for 64-bit machines.  The data types required by the SysV spec don’t allow for values larger 2^31 bytes (all fields in the structure are &lt;tt&gt;int&lt;/tt&gt;s).  The second problem is that the data structure is really specific to the &lt;tt&gt;malloc&lt;/tt&gt; implementation SysV used at that time.&lt;/p&gt;

&lt;p&gt;The implementation details of &lt;tt&gt;malloc&lt;/tt&gt; implementations will change over time.  It is therefore a bad idea to codify a specific implementation in the structures which export statistical information.&lt;/p&gt;

&lt;p&gt;The new &lt;tt&gt;malloc_info&lt;/tt&gt; function therefore does not export a structure.  Instead it exports the information in a self-describing data structure.  Nowadays the preferred way to do this is via XML.  The format can change over time (it’s versioned), some fields will stay the same, other will change.  No breakage.  The reader just cannot assume that all the information will forever be available in the same form.  There is no reader in glibc.  This isn’t necessary, it’s easy enough to write outside glibc using one of the many XML libraries.&lt;/p&gt;


&lt;h2&gt;Automatic use of optimized function&lt;/h2&gt;

&lt;p&gt;Processor vendors these days spend time fine tuning the instruction sets of their products.  Specialized instructions are introduced which can be used to accelerate the implementation of specific functions.  One problem holding back the adoption of such instructions is that people want their binaries to work everywhere.&lt;/p&gt;

&lt;p&gt;One example for such application-specific instructions are the SSE4.2 extensions Intel introduced in their Nehalem core.  This core features special instructions for string handling.  They allow optimized implementations of functions like &lt;tt&gt;strlen&lt;/tt&gt; or &lt;tt&gt;strchr&lt;/tt&gt; etc.&lt;/p&gt;

&lt;p&gt;It would of course be possible to start the implementation of these functions with a test for this feature and then use the old or the new implementation.  For functions where the total time a call takes is just a couple of dozen cycles this overhead is noticeable, though.&lt;/p&gt;

&lt;p&gt;Therefore I’ve designed an ELF extension which allows to make the decision about which implementation to use once per process run.  It is implemented using a new ELF symbol type (&lt;tt&gt;STT_GNU_IFUNC&lt;/tt&gt;).  Whenever the a symbol lookup resolves to a symbol with this type the dynamic linker does not immediately return the found value.  Instead it is interpreting the value as a function pointer to a function that takes no argument and returns the real function pointer to use.  The code called can be under control of the implementer and can choose, based on whatever information the implementer wants to use, which of the two or more implementations to use.&lt;/p&gt;

&lt;p&gt;This feature is not yet enabled in Fedora 11.  There is some more binutils work needed and then prelink has to be changed.  My guess is that F11 will go out without glibc taking advantage of this feature itself.  But we will perhaps enable it after the release, once binutils and prelink caught up.&lt;/p&gt;</description>
  <comments>https://udrepper.livejournal.com/20948.html?view=comments#comments</comments>
  <lj:security>public</lj:security>
  <lj:reply-count>0</lj:reply-count>
  </item>
  <item>
  <guid isPermaLink='true'>https://udrepper.livejournal.com/20709.html</guid>
  <pubDate>Sat, 03 Jan 2009 00:21:44 GMT</pubDate>
  <title>Fedora 10 a little bit more secure</title>
  <author>udrepper</author>
  <link>https://udrepper.livejournal.com/20709.html</link>
  <description>Fedora 10 comes with filesystem capability support.  Unfortunately it is not used by default in the packages which can take advantage of it.  I think the excuse is that there people who build their own kernels and disable it.  That&apos;s nonsense since there are many other options we rely on and which can be compiled out.&lt;br /&gt;&lt;br /&gt;Anyway, you can do the following by hand.  Unfortunately you have to do it every time the program is updated again.&lt;br /&gt;&lt;br /&gt;&lt;pre&gt;
sudo chmod u-s /bin/ping
sudo /usr/sbin/setcap cap_net_raw=ep /bin/ping
sudo chmod u-s /bin/ping6
sudo /usr/sbin/setcap cap_net_raw=ep /bin/ping6
&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;Voilà, ping and ping6 are no SUID binaries anymore.  Note that ls still signals (at least when you&apos;re using --color) that there is something special with the file, namely, there are filesystem attributes.&lt;br /&gt;&lt;br /&gt;These are two easy cases.  Other SUID programs need some research to see whether they can use filesystem capabilities as well and which capabilities they need.</description>
  <comments>https://udrepper.livejournal.com/20709.html?view=comments#comments</comments>
  <category>security</category>
  <lj:security>public</lj:security>
  <lj:reply-count>0</lj:reply-count>
  </item>
  <item>
  <guid isPermaLink='true'>https://udrepper.livejournal.com/20407.html</guid>
  <pubDate>Fri, 01 Aug 2008 23:25:50 GMT</pubDate>
  <title>Secure File Descriptor Handling</title>
  <author>udrepper</author>
  <link>https://udrepper.livejournal.com/20407.html</link>
  <description>&lt;p&gt;During the 2.6.27 merge window a number of my patches were merge and now we are at the point where we can securely create file descriptors without the danger of possibly leaking information.  Before I go into the details let&apos;s get some background information.&lt;/p&gt;

&lt;p&gt;A file descriptor in the Unix/POSIX world has lots of state associated with it.  One bit of information determines whether the file descriptor is automatically closed when the process executes an exec call to start executing another program.  This is useful, for instance, to establish pipelines.
Traditionally, when a file descriptor is created (e.g., with the default open() mode) this close-on-exec flag is not set and a programmer has to explicitly set it using&lt;/p&gt;

&lt;pre&gt;
   fcntl(fd, F_SETFD, FD_CLOEXEC);
&lt;/pre&gt;

&lt;p&gt;Closing the descriptor is a good idea for two main reasons:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;the new program&apos;s file descriptor table might fill up.  For every open file descriptor resources are consumed.&lt;/li&gt;
&lt;li&gt;more importantly, information might be leaked to the second program.  That program might get access to information it normally wouldn&apos;t have access to.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;It is easy to see why the latter point is such a problem.  Assume this common scenario:&lt;/p&gt;

&lt;blockquote&gt;
A web browser has two windows or tabs open, both loading a new page (maybe triggered through Javascript).  One connection is to your bank, the other some random Internet site.  The latter contains some random object which must be handled by a plug-in.  The plug-in could be an external program processing some scripting language.  The external program will be started through a fork() and exec sequence, inheriting all the file descriptors open and not marked with close-on-exec from the web browser process.
&lt;/blockquote&gt;

&lt;p&gt;The result is that the plug-in can have access to the file descriptor used for the bank connection.  This is especially bad if the plug-in is used for a scripting language such a Flash because this could make the descriptor easily available to the script.  In case the author of the script has malicious intentions you might end up losing money.&lt;/p&gt;

&lt;p&gt;Until not too long ago the best programs could to is to set the close-on-exec flag for file descriptors as quickly as possible after the file descriptor has been created.  Programs would break if the default for new file descriptors would be changed to set the bit automatically.&lt;/p&gt;

&lt;p&gt;This does not solve the problem, though.  There is a (possibly brief) period of time between the return of the open() call or other function creating a file descriptor and the fcntl() call to set the flag.  This is problematic because the fork() function is signal-safe (i.e., it can be called from a signal handler).  In multi-threaded code a second thread might call fork() concurrently.  It is theoretically possible to avoid these races by blocking all signals and by ensuring through locks that fork() cannot be called concurrently.  This very quickly get far too complicated to even contemplate:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;To block all signals, each thread in the process has to be interrupted (through another signal) and in the signal handler block all the other signals.  This is complicated, slow, possibly unreliable, and might introduce deadlocks.&lt;/li&gt;
&lt;li&gt;Using a lock also means there has to be a lock around fork() itself.  But fork() is signal safe.  This means this step also needs to block all signals.  This by itself requires additional work since child processes inherit signal masks.&lt;/li&gt;
&lt;li&gt;Making all this work in projects which come from different sources (and which non-trivial program doesn&apos;t use system or third-party libraries?) is virtually impossible.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;It is therefore necessary to find a different solution.  The first set of patches to achieve the goal went into the Linux kernel in 2.6.23, the last, as already mentioned, will be in the 2.6.27 release.  The patches are all rather simple.  They just extend the interface of various system calls so that already existing functionality can be taken advantage of.&lt;/p&gt;

&lt;p&gt;The simplest case is the open() system call.  To create a file descriptor with the close-on-exec flag atomically set all one has to do is to add the O_CLOEXEC flag to the call.  There is already a parameter which takes such flags.&lt;/p&gt;

&lt;p&gt;The next more complicated is the solution chosen to extend the socket() and socketcall() system calls.  No flag parameter is available but the second parameter to these interfaces (the type) has a very limited range requirement.  It was &lt;a href=&quot;http://lwn.net/Articles/282212/&quot; target=&quot;_blank&quot; rel=&quot;nofollow&quot;&gt;felt&lt;/a&gt; that overloading the parameter is an acceptable solution.  It definitely makes using the new interfaces simpler.&lt;/p&gt;

&lt;p&gt;The last group are interfaces where the original interface simply doesn&apos;t provide a way to pass additional parameters.  In all these cases a generic flags parameter was added.  This is preferable to using specialized new interfaces (like, for instance, dup2_cloexec) because we do and will need other flags.  O_NONBLOCK is one case.  Hopefully we&apos;ll have non-sequential file descriptors at some point and we can then request them using the flags, too.&lt;/p&gt;

&lt;p&gt;The (hopefully complete) list of interface changes which were introduced is listed below.  Note: these are the &lt;b&gt;userlevel&lt;/b&gt; change.  Inside the kernel things look different.&lt;/p&gt;

&lt;table&gt;
&lt;tr&gt;&lt;th&gt;Userlevel Interface&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/th&gt;&lt;th&gt;What changed?&lt;/th&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td&gt;open&lt;/td&gt;&lt;td&gt;O_CLOEXEC flag added&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td&gt;fcntl&lt;/td&gt;&lt;td&gt;F_DUPFD_CLOEXEC command added&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td&gt;recvmsg&lt;/td&gt;&lt;td&gt;MSG_CMSG_CLOEXEC flag for transmission of file descriptor over Unix domain socket which has close-on-exec set atomically&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td&gt;dup3&lt;/td&gt;&lt;td&gt;New interface taking an addition flag parameter (O_CLOEXEC, O_NONBLOCK)&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td&gt;pipe2&lt;/td&gt;&lt;td&gt;New interface taking an addition flag parameter (O_CLOEXEC, O_NONBLOCK)&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td&gt;socket&lt;/td&gt;&lt;td&gt;SOCK_CLOEXEC and SOCK_NONBLOCK flag added to type parameter&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td&gt;socketpair&lt;/td&gt;&lt;td&gt;SOCK_CLOEXEC and SOCK_NONBLOCK flag added to type parameter&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td&gt;paccept&lt;/td&gt;&lt;td&gt;New interface taking an addition flag parameter (SOCK_CLOEXEC, SOCK_NONBLOCK) and a temporary signal mask&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td&gt;fopen&lt;/td&gt;&lt;td&gt;New mode &apos;e&apos; to open file with close-on-exec set&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td&gt;popen&lt;/td&gt;&lt;td&gt;New mode &apos;e&apos; to open pipes with close-on-exec set&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td&gt;eventfd&lt;/td&gt;&lt;td&gt;Take new flags EFD_CLOEXEC and EFD_NONBLOCK&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td&gt;signalfd&lt;/td&gt;&lt;td&gt;Take new flags SFD_CLOEXEC and SFD_NONBLOCK&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td&gt;timerfd&lt;/td&gt;&lt;td&gt;Take new flags TFD_CLOEXEC and TFD_NONBLOCK&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td&gt;epoll_create1&lt;/td&gt;&lt;td&gt;New interface taking a flag parameter.  Support EPOLL_CLOEXEC and EPOLL_NONBLOCK&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td&gt;inotify_init1&lt;/td&gt;&lt;td&gt;New interface taking a flag parameter (IN_CLOEXEC, IN_NONBLOCK)&lt;/td&gt;&lt;/tr&gt;
&lt;/table&gt;

&lt;p&gt;When should these interfaces be used?  The answer is simple: whenever the author is not sure that no asynchronous fork()+exec can happen or a concurrently running threads executes fork()+exec (or posix_spawn(), BTW).&lt;/p&gt;

&lt;p&gt;Application writers might have control over this.  But I&apos;d say that in all library code one has to play it safe.  In glibc we do now in almost all interfaces open the file descriptor with the close-on-exec flag set.  This means a lot of work but it has to be done.  Applications also have to change (see this &lt;a href=&quot;http://bugzilla.redhat.com/show_bug.cgi?id=443321&quot; target=&quot;_blank&quot; rel=&quot;nofollow&quot;&gt;autofs bug&lt;/a&gt;, for instance).&lt;/p&gt;</description>
  <comments>https://udrepper.livejournal.com/20407.html?view=comments#comments</comments>
  <category>programming security linux</category>
  <lj:security>public</lj:security>
  <lj:reply-count>2</lj:reply-count>
  </item>
  <item>
  <guid isPermaLink='true'>https://udrepper.livejournal.com/20187.html</guid>
  <pubDate>Fri, 23 May 2008 17:53:00 GMT</pubDate>
  <title>dual head xrandr configuration</title>
  <author>udrepper</author>
  <link>https://udrepper.livejournal.com/20187.html</link>
  <description>&lt;p&gt;&lt;a href=&quot;mailto:ajax@redhat.com&quot; target=&quot;_blank&quot; rel=&quot;nofollow&quot;&gt;ajax&lt;/a&gt; told me that extra wide screens now work with the latest Fedora 9 binaries for X11.  So I had to try it out and after some experimenting I got it to work.  To save others the work here is what I did.&lt;/p&gt;

&lt;p&gt;Hardware:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;ATI FireGL V3600&lt;/li&gt;
&lt;li&gt;2x Dell 3007FPW&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;I use the free driver, of course.  No need for 3D here.&lt;/p&gt;

&lt;p&gt;The old way to get a spanning desktop was to use Xinerama.  This has been replaced by xrandr nowadays.  xrandr is not just for external screens of laptops and to change the resolution.  One can assign the origin of various screens and therefore display different parts of a bigger virtual desktop.  This is the whole trick here.  The /etc/X11/xorg.conf file I use is this:

&lt;pre&gt;
Section &quot;ServerLayout&quot;
	Identifier     &quot;dual head configuration&quot;
	Screen      0  &quot;Screen0&quot; 0 0
	InputDevice    &quot;Keyboard0&quot; &quot;CoreKeyboard&quot;
EndSection

Section &quot;InputDevice&quot;
	Identifier  &quot;Keyboard0&quot;
	Driver      &quot;kbd&quot;
	Option	    &quot;XkbModel&quot; &quot;pc105&quot;
	Option	    &quot;XkbLayout&quot; &quot;us+inet&quot;
EndSection

Section &quot;Device&quot;
	Identifier  &quot;Videocard0&quot;
	Driver      &quot;radeon&quot;
	Option	    &quot;monitor-DVI-0&quot; &quot;dvi0&quot;
	Option	    &quot;monitor-DVI-1&quot; &quot;dvi1&quot;
EndSection

Section &quot;Monitor&quot;
	Identifier &quot;dvi0&quot;
	Option &quot;Position&quot; &quot;2560 0&quot;
EndSection

Section &quot;Monitor&quot;
	Identifier &quot;dvi1&quot;
	Option &quot;LeftOf&quot; &quot;dvi0&quot;
EndSection

Section &quot;Screen&quot;
	Identifier &quot;Screen0&quot;
	Device     &quot;Videocard0&quot;
	DefaultDepth     16
	SubSection &quot;Display&quot;
		Viewport   0 0
		Depth     16
		Modes	&quot;2560x1600&quot;
		Virtual	5120 1600
	EndSubSection
EndSection
&lt;/pre&gt;

&lt;p&gt;Fortunately X11 configuration got much easier since I had to edit the file by hand.  I started from the most basic setup for a single screen which the installer or config-system-display will be happy to create for you.  The important changes on top of
this initial version are these:&lt;/p&gt;

&lt;pre&gt;
	Option	    &quot;monitor-DVI-0&quot; &quot;dvi0&quot;
	Option	    &quot;monitor-DVI-1&quot; &quot;dvi1&quot;
&lt;/pre&gt;

&lt;p&gt;These lines in the Device section announce the two screens.  It is unfortunately not well (at all?) documented that the first
parameter strings are magic.  If you ran &lt;tt&gt;xrandr -q&lt;/tt&gt; on your system with two screens attached you&apos;ll see the identifiers
assigned to the screens by the system.  In my case:&lt;/p&gt;

&lt;pre&gt;
$ xrandr -q
Screen 0: minimum 320 x 200, current 5120 x 1600, maximum 5120 x 1600
DVI-1 connected 2560x1600+0+0 (normal left inverted right x axis y axis) 646mm x 406mm
...
DVI-0 connected 2560x1600+2560+0 (normal left inverted right x axis y axis) 646mm x 406mm
...
&lt;/pre&gt;

&lt;p&gt;Add to the names DVI-0 and DVI-1 the magic prefix &lt;q&gt;monitor-&lt;/q&gt; and add as the second parameter string an arbitrary
identifier.  Do not drop or change the &lt;q&gt;monitor-&lt;/q&gt; prefix, that&apos;s the main magic which seems to make all this work.
Then create two monitor sections in the xorg.conf file, one for each screen:&lt;/p&gt;

&lt;pre&gt;
Section &quot;Monitor&quot;
	Identifier &quot;dvi0&quot;
	Option &quot;Position&quot; &quot;2560 0&quot;
EndSection

Section &quot;Monitor&quot;
	Identifier &quot;dvi1&quot;
	Option &quot;LeftOf&quot; &quot;dvi0&quot;
EndSection
&lt;/pre&gt;

&lt;p&gt;The Identifier lines must of course match the identifiers used in the Device section.  The rest are options which determine
what the screens show.  Since the LCDs have a resolution of 2560x1600 and since I want to have a spanning desktop and the DVI-0 connector is used for the display on the right side, I&apos;m using an x-offset of 2560 and an y-offset of 0 for that screen.  Then just tell the server to place the second screen at the left of it and the server will figure out the rest.&lt;p&gt;

&lt;p&gt;What remains to be done is to tell the server how large the screen in total is.  That&apos;s done using&lt;/p&gt;

&lt;pre&gt;
		Virtual	5120 1600
&lt;/pre&gt;

&lt;p&gt;The numbers should explain themselves.  Now the two screens show non-overlapping regions of the total desktop with no area
not displayed, all due to the correct arithmetic in the calculation of the total screen size and the offset.&lt;/p&gt;

&lt;p&gt; Note: there is only one Screen section.  That&apos;s something which is IIRC different from the last Xinerama setup I did years
ago.&lt;/p&gt;</description>
  <comments>https://udrepper.livejournal.com/20187.html?view=comments#comments</comments>
  <lj:security>public</lj:security>
  <lj:reply-count>0</lj:reply-count>
  </item>
  <item>
  <guid isPermaLink='true'>https://udrepper.livejournal.com/19751.html</guid>
  <pubDate>Thu, 22 Nov 2007 02:35:21 GMT</pubDate>
  <title>Producing PDFs</title>
  <author>udrepper</author>
  <link>https://udrepper.livejournal.com/19751.html</link>
  <description>I don&apos;t want to throw this in with the announcement of the availability of the paper on memory and cache handling but I also don&apos;t want to forget it.  So, here we go.&lt;br /&gt;&lt;br /&gt;I write all the text I can using TeX (PDFLaTeX to be exact).  This leads directly to a PDF document without intermediate steps.  The graphics are done using Metapost because I&apos;m better at programming than at drawing.  Metapost produces Postscript-like files which some LaTeX macros then read and directly integrate into the PDF output.&lt;br /&gt;&lt;br /&gt;The result in &lt;a href=&quot;http://people.redhat.com/drepper/cpumemory.pdf&quot; target=&quot;_blank&quot; rel=&quot;nofollow&quot;&gt;this case&lt;/a&gt; is a PDF with 114 pages which is only 934051 bytes in size.  Just about 8kB for each page.  Given that the text is multi-column and the numerous graphics in the text this is amazingly small.&lt;br /&gt;&lt;br /&gt;I &lt;a href=&quot;http://udrepper.livejournal.com/12663.html&quot; target=&quot;_blank&quot;&gt;mentioned before&lt;/a&gt; how badly OO.org sucks at exporting graphics. I bad all the other word processor, spreadsheets, etc suck just as badly.  Also generated PDFs for text is much, much bigger.&lt;br /&gt;&lt;br /&gt;My guess is that if I&apos;d written the document with OOO.org the size would be north of 4MB, probably significantly more.  I cannot understand why people do this to themselves and, more importantly, to others.</description>
  <comments>https://udrepper.livejournal.com/19751.html?view=comments#comments</comments>
  <lj:security>public</lj:security>
  <lj:reply-count>0</lj:reply-count>
  </item>
  <item>
  <guid isPermaLink='true'>https://udrepper.livejournal.com/19557.html</guid>
  <pubDate>Thu, 22 Nov 2007 02:09:09 GMT</pubDate>
  <title>Memory and Cache Paper</title>
  <author>udrepper</author>
  <link>https://udrepper.livejournal.com/19557.html</link>
  <description>Well, it&apos;s finally done.  I&apos;ve uploaded the PDF of the memory and cache paper to my home page.  You can &lt;a href=&quot;http://people.redhat.com/drepper/cpumemory.pdf&quot; target=&quot;_blank&quot; rel=&quot;nofollow&quot;&gt;download it&lt;/a&gt; but do not re-publish it or make it available in any form to others.  I do not want multiple copies flying around, at least not while I&apos;m still intending to maintain the document.&lt;br /&gt;&lt;br /&gt;With Jonathan Corbet&apos;s help the text should actually be readable.  I had to change some of the text in the end to accommodate line breaks in the PDF.  So I might have introduced problems, don&apos;t think bad about Jonathan&apos;s abilities.  Aside, this is a large document.  You simply go blind after a while, I know I do.&lt;br /&gt;&lt;br /&gt;Which brings me to the next point.  Even though I intend to maintain the document, don&apos;t expect me to do much in the near future.  I&apos;ve been working on it for far too long now and need a break.  Integrating all the editing Jonathan produced plus today&apos;s line breaking have given me the rest.  I haven&apos;t even integrated all the comments I&apos;ve received.  I know the structure of the document is in a few places a bit weak, esp section 5 which contains a lot of non-NUMA information.  But it was simply too much work so far.  Maybe some day.</description>
  <comments>https://udrepper.livejournal.com/19557.html?view=comments#comments</comments>
  <category>programming</category>
  <lj:security>public</lj:security>
  <lj:reply-count>0</lj:reply-count>
  </item>
  <item>
  <guid isPermaLink='true'>https://udrepper.livejournal.com/19395.html</guid>
  <pubDate>Tue, 13 Nov 2007 02:05:25 GMT</pubDate>
  <title>The Evils of pkgconfig and libtool</title>
  <author>udrepper</author>
  <link>https://udrepper.livejournal.com/19395.html</link>
  <description>&lt;p&gt;If you need more proof that this insane just look at some of the packages using it.  I recently was looking at krb5-auth-dialog.  The output of &lt;tt&gt;ldd -u -r&lt;/tt&gt; on the original binary shows 26 unused DSOs.&lt;/p&gt;

&lt;p&gt;This can be changed quite easily: add &lt;tt&gt;-Wl,--as-needed&lt;/tt&gt; to link line.  Do this in case of this package all but one of the unused dependencies is going away.  This has several benefits:&lt;/p&gt;

&lt;p&gt;The binary size is actually measurably reduced.&lt;/p&gt;

&lt;pre&gt;
   text    data     bss     dec     hex filename
  35944    6512      64   42520    a618 src/krb5-auth-dialog-old
  35517    6112      64   41693    a2dd src/krb5-auth-dialog
&lt;/pre&gt;

  &lt;p&gt;That’s a 2% improvement.  Note that all the saved dependencies are all recursive dependencies.  The runtime is therefore not much effected (only a little).  The saved data is pure overhead.  Multiply the number by the thousands of binaries and DSOs which are shipped and the savings are significant.&lt;/p&gt;

&lt;p&gt;The second problem to mention here is that not all unused dependencies are gone because somebody thought s/he is clever and uses -pthread in one of the pkgconfig files instead of linking with &lt;tt&gt;-lpthread&lt;/tt&gt;.  That’s just stupid when combined with the insanity called libtool.  The result is that the &lt;tt&gt;-Wl,--as-needed&lt;/tt&gt; is not applied to the thread library.&lt;/p&gt;

&lt;p&gt;Just avoid libtool and pkgconfig.  At the very least fix up the pkgconfig files to use &lt;tt&gt;-Wl,--as-needed&lt;/tt&gt;.&lt;/p&gt;</description>
  <comments>https://udrepper.livejournal.com/19395.html?view=comments#comments</comments>
  <lj:security>public</lj:security>
  <lj:reply-count>0</lj:reply-count>
  </item>
  <item>
  <guid isPermaLink='true'>https://udrepper.livejournal.com/19041.html</guid>
  <pubDate>Fri, 09 Nov 2007 04:44:21 GMT</pubDate>
  <title>Energy saving is everybody&apos;s business</title>
  <author>udrepper</author>
  <link>https://udrepper.livejournal.com/19041.html</link>
  <description>&lt;p&gt;With the wide acceptance of laptop and even smaller devices more and more people have been exposed to devices limited by energy consumption.  Still, programmers don&apos;t pay much attention to this aspect.&lt;/p&gt;

&lt;p&gt;This statement is not entirely accurate: there has been a big push towards energy conservation in the kernel world (at least in the Linux kernel).  With the tickless kernels we have the infrastructure to sleep for long times (&lt;q&gt;long&lt;/q&gt; is a relative term here).  Other internal changes avoid unnecessary wakeups.  It is now realy up to the userlevel world to do its part.&lt;/p&gt;

&lt;p&gt;The situation is pretty dire here.  There are some projects (e.g., &lt;a href=&quot;http://www.lesswatts.org/projects/powertop/&quot; target=&quot;_blank&quot; rel=&quot;nofollow&quot;&gt;PowerTOP&lt;/a&gt;) which highlight the problems.  Still, not much happens.&lt;/p&gt;

&lt;p&gt;I&apos;ve been &lt;i&gt;somewhat&lt;/i&gt; guilty myself.  nscd (part of glibc) was waking up every 5 seconds to clean up its cache, even if often was to be done.  This program structure has several reasons.  Good ones, but not ultimate reason.  So I finally bit the bullet and changed the program structure significantly to better enable wakeup.  The result is that now nscd at all times determines when the next cache cleanup is due and sleeps until then.  Cache cleanups might be many hours out, so the code improved from one wakeups every 5 seconds to one wakeup every couple of hours.&lt;/p&gt;

&lt;p&gt;nscd is a &lt;b&gt;very&lt;/b&gt; small drop in the bucket, though.  Just look at your machine and examine the running processes and those which are regularly started.  PowerTOP cannot realy help here (Arjan said something will be coming soon though).&lt;/p&gt;

&lt;p&gt;There is a tool which can help, though: systemtap.  Simply create a small script which traps syscalls the violators will use and disply process information.  The syscalls to use include: &lt;tt&gt;open&lt;/tt&gt;, &lt;tt&gt;stat&lt;/tt&gt;, &lt;tt&gt;access&lt;/tt&gt;, &lt;tt&gt;poll&lt;/tt&gt;, &lt;tt&gt;epoll&lt;/tt&gt;, &lt;tt&gt;select&lt;/tt&gt;, &lt;tt&gt;nanosleep&lt;/tt&gt;, &lt;tt&gt;futex&lt;/tt&gt;.  For the latter five it is a matter of small timeout values which is the problem.&lt;/p&gt;

&lt;p&gt;I&apos;ll post a script to do this soon (just not now).  But the guilty parties probably already know who they are.  Just don&apos;t do this quasi busy waiting!&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;If a program has to react to a file change or removal or creation, use &lt;tt&gt;inotify&lt;/tt&gt;&lt;/li&gt;
&lt;li&gt;for internal cleanups, choose reasonable values and then compute the timeout so that you don&apos;t wake up when nothing has to be done.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;If you want to see how &lt;b&gt;not&lt;/b&gt; to do it, look at something like the flash player (the proprietary one).  If you inadvertently have started it it&apos;ll remain active (even if no flash page is displayed) and it is basically busy waiting on something.&lt;/p&gt;

&lt;p&gt;Let&apos;s show the proprietary software world we can do better.&lt;/p&gt;</description>
  <comments>https://udrepper.livejournal.com/19041.html?view=comments#comments</comments>
  <lj:security>public</lj:security>
  <lj:reply-count>0</lj:reply-count>
  </item>
  <item>
  <guid isPermaLink='true'>https://udrepper.livejournal.com/18882.html</guid>
  <pubDate>Mon, 01 Oct 2007 15:09:36 GMT</pubDate>
  <title>Part 2 released</title>
  <author>udrepper</author>
  <link>https://udrepper.livejournal.com/18882.html</link>
  <description>&lt;p&gt;Jonathan and crew published part 2 of the paper.  If you have an LWN subscription you can read it &lt;a href=&quot;http://lwn.net/Articles/252125/&quot; target=&quot;_blank&quot; rel=&quot;nofollow&quot;&gt;here&lt;/a&gt;.&lt;/p&gt;</description>
  <comments>https://udrepper.livejournal.com/18882.html?view=comments#comments</comments>
  <category>linux programming</category>
  <lj:security>public</lj:security>
  <lj:reply-count>0</lj:reply-count>
  </item>
  <item>
  <guid isPermaLink='true'>https://udrepper.livejournal.com/18555.html</guid>
  <pubDate>Thu, 27 Sep 2007 17:45:53 GMT</pubDate>
  <title>Directory Reading</title>
  <author>udrepper</author>
  <link>https://udrepper.livejournal.com/18555.html</link>
  <description>&lt;p&gt;In the last weeks I have seen far too much code which reads directory content in horribly inefficient ways to let this slide.  Programmers really have to learn doing this efficiently.  Some of the instances I&apos;ve seen are in code which runs frequently.  Frequently as in once per second.  Doing it right can make a huge difference.&lt;/p&gt;

&lt;p&gt;The following is an exemplary piece of code.   Not taken from an actual project but it shows some of the problems quite well, all in one example.  I drop the error handling to make the point clearer.&lt;/p&gt;

&lt;pre&gt;
  DIR *dir = opendir(some_path);
  struct dirent *d;
  struct dirent d_mem;
  while (readdir_r(d, &amp;d_mem, &amp;d) == 0) {
    char path[PATH_MAX];
    snprintf(path, sizeof(path), &quot;%s/%s/somefile&quot;, some_path, d-&amp;gt;d_name);
    int fd = open(path, O_RDONLY);
    if (fd != -1) {
      ... do something ...
      close (fd);
    }
  }
  closedir(dir);
&lt;/pre&gt;

&lt;p&gt;How many things are inefficient at best and outright problematic in some cases?&lt;/p&gt;

&lt;p&gt;Let&apos;s enumerate:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Why use &lt;tt&gt;readdir_r&lt;/tt&gt;?&lt;/li&gt;
&lt;li&gt;Even the use of &lt;tt&gt;readdir&lt;/tt&gt; is dangerous.&lt;/li&gt;
&lt;li&gt;Creating a path string might exceed the &lt;tt&gt;PATH_MAX&lt;/tt&gt; limit.&lt;/li&gt;
&lt;li&gt;Using a path like this is racy.&lt;/li&gt;
&lt;li&gt;What if the directory contain entries which are not directories?&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;&lt;tt&gt;readdir_r&lt;/tt&gt; is only needed if multiple threads are using the &lt;i&gt;same&lt;/i&gt; directory stream.  I have yet to see a program where this really is the case.  In this toy example the stream (variable &lt;tt&gt;dir&lt;/tt&gt;) is definitely not shared between different threads.  Therefore the use of &lt;tt&gt;readdir&lt;/tt&gt; is just fine.  Should this matter?  Yes, it should, since &lt;tt&gt;readdir_r&lt;/tt&gt; has to copy the data in into the buffer provided by the user while &lt;tt&gt;readdir&lt;/tt&gt; has the possibility to avoid that.&lt;/p&gt;

&lt;p&gt;Instead of &lt;tt&gt;readdir&lt;/tt&gt; code should in fact use &lt;tt&gt;readdir64&lt;/tt&gt;.  The definition of the &lt;tt&gt;dirent&lt;/tt&gt; structure comes from an innocent time when hard drive with a couple of dozen MB of capacity were huge.  Things change and we need larger values for inode numbers etc.  Modern (i.e., 64-bit) ABIs do this by default but if the code is supposed to be used on 32-bit machines as well the &lt;tt&gt;*64&lt;/tt&gt; variants should always be used.&lt;/p&gt;

&lt;p&gt;Path length limits are becoming an ever-increasing problem.  Linux, like most Unix implementations, imposes a length limit on each filename string which is passed to a system call.  But this does not mean that in general path names have any length limit.  It just means that longer names have to be implicitly constructed through the use of multiple relative path names.  In the example above, what happens if &lt;tt&gt;some_path&lt;/tt&gt; is already close to &lt;tt&gt;PATH_MAX&lt;/tt&gt; bytes in size?  It means the &lt;tt&gt;snprintf&lt;/tt&gt; call will truncate the output.  This can and should of course be caught but this doesn&apos;t help the program.  It is crippled.&lt;/p&gt;

&lt;p&gt;Any use of filenames with path components (i.e., with one or more slashes in the name) is racy and an attacker change any of the contained path components.  This can lead to exploits.  In the example, the &lt;tt&gt;some_path&lt;/tt&gt; string itself might be long and traverse multiple directories.  A change in any of these will lead to the &lt;tt&gt;open&lt;/tt&gt; call not reaching the desired file or directory.&lt;/p&gt;

&lt;p&gt;Finally, while the code above works (the &lt;tt&gt;open&lt;/tt&gt; call will fail if &lt;tt&gt;d-&amp;gt;d_name&lt;/tt&gt; does not name a directory) it is anything but efficient.  In fact, the &lt;tt&gt;open&lt;/tt&gt; system calls are quite expensive.  Before any work is done, the kernel has to reserve a file descriptor.  Since file descriptors are a shared resource this requires coordination and synchronization which is expensive.  Synchronization also reduces parallelism, which might be a big issue in some code.  The &lt;tt&gt;open&lt;/tt&gt; call then has to follow the path which also is  not free.&lt;/p&gt;

&lt;p&gt;To make a long story short, here is how the code should look like (again, sans error handling):&lt;/p&gt;

&lt;pre&gt;
  DIR *dir = opendir(some_path);
  int dfd = dirfd(dir);
  struct dirent64 *d;
  while ((d = readdir64(dir)) != NULL) {
    if (d-&amp;gt;d_type != DT_DIR &amp;&amp; d-&amp;gt;d_type != DT_UNKNOWN)
      continue;
    char path[PATH_MAX];
    snprintf(path, sizeof(path), &quot;%s/somefile&quot;, d-&amp;gt;d_name);
    int fd = openat(dfd, path, O_RDONLY);
    if (fd != -1) {
      ... do something ...
      close (fd);
    }
  }
  closedir(dir);
&lt;/pre&gt;

&lt;p&gt;This rewrite addresses all the issues.  It uses &lt;tt&gt;readdir64&lt;/tt&gt; which will do just fine in this case and it is safe when it comes to huge disk drives.  It uses the &lt;tt&gt;d_type&lt;/tt&gt; field of the &lt;tt&gt;dirent64&lt;/tt&gt; to check whether we already know the file is no directory.  Most of Linux&apos;s directories today fill in the &lt;tt&gt;d_type&lt;/tt&gt; field correctly (including all the pseudo filesystems like &lt;tt&gt;sysfs&lt;/tt&gt; and &lt;tt&gt;proc&lt;/tt&gt;).  Those file systems which do not have the information handy fill in &lt;tt&gt;DT_UNKNOWN&lt;/tt&gt; which is why the code above allows this case, too.  In some program one also might want to allow &lt;tt&gt;DT_LNK&lt;/tt&gt; since a symbolic link might point to a directory.  But more often enough this is not the case and not following symlinks is a security measure.&lt;/p&gt;

&lt;p&gt;Finally, the new code uses &lt;tt&gt;openat&lt;/tt&gt; to open the file.  This avoids the length path lookup and it closes most of the races of the original &lt;tt&gt;open&lt;/tt&gt; call since the pathname lookup starts at the directory read by &lt;tt&gt;readdir64&lt;/tt&gt;.  Any change to the filesystem below this directory has no effect on the &lt;tt&gt;openat&lt;/tt&gt; call.  Also, since now the generated path is very short (just the maximum of 256 bytes for &lt;tt&gt;d_name&lt;/tt&gt; plus 10 we know that the buffer &lt;tt&gt;path&lt;/tt&gt; is sufficient.&lt;/p&gt;

&lt;p&gt;It is easy enough to apply these changes to all the places which read directories.  The result will be small, faster, and safer code.&lt;/p&gt;</description>
  <comments>https://udrepper.livejournal.com/18555.html?view=comments#comments</comments>
  <category>programming linux</category>
  <lj:security>public</lj:security>
  <lj:reply-count>0</lj:reply-count>
  </item>
  <item>
  <guid isPermaLink='true'>https://udrepper.livejournal.com/18193.html</guid>
  <pubDate>Fri, 21 Sep 2007 20:41:39 GMT</pubDate>
  <title>The Series is Underway</title>
  <author>udrepper</author>
  <link>https://udrepper.livejournal.com/18193.html</link>
  <description>Jon Corbet has edited the first two sections of the document I mentioned earlier &lt;a href=&quot;http://udrepper.livejournal.com/17682.html&quot; target=&quot;_blank&quot;&gt;here&lt;/a&gt; and &lt;a href=&quot;http://udrepper.livejournal.com/17280.html&quot; target=&quot;_blank&quot;&gt;here&lt;/a&gt;.&lt;br /&gt;&lt;br /&gt;The document will be published in multiple installments, beginning with &lt;a href=&quot;http://lwn.net/Articles/250967/&quot; target=&quot;_blank&quot; rel=&quot;nofollow&quot;&gt;Sections 1 and 2&lt;/a&gt; which are available now.  Since LWN is a business the reasonable limitation is put in place that for the first week only subscribers have access to it.&lt;br /&gt;&lt;br /&gt;So, get a &lt;a href=&quot;https://lwn.net/subscribe/&quot; target=&quot;_blank&quot; rel=&quot;nofollow&quot;&gt;subscription&lt;/a&gt; to LWN.&lt;br /&gt;&lt;br /&gt;If you find mistakes in the text let me know directly, either as a comment here or as a personal mail.  Don&apos;t bother J on with that.</description>
  <comments>https://udrepper.livejournal.com/18193.html?view=comments#comments</comments>
  <category>programming</category>
  <lj:security>public</lj:security>
  <lj:reply-count>0</lj:reply-count>
  </item>
  <item>
  <guid isPermaLink='true'>https://udrepper.livejournal.com/18038.html</guid>
  <pubDate>Wed, 19 Sep 2007 21:55:10 GMT</pubDate>
  <title>SHA for crypt</title>
  <author>udrepper</author>
  <link>https://udrepper.livejournal.com/18038.html</link>
  <description>Just a short note: I added SHA support to the Unix crypt implementation in glibc.  The reason for all this (including replies to the extended &quot;NIH&quot; complaints) can be found &lt;a href=&quot;http://people.redhat.com/drepper/sha-crypt.html&quot; target=&quot;_blank&quot; rel=&quot;nofollow&quot;&gt;here&lt;/a&gt;.</description>
  <comments>https://udrepper.livejournal.com/18038.html?view=comments#comments</comments>
  <category>security</category>
  <lj:security>public</lj:security>
  <lj:reply-count>0</lj:reply-count>
  </item>
  <item>
  <guid isPermaLink='true'>https://udrepper.livejournal.com/17682.html</guid>
  <pubDate>Tue, 14 Aug 2007 03:43:33 GMT</pubDate>
  <title>Publishing Update</title>
  <author>udrepper</author>
  <link>https://udrepper.livejournal.com/17682.html</link>
  <description>&lt;p&gt;A few weeks back I asked how I should publish the document on memory and cache handling.  I got quite some feedback.&lt;/p&gt;

&lt;ul&gt;

&lt;li&gt;There was the usual &lt;q&gt;it doesn&apos;t matter but I want it for free&lt;/q&gt; crowd.&lt;/li&gt;

&lt;li&gt;Then there was the &lt;q&gt;even $8 for a book is too much for me&lt;/q&gt;.  These are people from outside the US and $8 translated to local currency and income is certainly far too much for many people.  I do not throw this group in with the first.&lt;/li&gt;

&lt;li&gt;Several people (all or mostly US-based) thought the idea of printed paper to be nice.  The price was no issue.&lt;/li&gt;

&lt;li&gt;Most people said a freely PDF is more important than a printed copy.  Some derogatory comments about lecturers who require books were heard.  Others said editing isn&apos;t important.&lt;/li&gt;

&lt;/ul&gt;

&lt;p&gt;Because of this first obnoxious  group of people I would probably have gone with a print-only route.  This attitude that just because somebody works on free software he always has to make everything available for free makes me sick.  These are most probably the same people who never in their life produced anything that other found of value or they are the criminals working on (mostly embedded) project exploiting free software.&lt;/p&gt;

&lt;p&gt;But since I really want the document to be widely distributed and available to places where $8 is too much money I will release the PDF for free.  But this won&apos;t happen right away.  Unlike some of the people making comments I do think that editing is important.  Fortunately having professional editing and a free PDF don&apos;t exclude each other.&lt;/p&gt;

&lt;p&gt;I&apos;ll not go with a publisher (esp not these $%# at O&apos;Reilly, as several people suggested).  This would in most cases have precluded retaining the copyright and making the text available for free.&lt;/p&gt;

&lt;p&gt;Instead the nice people at &lt;a href=&quot;http://lwn.net/&quot; target=&quot;_blank&quot; rel=&quot;nofollow&quot;&gt;LWN&lt;/a&gt;, Jonathan Corbet and crew, will edit the document.  They will then serialize it, I guess, along with the weekly edition.  It&apos;s up to Jon to make this decision.  The document has 8 large section including introduction which means &lt;i&gt;my&lt;/i&gt; guess is that after 7 installments the whole document is published.  Once this has happened I&apos;ll then make the whole updated and edited PDF available.&lt;/p&gt;

&lt;p&gt;This means if you think it&apos;s worth it, get a subscription to the LWN instead of waiting a week to read it for free.&lt;/p&gt;

&lt;p&gt;So in summary, I get professional editing, keep the copyright, and might be able to help getting some more subscribers for the LWN.  Win, win, win.  If the &lt;q&gt;L&lt;/q&gt; in LWN bothers you I&apos;ve news for you: the document itself is very Linux-centric.&lt;/p&gt;

&lt;p&gt;I haven&apos;t forgotten the printed version.  I&apos;ve read a bit more of the Lulu documentation.  Apparently there is a model where I don&apos;t have to pay anything.  People ordering the book pay a per-copy price and that&apos;s it (apparently with discounts for larger orders).  If I submit it in letter/A4 format I don&apos;t have to do any reformatting and the price is less (for the color print) since there are fewer pages.&lt;/p&gt;

&lt;p&gt;I&apos;ll probably try to do this after the PDF is freely available.  People who like to have something in their hands will have their wishes.  The only problem I see right now is that Lulu has a stupid requirement that the PDF documents must be generated with proprietary tools from Adobe.  Of course I don&apos;t do this, I use pdfTeX.  If this proves to be the case I guess I&apos;ll have to have a word with Bob Young...&lt;/p&gt;</description>
  <comments>https://udrepper.livejournal.com/17682.html?view=comments#comments</comments>
  <lj:security>public</lj:security>
  <lj:reply-count>0</lj:reply-count>
  </item>
  <item>
  <guid isPermaLink='true'>https://udrepper.livejournal.com/17577.html</guid>
  <pubDate>Mon, 13 Aug 2007 23:52:58 GMT</pubDate>
  <title>Increasing Virtualization Insanity</title>
  <author>udrepper</author>
  <link>https://udrepper.livejournal.com/17577.html</link>
  <description>&lt;p&gt;People are starting to realize how broken the Xen model is with its privileged Dom0 domain.  But the actions they want to take are simply ridiculous: they want to add the drivers back into the hypervisor.  There are many technical reasons why this is a terrible idea.  You&apos;d have to add (back, mind you, Xen before version 2 did this) all the PCI handling and lots of other lowlevel code which is now maintained as part of the Linux kernel.  This would of course play nicely into Xensource&apos;s (the company) pocket.   Their technical people so far turn this down but I have no faith in this group: sooner or later they want to be independent of OS vendors and have their own mini-OS in the hypervisor.  Adios remaining few advantages of the hypervisor model. But this is of course also the direction of VMWare who loudly proclaim that in the future we won&apos;t have OS as they exist today. Instead only domains with mini-OS which are ideally only hooks into the hypervisor OS where single applications run.&lt;/p&gt;

&lt;p&gt;I hope everybody realizes the insanity of this:&lt;/p&gt;

&lt;ul&gt;

&lt;li&gt;If they really mean single application this must also mean single-process.  If not, you&apos;ll have to implement an OS which can provide multi-process services.  But this means that you either have no support to create processes or you rely on an mini-OS which is a front for the hypervisor.  In VMWare&apos;s case this is some proprietary mini-OS and I imagine Xensource would like to do the very same.&lt;/li&gt;

&lt;li&gt;Imagine that you have such application domains.  All nicely separated because replicated.  The result is a maintainance nightmare.  What if a component which is needed in all application domains has to be updated?  In a traditional system you update the one instance per machine/domain.  With application domains you have to update every single one and not forget one.&lt;/li&gt;

&lt;/ul&gt;

And worst of all:

&lt;ul&gt;

&lt;li&gt;Don&apos;t people realize that this is the KVM model just implemented &lt;b&gt;much&lt;/b&gt; poorer and more proprietary?  If you invite drivers and all the infrastructure into the hypervisor it is not small enough anymore to have a complete code review.  I.e., you end up with a full OS which is too large for that.  Why not use one which already works: Linux. &lt;/li&gt;

&lt;/ul&gt;

&lt;p&gt;I fear I have to repeat myself over and over again until the last person recognizes that the hypervisor model does not work for the type of virtualization for commodity hardware  we try to achieve.  Using a hypervisor was simply the first idea which popped into people&apos;s head since it was already done before in quite different environments.  The change from Xen v1 to v2 should have shown how rotten the model is.  Only when you take a step back you can see the whole picture and realize the KVM model is not only better, it&apos;s the only logical choice.&lt;/p&gt;

&lt;p&gt;I know people have invested into Xen and that KVM is not yet there yet but a) there has been a lot of progress in KVM-land and b) the performance is constantly improving and especially with next year&apos;s processor updates hardware virtualization costs will go down even further.&lt;/p&gt;

&lt;p&gt;For sysadmin types this means: do what you have to do with Xen for now.  But keep the investments small. For developers this means: don&apos;t let yourself be tied to a platform.  Use an abstraction layer such as libvirt to bridge over the differences.  For architects this means: don&apos;t looking to Xen for answers, base your new designs on KVM.&lt;/p&gt;</description>
  <comments>https://udrepper.livejournal.com/17577.html?view=comments#comments</comments>
  <category>virtualization</category>
  <lj:security>public</lj:security>
  <lj:reply-count>0</lj:reply-count>
  </item>
  <item>
  <guid isPermaLink='true'>https://udrepper.livejournal.com/17280.html</guid>
  <pubDate>Mon, 25 Jun 2007 17:08:04 GMT</pubDate>
  <title>How to publish?</title>
  <author>udrepper</author>
  <link>https://udrepper.livejournal.com/17280.html</link>
  <description>&lt;p&gt;That is meant as a question to the readers.  The problem I have right now is that I have more or less finished the paper accompanying one of the talks I gave at the Red Hat Summit in Nashville last year.  The slides for the talk about &lt;a href=&quot;http://people.redhat.com/drepper/cpucache-slides.pdf&quot; target=&quot;_blank&quot; rel=&quot;nofollow&quot;&gt;CPU Caches&lt;/a&gt; are available.  But quite honestly, as most slide sets, they don&apos;t do the topic any justice.  I had to compress things to &amp;lt; 45 mins which is of course not enough.  The paper covers everything I can currently think of and which makes sense with relation to CPU caches and CPU memory, as far as programmers are concerned (nothing for hardware people).  The title I currently use it&lt;/p&gt;

&lt;blockquote&gt;What Every Programmer Should Know About Memory&lt;/blockquote&gt;

&lt;p&gt;and I think this is adequate.&lt;/p&gt;

&lt;p&gt;For this reason I usually write a paper on the important topics I talk about.  And this topic qualifies.  I consider the topic especially important since it&apos;s almost never treated in the software world &lt;b&gt;at all&lt;/b&gt;.  College grads today in most cases have not the slightest clue about this topic.  Ideally I&apos;d like the paper be picked up by some lecturers (like they do for many of my other publications) and use it in a course.  Heck, I&apos;m even willing to teach it myself if that is what it takes to get credibility.&lt;/p&gt;

&lt;p&gt;The problem I&apos;m facing is that the document is (using my usual paper style, two column etc) around 100 densely packed  pages long.  Some of the people I&apos;ve shown it to suggested that it should rather be published as a book.  I&apos;m a bit unsure about this.  I have a few publisher who for a long time keep pestering me about writing something for them (some even prematurely submitted titles to distributors!).  One I talked to would be willing to print it even though it&apos;s thin for a book.  But there are a lot of pluses and minuses all around:&lt;/p&gt;

&lt;dl&gt;
  &lt;dt&gt;My PDF only&lt;/dt&gt;

  &lt;dd&gt;Going this route means the document is easy to change and extend.  The format is exactly as I want it.  The visibility is restricted, not in the print market.  No professional review.  Due to the size (and use of color) it is hard to print.&lt;/dd&gt;

  &lt;dt&gt;Go with a publisher&lt;/dt&gt;

  &lt;dd&gt;Professional editing, maybe a college edition, visibility through listing in catalogs etc.  Additionally available as e-book.  But it likely means the color has to go (printing in color is expensive) and there will be no free-of-charge copy.  Getting a revision out will be almost impossible.&lt;/dd&gt;

  &lt;dt&gt;Go with Lulu&lt;/dt&gt;

  &lt;dd&gt;The alternative publishing route: I could submit an appropriately formatted PDF to Lulu and have them publish it.  Demand printing, ISBN available.  B&amp;W and color printing possible.  Even e-books if anybody cares.  No professional editing.&lt;/dd&gt;

&lt;/dl&gt;

&lt;p&gt;Going with Lulu has the advantages I want but it&apos;s quite an effort.  And there are costs associated with it.  I do not plan to make money out of all this but I&apos;d have to recover the costs.  Excess gains would probably go to charity (in my case this is the &lt;a href=&quot;http://www.mbayaq.org/&quot; target=&quot;_blank&quot; rel=&quot;nofollow&quot;&gt;Monterey Bay Aquarium&lt;/a&gt; in case anybody is interested).&lt;/p&gt;

&lt;p&gt;So, the questions I have and would like to get some feedback on are:&lt;/p&gt;

&lt;ul&gt;

&lt;li&gt;Are printed copies wanted at all?  Especially for those teaching, is it a prerequisite?&lt;/li&gt;

&lt;li&gt;If yes, do you prefer a professional, more expensive book?&lt;/li&gt;

&lt;li&gt;Or perhaps an amateur-ish publication which is either B&amp;W and cheap (I guess not much more than $10)...&lt;/li&gt;

&lt;li&gt;... or a colored print for around $30.  The paper has currently around 60 diagrams and color helps.&lt;/li&gt;

&lt;/ul&gt;

&lt;p&gt;If you have an opinion and a mail or add a comment to the blog (which won&apos;t be published).  I know it is not easy to answer given that you haven&apos;t seen the material.  But this is the same for most books, isn&apos;t it?  Look at the slides and assume 100 times more details.  I doubt I&apos;ll find many people who know all these details now (I had to do research myself).&lt;/p&gt;</description>
  <comments>https://udrepper.livejournal.com/17280.html?view=comments#comments</comments>
  <lj:security>public</lj:security>
  <lj:reply-count>0</lj:reply-count>
  </item>
  <item>
  <guid isPermaLink='true'>https://udrepper.livejournal.com/17109.html</guid>
  <pubDate>Fri, 01 Jun 2007 13:53:06 GMT</pubDate>
  <title>grep and color</title>
  <author>udrepper</author>
  <link>https://udrepper.livejournal.com/17109.html</link>
  <description>&lt;p&gt;I cannot believe there are still people who are surprised they see me working with the command line on my machine or when I tell them otherwise the the output of grep can use highlighting.  Just add &lt;tt&gt;--color&lt;/tt&gt; to the command line (with the optional argument just like ls).  I&apos;ve implemented that more than six years ago.  In my &lt;tt&gt;.bashrc&lt;/tt&gt; I  have the following:&lt;/p&gt;

&lt;pre&gt;
alias egrep=&apos;egrep --color=tty -d skip&apos;
alias egrpe=&apos;egrep --color=tty -d skip&apos;
alias fgrep=&apos;fgrep --color=tty -d skip&apos;
alias fgrpe=&apos;fgrep --color=tty -d skip&apos;
alias grep=&apos;grep --color=tty -d skip&apos;
alias grpe=&apos;grep --color=tty -d skip&apos;
&lt;/pre&gt;

&lt;p&gt;Yes, I mistype &lt;tt&gt;grep&lt;/tt&gt; often enough to warrant the extra aliases.  Using &lt;tt&gt;tty&lt;/tt&gt; as the color mode mean that if I pipe the output into another program there won&apos;t be any color escape sequences added which could irritate those programs.&lt;/p&gt;

&lt;p&gt;Just make your life easier and add such aliases, too.&lt;/p&gt;</description>
  <comments>https://udrepper.livejournal.com/17109.html?view=comments#comments</comments>
  <lj:security>public</lj:security>
  <lj:reply-count>0</lj:reply-count>
  </item>
  <item>
  <guid isPermaLink='true'>https://udrepper.livejournal.com/16844.html</guid>
  <pubDate>Tue, 22 May 2007 18:46:46 GMT</pubDate>
  <title>pthread_t and similar types</title>
  <author>udrepper</author>
  <link>https://udrepper.livejournal.com/16844.html</link>
  <description>&lt;p&gt;Constantly people complain that the runtime does not catch their mistakes.  They are hiding behind this requirement in the POSIX specification (for &lt;tt&gt;pthread_join&lt;/tt&gt; in this case, also applies to &lt;tt&gt;pthread_kill&lt;/tt&gt; and similar functions):&lt;/p&gt;

&lt;pre&gt;
       The pthread_join() function shall fail if:
       [...]

       ESRCH  No thread could be found corresponding to that specified by the given thread ID.
&lt;/pre&gt;

&lt;p&gt;The glibc implementation follows this requirement to the letter.  *IFF* we can detect that the thread descriptor is invalid we do return &lt;tt&gt;ESRCH&lt;/tt&gt;.&lt;/p&gt;

&lt;p&gt;&lt;b&gt;But&lt;/b&gt;: the above does not mean that all uses of invalid thread descriptors must result in &lt;tt&gt;ESRCH&lt;/tt&gt; errors.  The reason is simple: the standard does not restrict the implementation in any way in the definition of the type &lt;tt&gt;pthread_t&lt;/tt&gt;.  It does not even have to be an arithmetic type.  This means it is valid to use a pointer type and this is just what NPTL does.&lt;/p&gt;

&lt;p&gt;Nobody argues that functions like &lt;tt&gt;strcpy&lt;/tt&gt; should not dump a core in case the buffer is invalid.  The same for &lt;tt&gt;pthread_attr_t&lt;/tt&gt; references passed to &lt;tt&gt;pthread_attr_init&lt;/tt&gt; etc.  The use of &lt;tt&gt;pthread_t&lt;/tt&gt; when defined as a pointer is no different.  The only complication is in the understanding that &lt;tt&gt;pthread_t&lt;/tt&gt; can be a pointer type.  This is obvious for &lt;tt&gt;void*&lt;/tt&gt; etc.&lt;/p&gt;

&lt;p&gt;In the POSIX committee we discussed several times changing the &lt;tt&gt;pthread_join&lt;/tt&gt; and &lt;tt&gt;pthread_kill&lt;/tt&gt; man pages.  The &lt;tt&gt;ESRCH&lt;/tt&gt; errors could be marked as &lt;q&gt;may fail&lt;/q&gt;.  But&lt;/p&gt;

&lt;ol&gt;

&lt;li&gt;this really is not necessary, see above.&lt;/li&gt;

&lt;li&gt;it would mean we have to go through the entire specification and treat every other place where this is an issue the same way.&lt;/li&gt;

&lt;/ol&gt;

&lt;p&gt;If somebody wants to do the work associated with the second step above and we have confidence in the results, we (= Austin Group) might make the change at some later date.  But it is a rather high risk for no real gain.  Programmers have to educate themselves anyway.&lt;/p&gt;

&lt;p&gt;What remains is the question: how can programs avoid these mistakes?  It is actually pretty simple: the program should make sure that no calls to &lt;tt&gt;pthread_kill&lt;/tt&gt;, for instance, can happen when the thread is exiting.  One way to solve this problem is:&lt;/p&gt;

&lt;ol&gt;

&lt;li&gt;Associate a variable &lt;tt&gt;running&lt;/tt&gt; of some sort and a mutex with each thread.

&lt;li&gt;In the function started by &lt;tt&gt;pthread_create&lt;/tt&gt; (the thread function) set &lt;tt&gt;running&lt;/tt&gt; to true.&lt;/li&gt;

&lt;li&gt;Before returning from the thread function or calling &lt;tt&gt;pthread_exit&lt;/tt&gt; or in a cancellation handler acquire the mutex, set &lt;tt&gt;running&lt;/tt&gt; to false, unlock the mutex, and proceed.&lt;/li&gt;

&lt;li&gt;Any thread trying to use &lt;tt&gt;pthread_kill&lt;/tt&gt; etc first must get the mutex for the target thread, if &lt;tt&gt;running&lt;/tt&gt; is true call &lt;tt&gt;pthread_kill&lt;/tt&gt;, and finally unlock the mutex.&lt;/li&gt;

&lt;/ol&gt;

&lt;p&gt;This ensures that no invalid descriptor is used.  But I can already hear people complain:&lt;/p&gt;

&lt;blockquote&gt;This is too expensive!&lt;/blockquote&gt;

&lt;p&gt;That is ridiculous.  The implementation would have to do something similar if it would try to catch bad thread descriptors.  In fact, it would have to do more.  What is important is to recognize that this price would have to be paid by &lt;sl&gt;every&lt;/sl&gt; program, not just the buggy ones.  This is wrong.  Only those people who need this extra protection should pay the price.&lt;/p&gt;

&lt;blockquote&gt;But I don&apos;t have control over the code calling &lt;tt&gt;pthread_create&lt;/tt&gt;!&lt;/blockquote&gt;

&lt;p&gt;Boo hoo, cry me a river.  Don&apos;t expect sympathy for using proprietary software.  I will never allow good free software to be shackled because of proprietary code.  If  you cannot get this changed in the code you pay good money for this just means it is time to find a new supplier or, even better, use free software.&lt;/p&gt;

&lt;p&gt;In summary, this is entirely a problem of the programs which experience them.  Existing Linux systems are proof that it is possible to write complex programs without requiring the implementation to help incompetent programmers.  We will have a few more words in the next revision of the POSIX specification which talk about this issue.  But I expect they will be ignored anyway and all focus remains on the &lt;q&gt;shall fail&lt;/q&gt; errors of &lt;tt&gt;pthread_kill&lt;/tt&gt; etc.&lt;/p&gt;</description>
  <comments>https://udrepper.livejournal.com/16844.html?view=comments#comments</comments>
  <category>programming posix</category>
  <lj:security>public</lj:security>
  <lj:reply-count>0</lj:reply-count>
  </item>
  <item>
  <guid isPermaLink='true'>https://udrepper.livejournal.com/16394.html</guid>
  <pubDate>Sat, 12 May 2007 17:49:32 GMT</pubDate>
  <title>The Growing Importance of Parallel Programming</title>
  <author>udrepper</author>
  <link>https://udrepper.livejournal.com/16394.html</link>
  <description>At the 2007 Red Hat Summit in San Diego which just which just wrapped up yesterday I gave a talk about parallel programming which the marketing folks retitled &lt;q&gt;Programming for tomorrow&apos;s high speed processors, today&lt;/q&gt;.&lt;br /&gt;&lt;br /&gt;The crux of the talk is that programmers in the future cannot always rely on improving hardware to make their programs run faster.  This is summarized nicely in the following graph which I generated from performance data for x86 processors.&lt;br /&gt;&lt;br /&gt;&lt;img src=&quot;https://imgprx.livejournal.net/984474d5014af1953735608725ffd731d7551f167488cfaddb65e13318f16182/P2WlxyVijxKghGBq98xWWUMdsf-ah7h0z0uNV75WwcLW9xDVgY-mB0dpBFVyDl10pA1Wky_bcwZXG10ekBk1_ENBm3nIevQ:5tudArR5euXHpX8V71fqEg&quot; fetchpriority=&quot;high&quot; /&gt;&lt;br /&gt;&lt;br /&gt;The crucial part is the divergence of the two lines going forward and the flattening of the blue line.  This means programs which are not able to take advantage of ever increasing numbers of processing cores simply won&apos;t run (much) faster.&lt;br /&gt;&lt;br /&gt;Parallel programming is hard.  There are algorithms to change to allow more than one thread in parallel.  Well, not necessarily thread, especially on Linux one should use processes if the sharing requirement between the processes makes this feasible.&lt;br /&gt;&lt;br /&gt;There are data structures to lay out correctly to allow a) vectorization and b) data parallelization.  Vectorization is important if one wants to come even close to the peak performance listed for the processor.  But when you do this you also have to know a lot about CPU design (pipelines etc), caches, and memory.&lt;br /&gt;&lt;br /&gt;And then there is something people might have heard about but didn&apos;t really register: co-processors are back.  Intel&apos;s Geneseo and AMD&apos;s Torrenza are technologies to couple 3rd party processors tightly to the existing processor-memory mash.&lt;br /&gt;&lt;br /&gt;In general I think the industry is entirely ill-prepared for these upcoming changes.  Many/most programmers are not able to write code with these requirements.  Companies and other organizations will have to invest into education.  The system provides (like Red Hat) have to find ways to make parallel programming easier.&lt;br /&gt;&lt;br /&gt;One big step in the right direction is OpenMP.  Officially supported in gcc 4.2 Red Hat has backported the changes to our gcc 4.1 used in RHEL5 and Fedora Core 6 and later.  Not only does OpenMP allow relatively easy conversion of existing code, it also frees the programmer from dealing with all the details of thread lifetime handling, thread stacks, etc.  Even mutual exclusion happens at a higher level.  All this is good, It will make programmers more productive if only it is used more often.&lt;br /&gt;&lt;br /&gt;But there is one more thing: the OpenMP runtime is basically in complete control.  It can decide on using just one thread or many threads.  It can decide where to run threads and many more things.  All these details are hidden from the programmer.  This is a good thing since it allows the runtime to perform optimizations.  I&apos;ll have more about this at a later date.&lt;br /&gt;&lt;br /&gt;In summary, programmers have to learn, re-learn or for the first time, about parallelism.  I think the topic of this talk is very important.  If you are a Red Hat customer you could potentially ask for somebody from Red Hat to come in and talk about these issues.  I&apos;ll give the slides and the details to our consulting organization and possibly also sales engineers.  I cannot make any promises but I&apos;ll encourage those gals and guys to be willing to talk about this.  If you&apos;re a big enough customer and you demand it, I might (have to) come out myself, if this is wanted.  Or somebody can organize gatherings in places I have to go to anyway and have me speak there.</description>
  <comments>https://udrepper.livejournal.com/16394.html?view=comments#comments</comments>
  <lj:security>public</lj:security>
  <lj:reply-count>0</lj:reply-count>
  </item>
  <item>
  <guid isPermaLink='true'>https://udrepper.livejournal.com/16362.html</guid>
  <pubDate>Sat, 12 May 2007 17:04:35 GMT</pubDate>
  <title>nscd and DNS TTL</title>
  <author>udrepper</author>
  <link>https://udrepper.livejournal.com/16362.html</link>
  <description>Recently some people spread their non-existing knowledge about nscd (Name Service Cache Daemon) by claiming it ignores the TTL (time-to-live) value a DNS server returns.  As far as I know this rampant ignorance is especially wide-spread in the ubuntu world.  They claim that for this reason one has to run a local, caching DNS server.  This is complete nonsense.  nscd does handle TTL for a long time now (committed to the public CVS on 2004-9-15).  All reasonable requests are handled,  i.e., all &lt;tt&gt;getaddrinfo&lt;/tt&gt; requests.&lt;br /&gt;&lt;br /&gt;As I have pointed out many times before (&lt;a href=&quot;http://udrepper.livejournal.com/16116.html&quot; target=&quot;_blank&quot;&gt;here&lt;/a&gt; and &lt;a href=&quot;http://people.redhat.com/drepper/userapi-ipv6.html&quot; target=&quot;_blank&quot; rel=&quot;nofollow&quot;&gt;here&lt;/a&gt; and in other places), it is completely unacceptable today to use &lt;tt&gt;gethostbyname&lt;/tt&gt; etc.  These functions simply don&apos;t work.  Which is why I found it unnecessary to make the implementation of nscd more complicated and add more compatiblity and maintenance problems just to fix one of the many problems these interfaces have.  Just don&apos;t use them and convert all your programs (e.g., I think we&apos;ve done just that for all of RHEL and Fedora nowadays).  Also don&apos;t use&lt;br /&gt;&lt;br /&gt;&lt;pre&gt;
  getent hosts some.host
&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;You have to use&lt;br /&gt;&lt;br /&gt;&lt;pre&gt;
  getent ahosts some.host
&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;For all &lt;tt&gt;getaddrinfo&lt;/tt&gt; lookups the TTL value from DNS replies takes precedence over the TTL value from &lt;tt&gt;/etc/nscd.conf&lt;/tt&gt;.  The latter is used for services which do not provide a TTL themselves (today all other services).</description>
  <comments>https://udrepper.livejournal.com/16362.html?view=comments#comments</comments>
  <lj:security>public</lj:security>
  <lj:reply-count>1</lj:reply-count>
  </item>
</channel>
</rss>
