-<p>Jeg møter alle slags interessante mennesker på min vei, og et møte
-jeg lærte mye av var å treffe på en svært kompetent IT-fyr som
-benektet ting jeg anser som åpenbart og selvfølgelig når det gjelder
-standarder. Det var interessant, da det fikk meg til å tenke litt
-nøyere på hvilke mekanismer som ligger til grunn for at noe oppfattes
-som en standard. Det hele startet med arbeid rundt integrering av NSS
-LDAP mot Active Directory, og problemer som oppstår pga. at Active
-Directory ikke følger LDAP-spesifikasjonen som dokumentert i RFCer fra
-IETF (konkret, AD returnerer kun et subset av attributter hvis det er
-mer enn 1500 atributter av en gitt type i et LDAP-objekt, og en må be
-om resten i bolker av 1500). Jeg hevdet måten dette ble gjort på brøt
-med LDAP-spesifikasjonen, og henviste til hvor i LDAP-spesifikasjonen
-fra IETF det sto at oppførselen til AD ikke fulgte
-LDAP-spesifikasjonen. AD-spesialisten overrasket meg da ved å
-fortelle at IETF var ikke de som definerte LDAP-spesifikasjonen, og at
-Active Directory ikke brøt den virkelige LDAP-spesifikasjonen som han
-mente lå til grunn. Jeg ble spesielt overrasket over denne
-tilnærmingen til problemstillingen, da til og med Microsoft så vidt
-jeg kan se anerkjenner IETF som organisasjonen som definerer
-LDAP-spesifikasjonen. Jeg fikk aldri spurt hvem han mente sto bak den
-egentlige LDAP-spesifikasjonen, da det var irrelevant for problemet vi
-måtte løse (få Linux og AD til å fungere sammen). Dette møtet
-fortalte meg uansett at det ikke er gitt at alle aktører er enige om
-hva en standard er, og hva som er kilden til en gitt standard. Det er
-vanskelig å enes om felles standarder før en først enes om hvem som
-bestemmer hva en gitt standard innebærer.</p>
-
-<p>Hva er så en standard? I sin abstrakte form er det noe å samles
-om. På engelsk er en av betydningene fane brukt i krig, du vet, den
-type fane en samlet seg rundt på kamplassen i riddertiden. En
-standard definerer altså et felleskap, noen som har noe felles. Det
-er naturligvis mange måter å utgjøre et felleskap på. En kan
-f.eks. enes om å gjøre alt slik som Ole gjør det, og dermed si at Oles
-oppførsel er standard. Hver gang Ole endrer oppførsel endrer også
-standarden seg uten noe mer organisering og prosedyre. En variant av
-dette er å gjøre slik som Ole har gjort det i stedet for slik Ole til
-enhver til gjør noe. Dette er ofte litt enklere å forholde seg til,
-da en slipper å sjekke med Ole hver gang for å vite hvordan ting skal
-gjøres nå, men hvis det Ole gjorde noe dumt den gang en bestemte seg
-for å følge Ole, så er det vanskeligere å få endret oppførsel for å
-unngå dette dumme.</p>
-
-<p>En kan også ta det et skritt videre, og istedet for å basere seg på
-enkeltpersoners oppførsel sette seg ned og bli enige om hvordan en
-skal gjøre ting, dvs. lage et felleskap basert på konsensus. Dette
-tar naturligvis litt mer tid (en må diskutere ting i forkant før en
-kan sette igang), men det kan bidra til at den oppførselen en
-planlegger å benytte seg av er mer gjennomtenkt. Det ender også
-typisk opp med en beskrivelse av ønsket oppførsel som flere kan forstå
-- da flere har vært involvert i å utarbeide beskrivelsen.</p>
-
-<p>Dette er dessverre ikke alt som trengs for å forstå hva en åpen
-standard er for noe. Der alle kan se på hvordan folk oppfører seg, og
-dermed har valget om de vil oppføre seg likt eller ikke, så er det
-endel juridiske faktorer som gjør det hele mer komplisert -
-opphavsretten og patentlovgivningen for å være helt konkret. For å gi
-et eksempel. Hvis noen blir enige om å alltid plystre en bestemt
-melodi når de møtes, for å identifisere hverandre, så kan
-opphavsretten brukes til å styre hvem som får lov til å gjøre dette.
-De har standardisert hvordan de kjenner igjen alle som følger denne
-standarden, men ikke alle har nødvendigvis lov til å følge den.
-Musikk er opphavsrettsbeskyttet, og fremføring av musikk i
-offentligheten er opphavsmannens enerett (dvs. et monopol). Det vil i
-sin ytterste konsekvens si at alle som skal plystre en
-opphavsrettsbeskyttet melodi i det offentlige rom må ha godkjenning
-fra opphavsmannen. Har en ikke dette, så bryter en loven og kan
-straffes. Det er dermed mulig for opphavsmannen å kontrollere hvem
-som får lov til å benytte seg av denne standarden. En annen variant
-er hvis en standard er dokumentert, så er dokumentet som definerer
-standarden (spesifikasjonen) beskyttet av opphavsretten, og det er
-dermed mulig for rettighetsinnehaver å begrense tilgang til
-spesifikasjonen, og slik styre hvem som kan ta i bruk standarden på
-den måten.</p>
-
-<p>Der opphavsretten innvilger et monopol på kunstneriske uttrykk med
-verkshøyde, innvilger patentlovgivningen monopol på ideer. Hvis en
-slik patentert idé (fortrinnsvis uttrykt i en teknisk innretning, men
-det er kompliserende faktorer som gjør at det ikke er et krav) trengs
-for å ta i bruk en standard, så vil den som innehar patent kunne styre
-hvem som får ta i bruk standarden. Det er dermed ikke gitt at alle
-kan delta i et standard-felleskap, og hvis de kan delta, så er det
-ikke sikkert at det er på like vilkår. F.eks. kan rettighetsinnehaver
-sette vilkår som gjør at noen faller utenfor, det være seg av
-finansielle, avtalemessige eller prinsipielle årsaker. Vanlige slike
-vilkår er "må betale litt for hver kunde/bruker" som utelukker de som
-gir bort en løsning gratis og "må gi fra seg retten til å håndheve
-sine egne patentrettigheter ovenfor rettighetshaver" som utelukker
-alle som ønsker å beholde den muligheten.</p>
-
-<p>En åpen standard innebærer for meg at alle kan få innsikt i en
-komplett beskrivelse av oppførsel som standarden skal dekke, og at
-ingen kan nektes å benytte seg av standarden. Noen mener at det
-holder at alle med tilstrekkelig finansiering kan få tilgang til
-spesifikasjonen og at en kun har finansielle krav til bruk.
-Pga. denne konflikten har et nytt begrep spredt seg de siste årene,
-nemlig fri og åpen standard, der en har gjort det klart at alle må ha
-komplett og lik tilgang til spesifikasjoner og retten til å gjøre bruk
-av en standard for at en standard skal kunne kalles fri og åpen.</p>
+<p>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.</p>
+
+<p>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.</p>
+
+<p>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:</p>
+
+<pre>
+/*
+ * 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 <errno.h>
+#include <fcntl.h>
+#include <stdio.h>
+#include <string.h>
+#include <stdlib.h>
+#include <sys/file.h>
+#include <sys/stat.h>
+#include <sys/types.h>
+#include <unistd.h>
+
+#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 <URL: http://www.sqlite.org./faq.html#q5 >.
+ */
+#include <sqlite3.h>
+#define CREATE_TABLE_USERS \
+ "CREATE TABLE users (user_id INT UNIQUE, login TEXT, lastname TEXT, firstname TEXT, birthdate TEXT, class_id INT ); "
+int test_sqlite_open(void) {
+ char *zErrMsg;
+ char *name = "testsqlite.db";
+ sqlite3 *db=NULL;
+ unlink(name);
+ int rc = sqlite3_open(name, &db);
+ if( rc ){
+ printf("error: sqlite open of %s failed: %s\n", name, sqlite3_errmsg(db));
+ sqlite3_close(db);
+ return -1;
+ }
+
+ /* create tables */
+ rc = sqlite3_exec(db,CREATE_TABLE_USERS, NULL, 0, &zErrMsg);
+ if( rc != SQLITE_OK ){
+ printf("error: sqlite table create failed: %s\n", zErrMsg);
+ sqlite3_close(db);
+ return -1;
+ }
+ printf("info: sqlite worked\n");
+ 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
+ * <URL:http://www.cygwin.com/ml/cygwin/2001-08/msg00854.html> and the
+ * POSIX specification
+ * <URL:http://www.opengroup.org/onlinepubs/009695399/functions/fcntl.html>.
+ */
+int test_gcompris_locking(void) {
+ struct flock fl;
+ char *name = "testsqlite.db";
+ unlink(name);
+ int fd = open(name, O_RDWR|O_CREAT|O_LARGEFILE, 0644);
+ printf("info: testing fcntl locking\n");
+
+ fl.l_whence = SEEK_SET;
+ fl.l_pid = getpid();
+ printf(" Read-locking 1 byte from 1073741824");
+ fl.l_start = 1073741824;
+ fl.l_len = 1;
+ fl.l_type = F_RDLCK;
+ if (0 != fcntl(fd, F_SETLK, &fl) ) printf(" - error!\n"); else printf("\n");
+
+ printf(" Read-locking 510 byte from 1073741826");
+ fl.l_start = 1073741826;
+ fl.l_len = 510;
+ fl.l_type = F_RDLCK;
+ if (0 != fcntl(fd, F_SETLK, &fl) ) printf(" - error!\n"); else printf("\n");
+
+ printf(" Unlocking 1 byte from 1073741824");
+ fl.l_start = 1073741824;
+ fl.l_len = 1;
+ fl.l_type = F_UNLCK;
+ if (0 != fcntl(fd, F_SETLK, &fl) ) printf(" - error!\n"); else printf("\n");
+
+ printf(" Write-locking 1 byte from 1073741824");
+ fl.l_start = 1073741824;
+ fl.l_len = 1;
+ fl.l_type = F_WRLCK;
+ if (0 != fcntl(fd, F_SETLK, &fl) ) printf(" - error!\n"); else printf("\n");
+
+ printf(" Write-locking 510 byte from 1073741826");
+ fl.l_start = 1073741826;
+ fl.l_len = 510;
+ if (0 != fcntl(fd, F_SETLK, &fl) ) printf(" - error!\n"); else printf("\n");
+
+ printf(" Unlocking 2 byte from 1073741824");
+ fl.l_start = 1073741824;
+ fl.l_len = 2;
+ fl.l_type = F_UNLCK;
+ if (0 != fcntl(fd, F_SETLK, &fl) ) printf(" - error!\n"); else printf("\n");
+
+ 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 'sync' seem to solve this problem while
+ * slowing down file operations.
+ */
+int test_subdirectory_creation(void) {
+#define LEVELS 5
+ char *path = strdup("test");
+ char *dirs[LEVELS];
+ int level;
+ printf("info: testing subdirectory creation\n");
+ for (level = 0; level < LEVELS; level++) {
+ char *newpath = NULL;
+ if (-1 == mkdir(path, 0777)) {
+ printf(" error: Unable to create directory '%s': %s\n",
+ path, strerror(errno));
+ break;
+ }
+ asprintf(&newpath, "%s/%s", path, "test");
+ free(path);
+ path = newpath;
+ }
+ return 0;
+}
+
+/*
+ * Test if symlinks can be created. This was a problem detected with
+ * KDE.
+ */
+int test_symlinks(void) {
+ printf("info: testing symlink creation\n");
+ unlink("symlink");
+ if (-1 == symlink("file", "symlink"))
+ printf(" error: Unable to create symlink\n");
+ return 0;
+}
+
+int main(int argc, char **argv) {
+ printf("Testing POSIX/Unix sematics on file system\n");
+ test_symlinks();
+ test_subdirectory_creation();
+#ifdef TEST_SQLITE
+ test_sqlite_open();
+#endif /* TEST_SQLITE */
+ test_gcompris_locking();
+ return 0;
+}
+</pre>
+
+<p>When everything is working, it should print something like
+this:</p>
+
+<pre>
+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
+</pre>
+
+<p>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.</p>
+
+<p>Anyway, here is a nice tool for your tool box, might you never need
+it. :)</p>