Toon posts:

Samba en file locking onder linux

Pagina: 1
Acties:

Verwijderd

Topicstarter
Ik heb een probleem

In heb een directory waar .prn in worden gezet dmv print to file (via printer)
in deze directory zet windows het bestand neer.

Onder linux wordt elke minuut (cron) gekeken of er een nieuw bestand is en converteerd deze naar PDF.

Het probleem is nu als windows nog aan het schrijven is.

dat het script het bestand al oppakt.

Via windows kan je niet echt een locking neer zetten.
Samba doet aan file locking oplocks etc maar daar gaat hij gewoon doorheen.

Kan samba een file locken (DENY_ALL) en dat onder linux het bestand niet geopend, gemoved en/of gekopieerd kan worden.

Ik heb al vele combinaties gemaakt maar kan dit uberhuapt wel ?

Iemand ervaringen ideen oplossingen welkom.

[ Voor 1% gewijzigd door Verwijderd op 14-05-2003 14:12 . Reden: typo ]


  • Leon
  • Registratie: Maart 2000
  • Laatst online: 10-04 09:12

Leon

Rise Of The Robots

Is het niet handiger als je in cups of zo een PDF printer maakt die pdf'jes maakt en in een directory zet :?

(ok, niet echt een oplossing voor je probleem, maar wel wat eleganter)

Eeuwige n00b


  • it0
  • Registratie: April 2000
  • Laatst online: 27-12-2025

it0

Mijn mening is een feit.

Als je alleen printopdrachten wilt omzetten in pdf dan kan je hiervoor ook een printerdriver voor instaleren.

Verwijderd

Topicstarter
Is opzich wel een idee om het zo te doen dan kan het script hem automatisch verplaatsen
Leon schreef op 14 May 2003 @ 14:41:
Is het niet handiger als je in cups of zo een PDF printer maakt die pdf'jes maakt en in een directory zet :?

(ok, niet echt een oplossing voor je probleem, maar wel wat eleganter)
Een printdriver is geen optie omdat de cpu van de werkstations niet belast mag worden.


Maar dan nog ben ik benieuwd hoe ik een LOCK kan zetten met samba

  • Wilke
  • Registratie: December 2000
  • Nu online
Begrijpelijke vraag, en ik ben heel benieuwd of dit kan.

Samba lockt het alleen 'naar clients toe', dus houd denk ik zelf intern bij welke files er locked zijn, en laat andere clients behalve de ene die de lock heeft er dan niet in schrijven (Samba experts, correct me if I'm wrong :) ). Hopelijk werkt dit via POSIX locking, dan kun je ook andere processen hier gebruik van laten maken.


Als Samba inderdaad het POSIX locking-mechanisme gebruikt (fcntl), zou je zelf een klein programmaatje kunnen schrijven dat checkt of de file gelockt is via POSIX-locking, en zo ja, wacht totdat dit lock wordt vrijgegeven.

Er zijn ook wel mandatory locks in Linux, maar het gebruik daarvan wordt afgeraden (want: non-portable); aangezien Samba nogal cross-platform is, kan ik me ook haast niet voorstellen dat die gebruikt worden.

Als je dit een beetje bagger vind: dat is het ook. Hoog tijd dat er een "echt" filelocking mechanisme komt op OS-level. Bij mijn weten is dat er nu niet (iig niet portable tussen unices). Maar alweer: ik zit niet diep in deze materie, dus ik kan het maar zo bij het verkeerde eind hebben.

Samba Project Documentation: Locking

Nou, als je die documentatie leest zul je het al wel zien: brakheid alom in die Linux-implementatie :( :( - maar voor files onder de 2 GB *schijnt* het locken dus gewoon via fcntl() te gaan, en in dat geval kun je ook in andere programma's achterhalen of de file gelockt is (degene die het achterlijk vind dat je vrijwillig kunt checken of een file gelockt is, maar ook gewoon kunt besluiten je daar geen ruk van aan te trekken: je bent niet de eerste of de enige die dat vind!)

N.B. Let even GOED op in die documentatie, welke settings je in smb.conf dan aan of uit zou moeten zetten!

[ Voor 26% gewijzigd door Wilke op 14-05-2003 15:27 ]


Verwijderd

Topicstarter
:/ wow :/

heftig verhaal
Nu nog uitzoeken hoe ik dat ga uit vinden.

Ik was al trots op dit scriptje
/code
#!/usr/bin/perl
$dir = "/data/fileserver/pdfconversie";
opendir(DIR, "$dir");
my @files = readdir(DIR);
for $i (@files)
{
if ($i =~ /.*\.prn$/)
{
$i =~ s/\ /\\\ /g;
$j = $i;
$j =~ s/\.prn$/\.ps/i;
unless (-e $j)
{
`cp -af $i $j`;
$k = $i;
$k =~ s/\.prn$/\.pdf/i;
$l = $i;
$l =~ s/\.prn$/\.txt/i;
$m = $i;
$m =~ s/\.prn$/\.ready/i;
`ps2pdf12 $j $k >$l`;
`unix2dos $l`;
`chmod 666 $l`;
`touch $m`;
`rm -rf $i`;
`rm -rf $j`;
}
}
}
/code
hmmmm wordt weer spitten

  • Wilke
  • Registratie: December 2000
  • Nu online
OMG...echte perl-code...nog geen 30 regels en toch al tamelijk onleesbaar :X

Nou, daar ga ik overheen met een stukkie C-code dat je zou kunnen gebruiken om die lock te krijgen. Het zal mij benieuwen of het werkt. Het *compileert*, maar of het doet wat het moet doen, dat is jouw probleem.

Anyway, op basis van het boek "Linux Application Development", wat ik nog heb uit de tijd van Linux 2.2/2.0 (dus ik hoop heel hard voor je dat het nog ongeveer hetzelfde werkt), kan ik je deze C-code wel geven:

C:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
#include <errno.h>
#include <fcntl.h>
#include <stdio.h>
#include <unistd.h>

/* fd = File Descriptor, type = lock type (F_RDLCK, F_WRLCK, F_UNLCK) */
void getlock(int fd, int type)
{
  struct flock lockinfo;
  /* Probeer de hele file te locken */
  lockinfo.l_whence = SEEK_SET;
  lockinfo.l_start = 0;
  lockinfo.l_len = 0;
  lockinfo.l_type = type;

  while (fcntl(fd, F_SETLK, &lockinfo)) /* Probeer tot het lukt*/
    usleep(1000); /* netter zou zijn om te wachten op het andere proces, maar dat
                     is veel lastiger te implementeren */
}

int main(int argc, char* argv[])
{
  int dummy_status; /* Nodig voor wait, boeit verder niet */

  /* Open bestaande file, die je maar beter als argument van dit prog kunt opgeven :) */
  int fd = open(argv[1], O_RDONLY);
  if (fd < 0) { fprintf(stderr, "Kan file niet openen\n"); return 1; }

  printf("Read lock te pakken krijgen....\n");
  getlock(fd, F_RDLCK);
  printf("Whee! Ik heb het lock te pakken\n");
  if (fork())
  {
    char conversieprog[] = "/usr/bin/pdf-conversie-prog";
    char* argumenten[] = { "-evt optie voor het programma", argv[1], NULL };

    execvp(conversieprog, argumenten);
  }
  else
    wait(&dummy_status);


  close(fd); /* Geeft ook vanzelf de lock weer vrij. Deze aanroep kun je evt. weglaten,
   want bij het sluiten van het proces gebeurt dit toch al vanzelf. */

  return 0;
}


Downloadbaar: lock.c.

Enige toelichting:

Als je dit compileert (met 'gcc -o lock lock.c') en het runt met:
./lock /ergens/mogelijk-gelockte-file

Dan zou hij moeten wachten tot 'ie de lock krijgt, en dan het programma runnen zoals in de code staat (ik neem aan dat je kennis van C ver genoeg reikt om dit zelf verder te kunnen verbouwen totdat het werkt. Bv. checken of er wel een filename is opgegeven zou geen kwaad kunnen (checken op argc > 1 :P )).

Dit alles werkt alleen als samba ook daadwerkelijk die locks zet via fcntl, en daar kun je dus invloed op hebben met die config-parameters zoals in de documentatie staat. Het zou wel eens een redelijk vervelende performance hit kunnen geven als je dit niet 'selectief' kunt doen trouwens!

Anyway, succes met prutsen, en laat weten of het werkt :P

[ Voor 19% gewijzigd door Wilke op 14-05-2003 16:29 ]


  • Wilke
  • Registratie: December 2000
  • Nu online
Goed, alternatief voor al dit gezeik: pruts eens wat met 'smbstatus -L' (zie ook man smbstatus) ?
Pagina: 1