~ubuntu-branches/debian/experimental/sysvinit/experimental

« back to all changes in this revision

Viewing changes to debian/startpar/startpar.c

  • Committer: Bazaar Package Importer
  • Author(s): Petter Reinholdtsen, Petter Reinholdtsen, Kel Modderman
  • Date: 2009-07-24 10:51:50 UTC
  • Revision ID: james.westby@ubuntu.com-20090724105150-gwwfemn5xccc9gdb
Tags: 2.86.ds1-66
[ Petter Reinholdtsen ]
* Replace Ó with \['O] and Á with \['A] in spanish
  update-rc.d(8) after looking up the correct string in
  groff_man(7), to avoid lintian warning.
* Move bootlogd to the sysvinit-utils package, as it is useful also
  without the sysvinit init program.  Make sysvinit-utils replace
  sysvinit (<= 2.86.ds1-65) to handle this.
* Clean up control file, dropping replaces and conflicts on sysvinit
  and file-rc packages before oldstable: sysvinit (<< 2.85-1),
  sysv-rc (<< 2.86.ds1-1.2), sysvinit (<< 2.86.ds1-12) and file-rc
  (>> 0.7.0).
* New patch 54_bootlogd_findptyfail making sure bootlogd findpty()
  returns an error value  when it fails to find a usable pty
  (Closes: #492796).  Patch from Rob Leslie.
* New patch 96_shutdown_acctoff making sure to call accton with the
  argument off during shutdown to stop accounting (Closes: #536574).
* Modify LSB header of init.d/bootlogd to depend on $all when
  starting, to get it to start later in the boot sequence
  (Closes: #531198.  Patch from Vincent Crevot.
* Modify LSB header of init.d/bootlogd to start earlier when
  dependency based boot sequencing is enabled, by stating that
  it should start before keymap and keyboard-setup.
* Make sure more verbose temp cleaning always calls log_end_msg
  after log_begin_msg (might solve #534713).
* New patch 97_init_starttest solving problem reported to
  <URL:http://freshmeat.net/projects/sysvinit/> 2003-03-10.
* Change init.d/bootmisc.sh to not set pseudo-terminal access
  permissions when udev is active.  Leave that to udev, the same way
  it is left to devfs.
* Correct boot dependency, move hostname dependency from bootmisc.sh to
  bootlogs.

[ Kel Modderman ]
* Remove debian/startpar/README, it contains outdated information about
  the origin of startpar upstream.
* Update startpar to version 0.53.1 upstream. Add Debian quilt patch series
  to ./debian/startpar/patches, while they wait for inclusion upstream.
* Patch startpar makeboot.c to allow a much higher amount of loops when
  calculating dependecies from make files.
* Modify all copyright blurbs which refer to the version-less symlink
  /usr/share/common-licenses/GPL to point to the versioned GPL-2 license.

Show diffs side-by-side

added added

removed removed

Lines of Context:
29
29
#include <sys/select.h>
30
30
#include <sys/time.h>
31
31
#include <sys/ioctl.h>
 
32
#include <sys/socket.h>
 
33
#include <sys/un.h>
32
34
#include <sys/sysinfo.h>
33
35
#include <sys/stat.h>
 
36
#ifndef SUSE
34
37
#include <sys/vfs.h>
 
38
#endif
35
39
#include <time.h>
36
40
#include <fcntl.h>
37
41
#include <errno.h>
65
69
static char *run_mode = NULL;
66
70
static struct makenode **nodevec;
67
71
 
 
72
static enum { Unknown, Preload, NoPreload } ispreload = Unknown;
 
73
 
68
74
#define PBUF_SIZE       8192
69
75
struct prg {
70
 
  char *name;
 
76
  const char *name;
 
77
  const char *arg0;
71
78
  int num;
72
79
  int fd;
73
80
  pid_t pid;
82
89
static int pidpipe[2];
83
90
static double iorate = 800.0;
84
91
 
 
92
void sighandler_nopreload(int x)
 
93
{
 
94
    (void)x;
 
95
    ispreload = NoPreload;
 
96
}
 
97
 
 
98
 
 
99
void sighandler_preload(int x)
 
100
{
 
101
    (void)x;
 
102
    ispreload = Preload;
 
103
}
 
104
 
85
105
void *xcalloc(size_t nmemb, size_t size)
86
106
{
87
107
  void *r;
151
171
  close(pidpipe[1]);
152
172
}
153
173
 
154
 
void callsplash(int n, char *path, char *action)
 
174
void callsplash(int n, const char *path, char *action)
155
175
{
156
 
  char *p;
 
176
  const char *p;
157
177
  char sbuf[32];
158
178
  char tbuf[256];
159
179
  pid_t pid;
249
269
  if (read_proc(&prcs_run, &prcs_blked))
250
270
    return par;
251
271
 
 
272
  /* if we have preload running, we expect I/O not to be a problem */
 
273
  if (ispreload != NoPreload)
 
274
    prcs_blked = 0;
 
275
 
252
276
  newpar  = (par*numcpu) - prcs_run + 1;        /* +1 for startpar its self */
253
277
  newpar -= (int)(((double)prcs_blked)*iorate); /* I/O load reduction */
254
278
 
255
279
#if DEBUG
256
 
  fprintf(stderr, "checksystem par=%d newpar=%d (prcs_run=%u) %ld\n", par, newpar, prcs_run, time(0));
 
280
  fprintf(stderr, "checksystem par=%d newpar=%d (prcs_run=%lu) %ld\n", par, newpar, prcs_run, time(0));
257
281
  dump_status();
258
282
#endif
259
283
  if (newpar <= 0)
272
296
  return checksystem(par, start, false);
273
297
}
274
298
 
 
299
#define SOCK_PATH "/dev/shm/preload_sock"
 
300
 
 
301
#ifdef SUSE
 
302
static int checkdevpts(void)
 
303
{
 
304
  /* /dev/pts is always mounted */
 
305
  return 1;
 
306
}
 
307
#else
275
308
/*
276
309
 * Based on __posix_openpt() from glibc.  Reimplemented here to work
277
310
 * around the problem with getpt() failing for the entire process life
327
360
      return 1;
328
361
    }
329
362
}
 
363
#endif
330
364
 
331
365
void run(struct prg *p)
332
366
{
333
367
  char *m = 0;
 
368
  pid_t parent = getpid();
334
369
 
335
370
  p->len = 0;
336
371
  p->pid = (pid_t)0;
398
433
 
399
434
  closeall();
400
435
 
 
436
  if (!strcmp(arg, "start")) 
 
437
    { 
 
438
      int s, t, len;
 
439
      pid_t child;
 
440
      struct sockaddr_un remote;
 
441
      char str[100];
 
442
 
 
443
      s = socket(AF_UNIX, SOCK_STREAM, 0);
 
444
      if (s != -1) 
 
445
        {
 
446
          memset(&remote, 0, sizeof(struct sockaddr_un));
 
447
          remote.sun_family = AF_UNIX;
 
448
          strcpy(remote.sun_path, SOCK_PATH);
 
449
          len = strlen(remote.sun_path) + sizeof(remote.sun_family);
 
450
 
 
451
          t = connect(s, (struct sockaddr *)&remote, len);
 
452
          if (t != -1) 
 
453
            {
 
454
              if (ispreload != Preload)
 
455
                kill(parent, SIGUSR1);
 
456
              send(s, p->name, strlen(p->name), 0);
 
457
              recv(s, str, 100, 0);
 
458
            } 
 
459
          else if ( ispreload == Unknown) 
 
460
            {
 
461
              /*
 
462
               * if we connected to preload once, we know it ran.
 
463
               * In case we can't connect to it later, it means it did
 
464
               * its job and we can guess I/O is no longer a problem. 
 
465
               */
 
466
              kill(parent, SIGUSR2);
 
467
            }
 
468
          close(s);
 
469
          /*
 
470
           * if we use preload, we fork again to make bootcharts easier to read.
 
471
           * The reason is that the name of the init script will otherwise be used
 
472
           * when in reality the above code waited for preload. If we fork away
 
473
           * before the exec, the waiting code will be folded into startpar
 
474
           */
 
475
          child = fork();
 
476
          if (child) {
 
477
                int status;
 
478
                int ret = waitpid(child, &status, 0);
 
479
                if (ret == -1)
 
480
                        perror("waitpid");
 
481
                exit(WEXITSTATUS(status));
 
482
          }
 
483
        }
 
484
    }
 
485
 
401
486
  if (run_mode)
402
487
    {
403
488
      char path[128];
404
489
      snprintf(path, sizeof(path), "/etc/init.d/%s", p->name);
405
 
      execlp(path, path, arg, (char *)0);
 
490
      execlp(path, p->arg0, arg, (char *)0);
406
491
    }
407
492
  else if (arg)
408
 
    execlp(p->name, p->name, arg, (char *)0);
 
493
    execlp(p->name, p->arg0, arg, (char *)0);
409
494
  else
410
 
    execlp(p->name, p->name, (char *)0);
 
495
    execlp(p->name, p->arg0, (char *)0);
411
496
  perror(p->name);
412
497
  _exit(1);
413
498
}
414
499
 
415
 
int run_single(char *prg, int spl)
 
500
int run_single(const char *prg, const char *arg0, int spl)
416
501
{
417
502
  pid_t pid;
418
503
  int r;
439
524
        {
440
525
          char path[128];
441
526
          snprintf(path, sizeof(path), "/etc/init.d/%s", prg);
442
 
          execlp(path, path, arg, (char *)0);
 
527
          execlp(path, arg0 ? arg0 : path, arg, (char *)0);
443
528
        }
444
529
      else if (arg)
445
 
        execlp(prg, prg, arg, (char *)0);
 
530
        execlp(prg, arg0 ? arg0 : prg, arg, (char *)0);
446
531
      else
447
 
        execlp(prg, prg, (char *)0);
 
532
        execlp(prg, arg0 ? arg0 : prg, (char *)0);
448
533
      perror(prg);
449
534
      _exit(1);
450
535
    }
614
699
  char *run_level = getenv("RUNLEVEL");
615
700
  char *splashopt = 0;
616
701
 
 
702
  (void)signal(SIGUSR1, sighandler_preload);
 
703
  (void)signal(SIGUSR2, sighandler_nopreload);
 
704
 
617
705
  (void)signal(SIGCHLD, SIG_DFL);
618
706
  numcpu = sysconf(_SC_NPROCESSORS_ONLN);
619
707
  myname = argv[0];
767
855
        {
768
856
          if ((*nodevec = pickup_task()))
769
857
          {
770
 
            *resvec = run_single((*nodevec)->name, calcsplash(0, 1, splashopt));
 
858
            *resvec = run_single((*nodevec)->name, (*nodevec)->arg0, calcsplash(0, 1, splashopt));
771
859
            finish_task(*nodevec);
772
860
          }
773
861
      } else
774
 
        *resvec = run_single(*argv, calcsplash(0, 1, splashopt));
 
862
        *resvec = run_single(*argv, *argv, calcsplash(0, 1, splashopt));
775
863
      goto finished;
776
864
    }
777
865
 
878
966
                      if (nodevec[num]->interactive)
879
967
                        interactive_task = p;
880
968
                      p->name = nodevec[num]->name;
 
969
                      p->arg0 = nodevec[num]->arg0 ? nodevec[num]->arg0 : nodevec[num]->name;
881
970
                    }
882
 
                  else
 
971
                  else {
883
972
                    p->name = *argv++;
 
973
                    p->arg0 = p->name;
 
974
                  }
884
975
                  p->splashadd = calcsplash(num, argc, splashopt);
885
976
                  p->num = num++;
886
 
                  if (!devpts)                  /* no /dev/pts, treat as interactive */
887
 
                    interactive_task = p;
888
977
                  if (interactive_task)
889
978
                    continue;                   /* don't start this here */
 
979
                  if (!devpts)
 
980
                    {
 
981
                      interactive_task = p;     /* no /dev/pts, treat as interactive */
 
982
                      continue;
 
983
                    }
890
984
                  run(p);
891
985
                  if (p->pid == 0)
892
986
                    {
917
1011
          if (active == 0)
918
1012
            {
919
1013
              p = interactive_task;
920
 
              resvec[p->num] = run_single(p->name, p->splashadd);
 
1014
              resvec[p->num] = run_single(p->name, p->arg0, p->splashadd);
921
1015
              if (run_mode)
922
1016
                finish_task(nodevec[p->num]);
923
1017
              p->pid = 0;