Check alle échte Black Friday-deals Ook zo moe van nepaanbiedingen? Wij laten alleen échte deals zien
Toon posts:

[RH7.2]Netwerk probleem rc.local

Pagina: 1
Acties:

Verwijderd

Topicstarter
Ik heb een (zelf-geschreven) programma dat moet starten als de PC gestart wordt.
Dit programma is een client en verbindt met een (externe) server over een TCP/IP verbinding. Het programma doet drie pogingen met een interval van 1 seconde.
Als ik dit programma handmatig start, gaat dit 100% van de keren goed en de verbinding wordt direct gemaakt (1ste poging). Het maakt niet uit of het programma via een script gestart wordt of van de commandline. Het maakt ook niet uit of ik het draai als root of als een gebruiker.

Als ik dit programma vanuit rc.local start krijg ik in ongeveer 20% van de gevallen een foutmelding dat de verbinding niet gemaakt kan worden, ook niet na 3 pogingen.
Een ping (met raw sockets) naar het betreffende adres (vanuit het programma) gaat wel goed hetgeen aangeeft dat de externe server wel aan staat.

De externe server is een stuk hardware waar verder winig invloed op kan worden uitgeoefend en die niet uitgeschakeld is tijdens de diverse reboots van de PC waar het programma op draait.

Oh ja, het programma wordt altijd gestart als een achtergrond process en wordt gestopt via kill. Er is een signal-handler die alle sockets sluit voordat het programma stopt.

Iemand enig idee waarom het niet betrouwbaar werkt via rc.local?


edit:

een foutje gevonden; zou geen invloed moeten hebben aangezien ik (als het fout gaat) nooit een melding krijg dat het eerst succesvol was (connected (1))
zie bugfix


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
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
static int device_connect(sCONN *pConn, int socktype, sCFG *pCfg)
{
int rc;

  // create socket if current socket invalid (-1)
  if(pConn->connfd<0)
  {
    logit(LOG2SCRN|LOG2FILE,pCfg->eflags,pCfg->logfile,0,
          "device_connect",NULL,0,
          "creating socket; initial value ='%d'",pConn->connfd);
    // create socket
    pConn->connfd=socket(PF_INET,socktype,0);
    if(pConn->connfd<0)
    {
      // error
      logit(LOG2SCRN|LOG2FILE,pCfg->eflags,pCfg->logfile,errno,
            "device_connect",NULL,0,
            "Socket error");
// TO DO: inform IOCM here
      return 0;
    } // end_of_if(pConn->connfd<0)

    // make socket non-blocking
    rc=fcntl(pConn->connfd,F_SETFL,
          fcntl(pConn->connfd,F_GETFL)|O_NONBLOCK);
    if(rc<0)
    {
      logit(LOG2SCRN|LOG2FILE,pCfg->eflags,pCfg->logfile,errno,
          "device_connect",NULL,0,
          "fcntl failed");
    }
    pConn->inuse=0;

    // initialize counter
    pConn->attempts=MAXCONNATTEMPTS;
    pConn->endtime=time(NULL)+CONNECTIONTO;
  } // end_of_if(pConn->connfd<0)

  // try to connect when we have a valid socket
  if(pConn->connfd>=0)          // socket created
  {
    if(pConn->inuse==0)
    {
      logit(LOG2SCRN|LOG2FILE,pCfg->eflags,pCfg->logfile,0,
            "device_connect",NULL,0,
            "trying to connect socket '%d'",pConn->connfd);
      // not in use, attempt to connect
      if(connect(pConn->connfd,(struct sockaddr*)&pConn->addr,
                 sizeof(pConn->addr))!=0)
      {
        // connection 'error'
        if(errno==EISCONN)          // EISCONN equals errno 106
        {
          // if already connected, we're connected

          logit(LOG2SCRN|LOG2FILE,pCfg->eflags,pCfg->logfile,0,
                "device_connect",NULL,0,
                "Device '%s' ('%s:%d') connected (1)",
                pConn->device,
                inet_ntoa(pConn->addr.sin_addr),
                ntohs(pConn->addr.sin_port));
          proc_iolan(pCfg,pConn->addr,1);
          pConn->inuse=1;
// bugfix
          return 0;

        }
        if(time(NULL)-pConn->endtime>0)
        {
          pConn->endtime=time(NULL)+CONNECTIONTO;
          pConn->attempts--;
          if(pConn->attempts==0)
          {
            // MAXCONNATTEMPTS reached, inform IOCM
            logit(LOG2SCRN|LOG2FILE,pCfg->eflags,pCfg->logfile,0,
                  "device_connect",NULL,0,
                  "Device '%s' ('%s:%d') disconnected (3)",
                  pConn->device,
                  inet_ntoa(pConn->addr.sin_addr),
                  ntohs(pConn->addr.sin_port));
            proc_iolan(pCfg,pConn->addr,0);

            close(pConn->connfd);
            pConn->connfd=-1;
            pConn->inuse=0;

            pConn->attempts=MAXCONNATTEMPTS;
          }
        }
      } // end_of_if(connect(....)!=0)
      else
      {
        logit(LOG2SCRN|LOG2FILE,pCfg->eflags,pCfg->logfile,0,
              "device_connect",NULL,0,
              "Device '%s' ('%s:%d') connected (2)",
              pConn->device,
              inet_ntoa(pConn->addr.sin_addr),
              ntohs(pConn->addr.sin_port));
        proc_iolan(pCfg,pConn->addr,1);
        pConn->inuse=1;
      } // end_of_else(connect(....)!=0)
    }
  } // end_of_if(pConn->fd>=0)

  return 0;
}


Deze code wordt aangeroepen totdat pConn->inuse gezet is. CONNECTIONTO is 1 en MAXCONNATTEMPTS is 3.

[ Voor 16% gewijzigd door Verwijderd op 24-07-2003 09:31 ]


  • ACM
  • Registratie: Januari 2000
  • Niet online

ACM

Software Architect

Werkt hier

Hoe krijgt die pc zijn ipadres? Via dhcp? Dan is het mogelijk dat op het moment dat de rc.local uitgevoerd wordt de pc nog geen ipadres heeft gekregen...

Verwijderd

Topicstarter
Goede suggestie; helaas is adres fixed.

  • djluc
  • Registratie: Oktober 2002
  • Laatst online: 26-11 19:23
Kun je het programma eens testen maar dan met een wachttijd van bijvoorbeeld 10 seconden en dan eens kijken of het werkt? Anders kun je per handeling het tijdstip bijhouden zodat je kunt zien wat het verschil is met een niet domein uitvoer. Ook zie je dan meteen bij welke acties dit verschil zit.

Verwijderd

Topicstarter
Ik snap je 'domein' niet helemaal. Dit is in beide gevallen toch hetzelfde (of zie ik dat verkeerd)?
Ben overigens wel een stap verder. Ik kan het nu simuleren zonder rc.local te gebruiken.
Dit gebeurt als de netwerk-verbinding verbroken is geweest (kabel eruit). Detectie hiervan gebeurt via een ping routine die dan alle sockets sluit en connfd op -1 zet. Nadat een ping weer succesvol is, wordt bovenstaande routine weer aangeroepen; het kan dan tot een minuut of zo duren voordat de verbinding weer terugkomt.

Aanvulling over de server waar ik mee verbindt: deze accepteert maar een (1) verbinding per poort/service. Kan het zijn dat die server nog niet in de gaten heeft dat de verbinding verbroken is geweest en daarom geen nieuwe verbindingen accepteert?

[ Voor 21% gewijzigd door Verwijderd op 27-07-2003 09:58 ]


  • deadinspace
  • Registratie: Juni 2001
  • Laatst online: 17:59

deadinspace

The what goes where now?

Een paar dingetjes :)
Verwijderd schreef op 24 July 2003 @ 09:20:
Het programma doet drie pogingen met een interval van 1 seconde.
Wat als een poging langer duurt dan één seconde, bijvoorbeeld omdat de machine waarnaar geconnect wordt onbereikbaar is?
Als ik dit programma vanuit rc.local start krijg ik in ongeveer 20% van de gevallen een foutmelding dat de verbinding niet gemaakt kan worden, ook niet na 3 pogingen.
Wanneer in het bootprocess wordt rc.local uitgevoerd? Zoals ACM al suggereert kan het zijn dat er op dat moment nog iets niet beschikbaar / geconfigureerd is.
Er is een signal-handler die alle sockets sluit voordat het programma stopt.
Leuk, maar niet echt nodig :)
De kernel sluit alle open filedescriptors (waaronder dus de sockets) van een process dat beeindigd wordt.
Iemand enig idee waarom het niet betrouwbaar werkt via rc.local?
Zet in rc.local eens "strace -f -o /tmp/strace.log " oid voor het programma, dat verschaft misschien duidelijkheid.

Verwijderd

Topicstarter
Het zijn/waren toch min-of-meer twee problemen.

1) reboot: vraag me niet hoe het kan, maar het lijkt dat tijdens een reboot de processen gewoon doorlopen. Op een andere server (via een andere software module) blijft de communicatie led knipperen gedurende een shutdown -g0 -y -r, zelfs als de computer waar deze software op draait bezig is met de POST :?
Als ik echter het process handmatig kill voordat ik reboot is er geen probleem (en de communicatie led dimt dan ook.
Ik vermoed dat voor de server waar bovenstaande code voor geschreven is, ook zoiets geldt. Aangezien de aangesloten servers slechts een (1) verbinding accepteren en deze niet zien dat de verbinding verbroken is en krijg ik mijn foutmeldingen.

2) communicatie probleem:
Probleem lijkt opgelost. Oorzaak lijkt het feit te zijn dat mijn software sockets sluit op het moment dat een ping naar de server fout gaat (bv netwerk kabel eruit). De aangesloten server ziet dit (uiteraard) niet. Aangezien die server slechts een (1)verbinding toestaat, gaat een reconnect fout (nadat de ping OK is) totdat de server heeft gedetecteerd dat de verbindig weg is. Helaas heb ik daar geen invloed op. Opgelost door socket pas te sluiten als als een ping weer OK is.
[...]

... omdat de machine waarnaar geconnect wordt onbereikbaar is?
Tja, dat is nu net wat deze software moet uitvinden (maar dat kon je niet weten) en dat ook nog eens binnen een zekere tijd. Niet kunnen verbinden of een verbinding die verbroken wordt is een ernstige fout.
[...]

Wanneer in het bootprocess wordt rc.local uitgevoerd? Zoals ACM al suggereert kan het zijn dat er op dat moment nog iets niet beschikbaar / geconfigureerd is.
rc.local is de laatste stap (net voordat de login prompt verschijnt om het maar zo te zeggen
[...]

Leuk, maar niet echt nodig :)
De kernel sluit alle open filedescriptors (waaronder dus de sockets) van een process dat beeindigd wordt.
Ik ben van mening dat het wel zo netjes is om het zelf te doen voor zover mogelijk. Die handler is bedoelt voor ctrl-c (in het geval het proces in de voorgrond draait voor debugging).
Helaas gaat er iets fout als er een SIGTERM wordt gestuurd. Ik kan die (uiteraard) niet afvangen en verder lijken de sockets niet gesloten te worden. Zie hierboven
[...]

Zet in rc.local eens "strace -f -o /tmp/strace.log " oid voor het programma, dat verschaft misschien duidelijkheid.
Bedankt voor die tip, het heeft uiteindelijk wel een gedeelte verklaard (namelijk dat connect een ECONNREFUSED teruggaf..


Iedereen bedankt voor het meedenken. Als iemand nog kan verklaren waarom mijn communicatie lijkt door te lopen tijdens een reboot, houd ik mij aanbevolen.

  • JeroenE
  • Registratie: Januari 2001
  • Niet online
Aangezien de aangesloten servers slechts een (1) verbinding accepteren en deze niet zien dat de verbinding verbroken is en krijg ik mijn foutmeldingen.
en
Iedereen bedankt voor het meedenken. Als iemand nog kan verklaren waarom mijn communicatie lijkt door te lopen tijdens een reboot, houd ik mij aanbevolen.
Weet je wel zeker dat het aan jouw kant ligt? Als ik bovenstaande lees dan begrijp ik het volgende: de server ziet dat er communicatie is en een ledje laat knipperen. Als je afsluit krijgt de server een melding en stopt hij met het knipperen. Klopt dat?

Maar als er iets mis gaat en hij krijgt geen melding dat de verbinding wordt verbroken lijkt het er dus op dat hij pas na een bepaalde time-out opgeeft en stopt met knipperen. In die tijd kan jij geen nieuwe verbinding maken, toch?

Wat gebeurt er als je fysiek de netwerkkabel uit jouw PC trekt? Blijft het ledje van de server dan ook nog steeds knipperen? Als datzo is dan weet je dat het probleem dus niet aan jou kant zit, maar aan de server die niet snel genoeg door heeft of de verbinding is verbroken of niet.

  • ACM
  • Registratie: Januari 2000
  • Niet online

ACM

Software Architect

Werkt hier

Verwijderd schreef op 29 juli 2003 @ 10:39:
1) reboot: vraag me niet hoe het kan, maar het lijkt dat tijdens een reboot de processen gewoon doorlopen. Op een andere server (via een andere software module) blijft de communicatie led knipperen gedurende een shutdown -g0 -y -r, zelfs als de computer waar deze software op draait bezig is met de POST :?
Mijn shutdown's kennen geen -g en -y parameters. Magoed, hij zal wel bezig zijn met een reboot, ondanks dat.

Enneuh, er is niet eens een kernel geladen bij POST, dus laat staan processen... Dus er _is_ geen communicatie vanuit die machine, misschien dat een andere doos wat opstuurt waardoor het netwerklampje gaat knipperen, maar er komt niks bij die doos vandaan.
Ik vermoed dat voor de server waar bovenstaande code voor geschreven is, ook zoiets geldt. Aangezien de aangesloten servers slechts een (1) verbinding accepteren en deze niet zien dat de verbinding verbroken is en krijg ik mijn foutmeldingen.
Blijkbaar werd dus de connectie niet als netjes afgesloten beschouwd en dus nog als open gezien.
2) communicatie probleem:
[..]Opgelost door socket pas te sluiten als als een ping weer OK is.
Mja, dat zal niet altijd mogelijk zijn he? :)
rc.local is de laatste stap (net voordat de login prompt verschijnt om het maar zo te zeggen
Dat weten ik en deadinspace wel hoor :) Maar dat zegt nog niet (zeker met dhcp) dat je nic dan al een ip heeft, meestal wel natuurlijk.
Helaas gaat er iets fout als er een SIGTERM wordt gestuurd. Ik kan die (uiteraard) niet afvangen en verder lijken de sockets niet gesloten te worden. Zie hierboven
SIGKILL kan je niet afvangen, SIGTERM wel :)
Iedereen bedankt voor het meedenken. Als iemand nog kan verklaren waarom mijn communicatie lijkt door te lopen tijdens een reboot, houd ik mij aanbevolen.
Wellicht dat je server _denkt_ dat het goed gaat, maar je client doet er echt niks mee hoor :)

Verwijderd

Topicstarter
jeroene schreef op 29 July 2003 @ 11:24:
[...]
en
[...]
Weet je wel zeker dat het aan jouw kant ligt? Als ik bovenstaande lees dan begrijp ik het volgende: de server ziet dat er communicatie is en een ledje laat knipperen. Als je afsluit krijgt de server een melding en stopt hij met het knipperen. Klopt dat?

Maar als er iets mis gaat en hij krijgt geen melding dat de verbinding wordt verbroken lijkt het er dus op dat hij pas na een bepaalde time-out opgeeft en stopt met knipperen. In die tijd kan jij geen nieuwe verbinding maken, toch?

Wat gebeurt er als je fysiek de netwerkkabel uit jouw PC trekt? Blijft het ledje van de server dan ook nog steeds knipperen? Als datzo is dan weet je dat het probleem dus niet aan jou kant zit, maar aan de server die niet snel genoeg door heeft of de verbinding is verbroken of niet.
Server is een andere server die via andere module aangestuurd wordt. De server waar het LEDJE opzit gaat knipperen op het moment dat ik er data naartoe stuur.
Als ik die module stop, gaat de het LEDJE ook uit. Als ik de kabel eruittrek blijft de LED knipperen, maar geeft die server via andere LEDs aan dat er een probleem is.

Het is overigens wel mijn probleem want ik moet binnen redelijke tijd (een paar seconden) weten of de verbinding gemaakt kan worden.
ACM schreef op 29 July 2003 @ 11:46:
[...]

Mijn shutdown's kennen geen -g en -y parameters. Magoed, hij zal wel bezig zijn met een reboot, ondanks dat.
Komen nog uit mijn SCO tijd.

Enneuh, er is niet eens een kernel geladen bij POST, dus laat staan processen... Dus er _is_ geen communicatie vanuit die machine, misschien dat een andere doos wat opstuurt waardoor het netwerklampje gaat knipperen, maar er komt niks bij die doos vandaan.[/quote]Ik weet het, daarom snap ik het ook niet :'(
[...]

Blijkbaar werd dus de connectie niet als netjes afgesloten beschouwd en dus nog als open gezien.
Ja. Ik heb ook al gezien dat er in de rc6.d eigenlijk nog iets kan/moet komen om de boel netjes af te sluiten. Ik ga daar nu mee klooien om te zien of ik het zo kan oplossen. Eventuele problemen daarmee zal ik wel posten in het OS-anders forum.
[...]

Dat weten ik en deadinspace wel hoor :) Maar dat zegt nog niet (zeker met dhcp) dat je nic dan al een ip heeft, meestal wel natuurlijk.
Waarom vraagt deadinspace het dan :? Ik had verder al aangegeven dat ik fixed IP-adressen gebruik ;)
[...]

SIGKILL kan je niet afvangen, SIGTERM wel :)
Foutje, bedankt

[ Voor 1% gewijzigd door Verwijderd op 29-07-2003 12:35 . Reden: typos ]


  • ACM
  • Registratie: Januari 2000
  • Niet online

ACM

Software Architect

Werkt hier

Verwijderd schreef op 29 juli 2003 @ 12:32:
Ja. Ik heb ook al gezien dat er in de init6.d eigenlijk nog iets kan/moet komen om de boel netjes af te sluiten. Ik ga daar nu mee klooien om te zien of ik het zo kan oplossen. Eventuele problemen daarmee zal ik wel posten in het Linux forum.
Als je gewoon de SIGTERM netjes afvangt en de boel afsluit, heb je heel dat geklooi in init6 niet nodig hoor :)
Opzich is het wel netter natuurlijk om in init6 een daemon netjes af te laten sluiten, maar het moet niet, zeker als je hem in init3/init5 laat starten (maar je start hem met de rc.local dus dan hoort het eigenlijk ook niet in init6) :P
Waarom vraagt deadinspace het dan :? Ik had verder al aangegeven dat ik fixed IP-adressen gebruik ;)
Ook met een fixed ip is het geloof ik niet gegarandeerd dat je daar al een ip hebt, maar dan is er wel wat meer aan de hand :o

Verwijderd

Topicstarter
Zal waarschijnlijk niet gaan werken aangezien interface eth0 al down is voordat het TERM signaal gestuurd wordt :'(

edit:
|:( Ik geloof dat ik iets niet goed gezien heb 8)7 Hierboven staat dus onzin |:( Sorry


Het is overigens geen probleem om de startup naar RC3 en/of rc5 to verplaatsen. Enige motivatie voor rc.local was dat ik het dan slechts een keer hoefde te doen.

[ Voor 43% gewijzigd door Verwijderd op 29-07-2003 15:35 . Reden: Onzin ]


  • ACM
  • Registratie: Januari 2000
  • Niet online

ACM

Software Architect

Werkt hier

Iig kan je er met rc6 mooi voor zorgen dat het down gaat _voor_ je netwerk down gaat :)
En in rc3/5 dat het up gaat _na_ je netwerk up komt.

Verwijderd

Topicstarter
Ik heb nu een signal handler voor SIGTERM toegevoegd die de sockets sluit en het lijkt verbeterd te zijn. Als er nog problemen zijn meld ik me weer. Dank aan allen voor het meedenken.
Pagina: 1