chiark / gitweb /
Do some basic compatibility checking when installing a new server
authorRichard Kettlewell <rjk@greenend.org.uk>
Sun, 12 Apr 2009 16:52:03 +0000 (17:52 +0100)
committerRichard Kettlewell <rjk@greenend.org.uk>
Sun, 12 Apr 2009 16:52:03 +0000 (17:52 +0100)
configuration.  There is plenty more that could be done.

18 files changed:
README.reload
cgi/cgimain.c
clients/disorder.c
clients/playrtp.c
disobedience/disobedience.c
lib/configuration.c
lib/configuration.h
server/choose.c
server/dbupgrade.c
server/deadlock.c
server/disorderd.c
server/dump.c
server/normalize.c
server/rescan.c
server/speaker.c
server/state.c
server/stats.c
server/trackname.c

index 66d74a8..6c645ec 100644 (file)
@@ -5,14 +5,15 @@ This is current rather vaguely defined and implemented.  This file
 will lay out what you can and cannot change over a reconfigure.  Any
 other changes will require a full server restart.
 
-I intend to improve the situation, but for now this is how it is.
+The situation is gradually improving; this file tracks the current
+state.
 
 * Options that might have to remain the same across restart
 
 Arguably if there is anything in this section then that's a serious
 bug!
 
-** alias
+** alias (enforced at reload only)
 
 This defines how aliases are inserted into the track database.  Need
 to think about how changing it will affect things.
@@ -26,7 +27,7 @@ Probably affects alias construction.
 The search database will have to be rebuilt from scratch.  This is
 do-able but AFAIK we don't detect it.
 
-** user
+** user (enforced at reload only)
 
 All the files will be owned by the wrong user!
 
@@ -36,20 +37,18 @@ Some things will just require a restart.  We should either enforce
 this (refusing to accept modified configurations that purport to
 change them) or explicitly ignore it.
 
-** home
+** home (enforced at reload)
 
-We absolutely cannot accept changing our state directory.  If this is
-attempted it must be rejected.
+We absolutely cannot accept changing our state directory.
 
-** lock
+** lock (generates a deprecation warning)
 
 Liable to be removed anyway.
 
-** nice_speaker
+** nice_speaker (generates a warning)
 
-Can't renice a running speaker to make it less nice (and we don't try
-to make it more nice).  We ought to issue an error message and
-otherwise ignore.
+You can't renice a running speaker to make it less nice (and we don't
+try to make it more nice).
 
 * Options that ought to be changable across reload but aren't
 
index 583af30..e4c7220 100644 (file)
@@ -48,7 +48,7 @@ int main(int argc, char **argv) {
   if(getenv("DISORDER_DEBUG"))
     debugging = 1;
   /* Read configuration */
-  if(config_read(0/*!server*/))
+  if(config_read(0/*!server*/, NULL))
     exit(EXIT_FAILURE);
   /* Figure out our URL.  This can still be overridden from the config file if
    * necessary but it shouldn't be necessary in ordinary installations. */
index 2466311..bc2a8ec 100644 (file)
@@ -158,7 +158,7 @@ static void cf_shutdown(char attribute((unused)) **argv) {
 
 static void cf_reconfigure(char attribute((unused)) **argv) {
   /* Re-check configuration for server */
-  if(config_read(1)) fatal(0, "cannot read configuration");
+  if(config_read(1, NULL)) fatal(0, "cannot read configuration");
   if(disorder_reconfigure(getclient())) exit(EXIT_FAILURE);
 }
 
@@ -754,7 +754,7 @@ int main(int argc, char **argv) {
     default: fatal(0, "invalid option");
     }
   }
-  if(config_read(0)) fatal(0, "cannot read configuration");
+  if(config_read(0, NULL)) fatal(0, "cannot read configuration");
   if(user) {
     config->username = user;
     config->password = 0;
index f5f538d..81c1e8e 100644 (file)
@@ -621,7 +621,7 @@ int main(int argc, char **argv) {
     default: fatal(0, "invalid option");
     }
   }
-  if(config_read(0)) fatal(0, "cannot read configuration");
+  if(config_read(0, NULL)) fatal(0, "cannot read configuration");
   if(!maxbuffer)
     maxbuffer = 2 * minbuffer;
   argc -= optind;
index dea9d59..a4e9d20 100644 (file)
@@ -460,7 +460,7 @@ int main(int argc, char **argv) {
   /* create the event loop */
   D(("create main loop"));
   mainloop = g_main_loop_new(0, 0);
-  if(config_read(0)) fatal(0, "cannot read configuration");
+  if(config_read(0, NULL)) fatal(0, "cannot read configuration");
   /* we'll need mixer support */
   backend = uaudio_apis[0];
   if(backend->open_mixer)
index 1fcfb1a..dd08949 100644 (file)
@@ -1156,7 +1156,7 @@ static struct config *config_default(void) {
   logname = pw->pw_name;
   c->username = xstrdup(logname);
   c->refresh = 15;
-  c->prefsync = 3600;
+  c->prefsync = 0;
   c->signal = SIGKILL;
   c->alias = xstrdup("{/artist}{/album}{/title}{ext}");
   c->lock = 1;
@@ -1326,8 +1326,14 @@ static void config_postdefaults(struct config *c,
 
 /** @brief (Re-)read the config file
  * @param server If set, do extra checking
+ * @param oldconfig Old configuration for compatibility check
+ * @return 0 on success, non-0 on error
+ *
+ * If @p oldconfig is set, then certain compatibility checks are done between
+ * the old and new configurations.
  */
-int config_read(int server) {
+int config_read(int server,
+                const struct config *oldconfig) {
   struct config *c;
   char *privconf;
   struct passwd *pw;
@@ -1362,6 +1368,31 @@ int config_read(int server) {
   }
   /* install default namepart and transform settings */
   config_postdefaults(c, server);
+  if(oldconfig)  {
+    int failed = 0;
+    if(strcmp(c->home, oldconfig->home)) {
+      error(0, "'home' cannot be changed without a restart");
+      failed = 1;
+    }
+    if(strcmp(c->alias, oldconfig->alias)) {
+      error(0, "'alias' cannot be changed without a restart");
+      failed = 1;
+    }
+    if(strcmp(c->user, oldconfig->user)) {
+      error(0, "'user' cannot be changed without a restart");
+      failed = 1;
+    }
+    if(c->nice_speaker != oldconfig->nice_speaker) {
+      error(0, "'nice_speaker' cannot be changed without a restart");
+      /* ...but we accept the new config anyway */
+    }
+    /* TODO namepart */
+    /* TODO stopword */
+    if(failed) {
+      error(0, "not installing incompatible new configuration");
+      return -1;
+    }
+  }
   /* everything is good so we shall use the new config */
   config_free(config);
   /* warn about obsolete directives */
@@ -1371,6 +1402,12 @@ int config_read(int server) {
     error(0, "'allow' will be removed in a future version");
   if(c->trust.n)
     error(0, "'trust' will be removed in a future version");
+  if(!c->lock)
+    error(0, "'lock' will be removed in a future version");
+  if(c->gap)
+    error(0, "'gap' will be removed in a future version");
+  if(c->prefsync)
+    error(0, "'prefsync' will be removed in a future version");
   config = c;
   return 0;
 }
index 4cb5677..e9fce73 100644 (file)
@@ -292,7 +292,8 @@ struct config {
 extern struct config *config;
 /* the current configuration */
 
-int config_read(int server);
+int config_read(int server,
+                const struct config *oldconfig);
 /* re-read config, return 0 on success or non-0 on error.
  * Only updates @config@ if the new configuration is valid. */
 
index bc82475..10ed360 100644 (file)
@@ -281,7 +281,7 @@ int main(int argc, char **argv) {
     openlog(progname, LOG_PID, LOG_DAEMON);
     log_default = &log_syslog;
   }
-  if(config_read(0)) fatal(0, "cannot read configuration");
+  if(config_read(0, NULL)) fatal(0, "cannot read configuration");
   /* Find out current queue/recent list */
   queue_read();
   recent_read();
index bd08eed..09dd789 100644 (file)
@@ -333,7 +333,7 @@ int main(int argc, char **argv) {
     openlog(progname, LOG_PID, LOG_DAEMON);
     log_default = &log_syslog;
   }
-  if(config_read(0)) fatal(0, "cannot read configuration");
+  if(config_read(0, NULL)) fatal(0, "cannot read configuration");
   /* Open the database */
   trackdb_init(TRACKDB_NO_RECOVER);
   trackdb_open(TRACKDB_OPEN_FOR_UPGRADE);
index 3c13351..d90a123 100644 (file)
@@ -71,7 +71,7 @@ int main(int argc, char **argv) {
     openlog(progname, LOG_PID, LOG_DAEMON);
     log_default = &log_syslog;
   }
-  if(config_read(0)) fatal(0, "cannot read configuration");
+  if(config_read(0, NULL)) fatal(0, "cannot read configuration");
   info("started");
   trackdb_init(TRACKDB_NO_RECOVER);
   while(getppid() != 1) {
index 74fc07e..ab6221a 100644 (file)
@@ -230,7 +230,7 @@ int main(int argc, char **argv) {
   if(ev_child_setup(ev)) fatal(0, "ev_child_setup failed");
   /* read config */
   config_uaudio_apis = uaudio_apis;
-  if(config_read(1))
+  if(config_read(1,  NULL))
     fatal(0, "cannot read configuration");
   /* make sure the home directory exists and has suitable permissions */
   make_home();
index e08b32f..4b023aa 100644 (file)
@@ -473,7 +473,7 @@ int main(int argc, char **argv) {
       fatal(0, "specify only a dump file name");
     path = argv[optind];
   }
-  if(config_read(0)) fatal(0, "cannot read configuration");
+  if(config_read(0, NULL)) fatal(0, "cannot read configuration");
   trackdb_init(recover|TRACKDB_MAY_CREATE);
   trackdb_open(TRACKDB_NO_UPGRADE);
   if(dump) {
index db5b9d5..717f3cc 100644 (file)
@@ -141,7 +141,7 @@ int main(int argc, char attribute((unused)) **argv) {
     default: fatal(0, "invalid option");
     }
   }
-  if(config_read(1))
+  if(config_read(1, NULL))
     fatal(0, "cannot read configuration");
   if(logsyslog) {
     openlog(progname, LOG_PID, LOG_DAEMON);
index 1380e24..ebff098 100644 (file)
@@ -380,7 +380,7 @@ int main(int argc, char **argv) {
     openlog(progname, LOG_PID, LOG_DAEMON);
     log_default = &log_syslog;
   }
-  if(config_read(0)) fatal(0, "cannot read configuration");
+  if(config_read(0, NULL)) fatal(0, "cannot read configuration");
   xnice(config->nice_rescan);
   sa.sa_handler = signal_handler;
   sa.sa_flags = SA_RESTART;
index b41c94f..adda2eb 100644 (file)
@@ -608,7 +608,7 @@ static void mainloop(void) {
          break;
        case SM_RELOAD:
           D(("SM_RELOAD"));
-         if(config_read(1))
+         if(config_read(1, NULL))
             error(0, "cannot read configuration");
           info("reloaded configuration");
          break;
@@ -707,7 +707,7 @@ int main(int argc, char **argv) {
     log_default = &log_syslog;
   }
   config_uaudio_apis = uaudio_apis;
-  if(config_read(1)) fatal(0, "cannot read configuration");
+  if(config_read(1, NULL)) fatal(0, "cannot read configuration");
   /* ignore SIGPIPE */
   signal(SIGPIPE, SIG_IGN);
   /* set nice value */
index a881e9b..1c1e2aa 100644 (file)
@@ -164,7 +164,7 @@ int reconfigure(ev_source *ev, int reload) {
     /* Close the track database */
     trackdb_close();
     /* (Re-)read the configuration */
-    if(config_read(1/*server*/))
+    if(config_read(1/*server*/, config))
       ret = -1;
     else {
       /* Tell the speaker it needs to reload its config too. */
index 81c92f4..ad35cb8 100644 (file)
@@ -74,7 +74,7 @@ int main(int argc, char **argv) {
     openlog(progname, LOG_PID, LOG_DAEMON);
     log_default = &log_syslog;
   }
-  if(config_read(0))
+  if(config_read(0, NULL))
     fatal(0, "cannot read configuration");
   trackdb_init(TRACKDB_NO_RECOVER);
   trackdb_open(TRACKDB_NO_UPGRADE);
index ec84f68..b661e0c 100644 (file)
@@ -57,7 +57,7 @@ int main(int argc, char **argv) {
   }
   if(argc - optind < 3) fatal(0, "not enough arguments");
   if(argc - optind > 3) fatal(0, "too many arguments");
-  if(config_read(0)) fatal(0, "cannot read configuration");
+  if(config_read(0, NULL)) fatal(0, "cannot read configuration");
   s = trackname_part(argv[optind], argv[optind+1], argv[optind+2]);
   if(!s) fatal(0, "trackname_part returned NULL");
   xprintf("%s\n", nullcheck(utf82mb(s)));