On Mon, Feb 24, 2014 at 04:32:46PM +0100, Lennart Poettering wrote: > On Mon, 24.02.14 15:59, Michal Sekletar (msekl...@redhat.com) wrote: > > > hostnamed parses its state information at the startup time and doesn't > > update > > it. This might lead to the situation when we are presenting administrator > > with > > inaccurate information. We should watch for changes in the system and > > update our > > state information accordingly. > > Hmm, so there has been a TODO list item for a while that suggests to > refresh all information we expose when the user asks for it. More > specifically, we should stat() check the configuration files on each > property request, to see if they changed mtime since the last time. And > for the hostname we should simply never cache anything and always simply > go to the kernel. That is cheap enough and wouldn't make any fancy > hostname watching necessary.
Very well then, I will rework this as you suggest. Thanks, Michal > > > --- > > src/hostname/hostnamed.c | 88 > > ++++++++++++++++++++++++++++++++++++++++++++++++ > > 1 file changed, 88 insertions(+) > > > > diff --git a/src/hostname/hostnamed.c b/src/hostname/hostnamed.c > > index e57891b..045f24d 100644 > > --- a/src/hostname/hostnamed.c > > +++ b/src/hostname/hostnamed.c > > @@ -24,6 +24,10 @@ > > #include <unistd.h> > > #include <dlfcn.h> > > > > +#include <sys/types.h> > > +#include <sys/stat.h> > > +#include <fcntl.h> > > + > > #include "util.h" > > #include "strv.h" > > #include "def.h" > > @@ -46,8 +50,12 @@ enum { > > typedef struct Context { > > char *data[_PROP_MAX]; > > Hashmap *polkit_registry; > > + int hostnamefd; > > + sd_event_source *hostname_fd_event_source; > > } Context; > > > > +static const char *proc_hostname = "/proc/sys/kernel/hostname"; > > + > > static void context_reset(Context *c) { > > int p; > > > > @@ -59,11 +67,21 @@ static void context_reset(Context *c) { > > } > > } > > > > +static void context_init(Context *c) { > > + assert(c); > > + > > + memzero(c, sizeof(*c)); > > + > > + c->hostnamefd = -1; > > +} > > + > > static void context_free(Context *c, sd_bus *bus) { > > assert(c); > > > > context_reset(c); > > bus_verify_polkit_async_registry_free(bus, c->polkit_registry); > > + sd_event_source_unref(c->hostname_fd_event_source); > > + close_nointr_nofail(c->hostnamefd); > > } > > > > static int context_read_data(Context *c) { > > @@ -592,6 +610,70 @@ static int connect_bus(Context *c, sd_event *event, > > sd_bus **_bus) { > > return 0; > > } > > > > +static int dispatch_hostname_change(sd_event_source *s, int fd, uint32_t > > revents, void *userdata) { > > + int r = 0; > > + char hostname[HOST_NAME_MAX + 1] = {}, *t; > > + Context *context = (Context *) userdata; > > + > > + r = lseek(fd, 0, SEEK_SET); > > + if (r < 0) { > > + log_error("Failed to seek to begining of the file : %m"); > > + return -errno; > > + } > > + > > + r = read(fd, hostname, HOST_NAME_MAX); > > + if (r < 0) { > > + log_error("Failed to read hostname : %m"); > > + return -errno; > > + } > > + > > + strstrip(hostname); > > + > > + t = strdup(hostname); > > + if (!t) > > + return log_oom(); > > + free(context->data[PROP_HOSTNAME]); > > + context->data[PROP_HOSTNAME] = t; > > + > > + return r; > > +} > > + > > +static int open_hostname(sd_event *event, Context *context) { > > + int r = 0, fd; > > + > > + assert(event); > > + assert(context); > > + > > + fd = open(proc_hostname, O_RDONLY|O_CLOEXEC|O_NOCTTY|O_NOFOLLOW); > > + if (fd < 0) { > > + log_error("Failed to open %s : %m", proc_hostname); > > + return -errno; > > + } > > + > > + context->hostnamefd = fd; > > + > > + r = sd_event_add_io(event, &context->hostname_fd_event_source, fd, > > EPOLLHUP, dispatch_hostname_change, context); > > + if (r < 0) { > > + /* poll on /proc/sys/kernel/hostname not supported by > > kernel */ > > + if (r == -EPERM) { > > + log_warning("Failed to register hostname fd in > > event loop: %m. Ignoring."); > > + close_nointr_nofail(fd); > > + return 0; > > + } > > + > > + log_error("Failed to register hostname fd in event loop : > > %m"); > > + return r; > > + } > > + > > + r = > > sd_event_source_set_priority(context->hostname_fd_event_source, > > SD_EVENT_PRIORITY_IMPORTANT); > > + if (r < 0) { > > + log_error("Failed to set priority for hostname fd event > > source : %m"); > > + return r; > > + } > > + > > + return r; > > +} > > + > > int main(int argc, char *argv[]) { > > Context context = {}; > > > > @@ -621,6 +703,8 @@ int main(int argc, char *argv[]) { > > goto finish; > > } > > > > + context_init(&context); > > + > > r = sd_event_default(&event); > > if (r < 0) { > > log_error("Failed to allocate event loop: %s", > > strerror(-r)); > > @@ -639,6 +723,10 @@ int main(int argc, char *argv[]) { > > goto finish; > > } > > > > + r = open_hostname(event, &context); > > + if (r < 0) > > + goto finish; > > + > > r = bus_event_loop_with_idle(event, bus, > > "org.freedesktop.hostname1", DEFAULT_EXIT_USEC, NULL, NULL); > > if (r < 0) { > > log_error("Failed to run event loop: %s", strerror(-r)); > > > Lennart > > -- > Lennart Poettering, Red Hat _______________________________________________ systemd-devel mailing list systemd-devel@lists.freedesktop.org http://lists.freedesktop.org/mailman/listinfo/systemd-devel