]> pere.pagekite.me Git - homepage.git/blobdiff - blog/index.rss
Generated.
[homepage.git] / blog / index.rss
index c899898782148918eb30fa2948afd436e644c332..4541e6eaad1487651ed01d255fc470b7c07cf185 100644 (file)
@@ -6,6 +6,234 @@
                 <link>http://people.skolelinux.org/pere/blog/</link>
                 <atom:link href="http://people.skolelinux.org/pere/blog/index.rss" rel="self" type="application/rss+xml" />
        
+       <item>
+               <title>Testing if a file system can be used for home directories...</title>
+               <link>http://people.skolelinux.org/pere/blog/Testing_if_a_file_system_can_be_used_for_home_directories___.html</link>
+               <guid isPermaLink="true">http://people.skolelinux.org/pere/blog/Testing_if_a_file_system_can_be_used_for_home_directories___.html</guid>
+                <pubDate>Sun, 8 Aug 2010 21:20:00 +0200</pubDate>
+               <description>
+&lt;p&gt;A few years ago, I was involved in a project planning to use
+Windows file servers as home directory servers for Debian
+Edu/Skolelinux machines.  This was thought to be no problem, as the
+access would be through the SMB network file system protocol, and we
+knew other sites used SMB with unix and samba as the file server to
+mount home directories without any problems.  But, after months of
+struggling, we had to conclude that our goal was impossible.&lt;/p&gt;
+
+&lt;p&gt;The reason is simply that while SMB can be used for home
+directories when the file server is Samba running on Unix, this only
+work because of Samba have some extensions and the fact that the
+underlying file system is a unix file system.  When using a Windows
+file server, the underlying file system do not have POSIX semantics,
+and several programs will fail if the users home directory where they
+want to store their configuration lack POSIX semantics.&lt;/p&gt;
+
+&lt;p&gt;As part of this work, I wrote a small C program I want to share
+with you all, to replicate a few of the problematic applications (like
+OpenOffice.org and GCompris) and see if the file system was working as
+it should.  If you find yourself in spooky file system land, it might
+help you find your way out again.  This is the fs-test.c source:&lt;/p&gt;
+
+&lt;pre&gt;
+/*
+ * Some tests to check the file system sematics.  Used to verify that
+ * CIFS from a windows server do not work properly as a linux home
+ * directory.
+ * License: GPL v2 or later
+ * 
+ * needs libsqlite3-dev and build-essential installed
+ * compile with: gcc -Wall -lsqlite3 -DTEST_SQLITE fs-test.c -o fs-test
+*/
+
+#define _FILE_OFFSET_BITS 64
+#define _LARGEFILE_SOURCE 1
+#define _LARGEFILE64_SOURCE 1
+
+#define _GNU_SOURCE /* for asprintf() */
+
+#include &lt;errno.h&gt;
+#include &lt;fcntl.h&gt;
+#include &lt;stdio.h&gt;
+#include &lt;string.h&gt;
+#include &lt;stdlib.h&gt;
+#include &lt;sys/file.h&gt;
+#include &lt;sys/stat.h&gt;
+#include &lt;sys/types.h&gt;
+#include &lt;unistd.h&gt;
+
+#ifdef TEST_SQLITE
+/*
+ * Test sqlite open, as done by gcompris require the libsqlite3-dev
+ * package and linking with -lsqlite3.  A more low level test is
+ * below.
+ * See also &lt;URL: http://www.sqlite.org./faq.html#q5 &gt;.
+ */
+#include &lt;sqlite3.h&gt;
+#define CREATE_TABLE_USERS                                              \
+  &quot;CREATE TABLE users (user_id INT UNIQUE, login TEXT, lastname TEXT, firstname TEXT, birthdate TEXT, class_id INT ); &quot;
+int test_sqlite_open(void) {
+  char *zErrMsg;
+  char *name = &quot;testsqlite.db&quot;;
+  sqlite3 *db=NULL;
+  unlink(name);
+  int rc = sqlite3_open(name, &amp;db);
+  if( rc ){
+    printf(&quot;error: sqlite open of %s failed: %s\n&quot;, name, sqlite3_errmsg(db));
+    sqlite3_close(db);
+    return -1;
+  }
+
+  /* create tables */
+  rc = sqlite3_exec(db,CREATE_TABLE_USERS, NULL,  0, &amp;zErrMsg);
+  if( rc != SQLITE_OK ){
+    printf(&quot;error: sqlite table create failed: %s\n&quot;, zErrMsg);
+    sqlite3_close(db);
+    return -1;
+  }
+  printf(&quot;info: sqlite worked\n&quot;);
+  sqlite3_close(db);
+  return 0;
+}
+#endif /* TEST_SQLITE */
+
+/*
+ * Demonstrate locking issue found in gcompris using sqlite3.  This
+ * work with ext3, but not with cifs server on Windows 2003.  This is
+ * done in the sqlite3 library.
+ * See also
+ * &lt;URL:http://www.cygwin.com/ml/cygwin/2001-08/msg00854.html&gt; and the
+ * POSIX specification
+ * &lt;URL:http://www.opengroup.org/onlinepubs/009695399/functions/fcntl.html&gt;.
+ */
+int test_gcompris_locking(void) {
+  struct flock fl;
+  char *name = &quot;testsqlite.db&quot;;
+  unlink(name);
+  int fd = open(name, O_RDWR|O_CREAT|O_LARGEFILE, 0644);
+  printf(&quot;info: testing fcntl locking\n&quot;);
+
+  fl.l_whence = SEEK_SET;
+  fl.l_pid    = getpid();
+  printf(&quot;  Read-locking 1 byte from 1073741824&quot;);
+  fl.l_start  = 1073741824;
+  fl.l_len    = 1;
+  fl.l_type   = F_RDLCK;
+  if (0 != fcntl(fd, F_SETLK, &amp;fl) ) printf(&quot; - error!\n&quot;); else printf(&quot;\n&quot;);
+
+  printf(&quot;  Read-locking 510 byte from 1073741826&quot;);
+  fl.l_start  = 1073741826;
+  fl.l_len    = 510;
+  fl.l_type   = F_RDLCK;
+  if (0 != fcntl(fd, F_SETLK, &amp;fl) ) printf(&quot; - error!\n&quot;); else printf(&quot;\n&quot;);
+
+  printf(&quot;  Unlocking 1 byte from 1073741824&quot;);
+  fl.l_start  = 1073741824;
+  fl.l_len    = 1;
+  fl.l_type   = F_UNLCK;
+  if (0 != fcntl(fd, F_SETLK, &amp;fl) ) printf(&quot; - error!\n&quot;); else printf(&quot;\n&quot;);
+
+  printf(&quot;  Write-locking 1 byte from 1073741824&quot;);
+  fl.l_start  = 1073741824;
+  fl.l_len    = 1;
+  fl.l_type   = F_WRLCK;
+  if (0 != fcntl(fd, F_SETLK, &amp;fl) ) printf(&quot; - error!\n&quot;); else printf(&quot;\n&quot;);
+
+  printf(&quot;  Write-locking 510 byte from 1073741826&quot;);
+  fl.l_start  = 1073741826;
+  fl.l_len    = 510;
+  if (0 != fcntl(fd, F_SETLK, &amp;fl) ) printf(&quot; - error!\n&quot;); else printf(&quot;\n&quot;);
+
+  printf(&quot;  Unlocking 2 byte from 1073741824&quot;);
+  fl.l_start  = 1073741824;
+  fl.l_len    = 2;
+  fl.l_type   = F_UNLCK;
+  if (0 != fcntl(fd, F_SETLK, &amp;fl) ) printf(&quot; - error!\n&quot;); else printf(&quot;\n&quot;);
+
+  close(fd);
+  return 0;
+}
+
+/*
+ * Test if permissions of freshly created directories allow entries
+ * below them.  This was a problem with OpenOffice.org and gcompris.
+ * Mounting with option &#39;sync&#39; seem to solve this problem while
+ * slowing down file operations.
+ */
+int test_subdirectory_creation(void) {
+#define LEVELS 5
+  char *path = strdup(&quot;test&quot;);
+  char *dirs[LEVELS];
+  int level;
+  printf(&quot;info: testing subdirectory creation\n&quot;);
+  for (level = 0; level &lt; LEVELS; level++) {
+    char *newpath = NULL;
+    if (-1 == mkdir(path, 0777)) {
+      printf(&quot;  error: Unable to create directory &#39;%s&#39;: %s\n&quot;,
+            path, strerror(errno));
+      break;
+    }
+    asprintf(&amp;newpath, &quot;%s/%s&quot;, path, &quot;test&quot;);
+    free(path);
+    path = newpath;
+  }
+  return 0;
+}
+
+/*
+ * Test if symlinks can be created.  This was a problem detected with
+ * KDE.
+ */
+int test_symlinks(void) {
+  printf(&quot;info: testing symlink creation\n&quot;);
+  unlink(&quot;symlink&quot;);
+  if (-1 == symlink(&quot;file&quot;, &quot;symlink&quot;))
+    printf(&quot;  error: Unable to create symlink\n&quot;);
+  return 0;
+}
+
+int main(int argc, char **argv) {
+  printf(&quot;Testing POSIX/Unix sematics on file system\n&quot;);
+  test_symlinks();
+  test_subdirectory_creation();
+#ifdef TEST_SQLITE
+  test_sqlite_open();
+#endif /* TEST_SQLITE */
+  test_gcompris_locking();
+  return 0;
+}
+&lt;/pre&gt;
+
+&lt;p&gt;When everything is working, it should print something like
+this:&lt;/p&gt;
+
+&lt;pre&gt;
+Testing POSIX/Unix sematics on file system
+info: testing symlink creation
+info: testing subdirectory creation
+info: sqlite worked
+info: testing fcntl locking
+  Read-locking 1 byte from 1073741824
+  Read-locking 510 byte from 1073741826
+  Unlocking 1 byte from 1073741824
+  Write-locking 1 byte from 1073741824
+  Write-locking 510 byte from 1073741826
+  Unlocking 2 byte from 1073741824
+&lt;/pre&gt;
+
+&lt;p&gt;I do not remember the exact details of the problems we saw, but one
+of them was with locking, where if I remember correctly, POSIX allow a
+read-only lock to be upgraded to a read-write lock without unlocking
+the read-only lock (while Windows do not).  Another was a bug in the
+CIFS/SMB client implementation in the Linux kernel where directory
+meta information would be wrong for a fraction of a second, making
+OpenOffice.org fail to create its deep directory tree because it was
+not allowed to create files in its freshly created directory.&lt;/p&gt;
+
+&lt;p&gt;Anyway, here is a nice tool for your tool box, might you never need
+it. :)&lt;/p&gt;
+</description>
+       </item>
+       
        <item>
                <title>Autodetecting Client setup for roaming workstations in Debian Edu</title>
                <link>http://people.skolelinux.org/pere/blog/Autodetecting_Client_setup_for_roaming_workstations_in_Debian_Edu.html</link>
@@ -769,88 +997,5 @@ please contact us on debian-edu@lists.debian.org.&lt;/p&gt;
 </description>
        </item>
        
-       <item>
-               <title>Idea for storing LTSP configuration in LDAP</title>
-               <link>http://people.skolelinux.org/pere/blog/Idea_for_storing_LTSP_configuration_in_LDAP.html</link>
-               <guid isPermaLink="true">http://people.skolelinux.org/pere/blog/Idea_for_storing_LTSP_configuration_in_LDAP.html</guid>
-                <pubDate>Sun, 11 Jul 2010 22:00:00 +0200</pubDate>
-               <description>
-&lt;p&gt;Vagrant mentioned on IRC today that ltsp_config now support
-sourcing files from /usr/share/ltsp/ltsp_config.d/ on the thin
-clients, and that this can be used to fetch configuration from LDAP if
-Debian Edu choose to store configuration there.&lt;/p&gt;
-
-&lt;p&gt;Armed with this information, I got inspired and wrote a test module
-to get configuration from LDAP.  The idea is to look up the MAC
-address of the client in LDAP, and look for attributes on the form
-ltspconfigsetting=value, and use this to export SETTING=value to the
-LTSP clients.&lt;/p&gt;
-
-&lt;p&gt;The goal is to be able to store the LTSP configuration attributes
-in a &quot;computer&quot; LDAP object used by both DNS and DHCP, and thus
-allowing us to store all information about a computer in one place.&lt;/p&gt;
-
-&lt;p&gt;This is a untested draft implementation, and I welcome feedback on
-this approach.  A real LDAP schema for the ltspClientAux objectclass
-need to be written.  Comments, suggestions, etc?&lt;/p&gt;
-
-&lt;blockquote&gt;&lt;pre&gt;
-# Store in /opt/ltsp/$arch/usr/share/ltsp/ltsp_config.d/ldap-config
-#
-# Fetch LTSP client settings from LDAP based on MAC address
-#
-# Uses ethernet address as stored in the dhcpHost objectclass using
-# the dhcpHWAddress attribute or ethernet address stored in the
-# ieee802Device objectclass with the macAddress attribute.
-#
-# This module is written to be schema agnostic, and only depend on the
-# existence of attribute names.
-#
-# The LTSP configuration variables are saved directly using a
-# ltspConfig prefix and uppercasing the rest of the attribute name.
-# To set the SERVER variable, set the ltspConfigServer attribute.
-#
-# Some LDAP schema should be created with all the relevant
-# configuration settings.  Something like this should work:
-# 
-# objectclass ( 1.1.2.2 NAME &#39;ltspClientAux&#39;
-#     SUP top
-#     AUXILIARY
-#     MAY ( ltspConfigServer $ ltsConfigSound $ ... )
-
-LDAPSERVER=$(debian-edu-ldapserver)
-if [ &quot;$LDAPSERVER&quot; ] ; then
-    LDAPBASE=$(debian-edu-ldapserver -b)
-    for MAC in $(LANG=C ifconfig |grep -i hwaddr| awk &#39;{print $5}&#39;|sort -u) ; do
-       filter=&quot;(|(dhcpHWAddress=ethernet $MAC)(macAddress=$MAC))&quot;
-       ldapsearch -h &quot;$LDAPSERVER&quot; -b &quot;$LDAPBASE&quot; -v -x &quot;$filter&quot; | \
-           grep &#39;^ltspConfig&#39; | while read attr value ; do
-           # Remove prefix and convert to upper case
-           attr=$(echo $attr | sed &#39;s/^ltspConfig//i&#39; | tr a-z A-Z)
-           # bass value on to clients
-           eval &quot;$attr=$value; export $attr&quot;
-       done
-    done
-fi
-&lt;/pre&gt;&lt;/blockquote&gt;
-
-&lt;p&gt;I&#39;m not sure this shell construction will work, because I suspect
-the while block might end up in a subshell causing the variables set
-there to not show up in ltsp-config, but if that is the case I am sure
-the code can be restructured to make sure the variables are passed on.
-I expect that can be solved with some testing. :)&lt;/p&gt;
-
-&lt;p&gt;If you want to help out with implementing this for Debian Edu,
-please contact us on debian-edu@lists.debian.org.&lt;/p&gt;
-
-&lt;p&gt;Update 2010-07-17: I am aware of another effort to store LTSP
-configuration in LDAP that was created around year 2000 by
-&lt;a href=&quot;http://www.pcxperience.com/thinclient/documentation/ldap.html&quot;&gt;PC
-Xperience, Inc., 2000&lt;/a&gt;.  I found its
-&lt;a href=&quot;http://people.redhat.com/alikins/ltsp/ldap/&quot;&gt;files&lt;/a&gt; on a
-personal home page over at redhat.com.&lt;/p&gt;
-</description>
-       </item>
-       
         </channel>
 </rss>