$(MKDIR_P) $(DESTDIR)$(pkglibdir)/available-modules
$(MKDIR_P) $(DESTDIR)$(sysconfdir)/faultd/available-modules
$(MKDIR_P) $(DESTDIR)$(sysconfdir)/faultd/enabled-modules
- $(MKDIR_P) $(DESTDIR)$(unitdir)/display-manager.service.d
- $(INSTALL) systemd-service.d/display-manager.service.conf $(DESTDIR)/$(unitdir)/display-manager.service.d/faultd.conf
if BUILD_TEST_PROGRAMS
TESTS = $(check_PROGRAMS)
endif
+
+generatorsdir = $(prefix)/lib/systemd/system-generators
+
+generators_PROGRAMS = vip-generator
+
+vip_generator_SOURCES = \
+ generators/vip-generator.c \
+ src/util/common.c \
+ src/util/systemd_dbus.c \
+ src/util/json-config.c \
+ src/util/log.c
+
+vip_generator_LDADD = $(LIBSYSTEMD_LIBS) $(JSON_C_LIBS)
--- /dev/null
+/*
+ * This file is part of faultd.
+ *
+ * Copyright © 2017 Samsung Electronics
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include <stdio.h>
+#include <string.h>
+#include <errno.h>
+#include <sys/stat.h>
+#include <dirent.h>
+
+#include "service.h"
+#include "json-config.h"
+#include "log.h"
+
+static const char *dest_path = "/tmp/";
+
+static char *get_next_file(DIR *conf_dir)
+{
+ struct dirent *d;
+
+ while (1) {
+ d = readdir(conf_dir);
+ if (d == NULL)
+ return NULL;
+
+ if (strcmp(d->d_name, ".") == 0 ||
+ strcmp(d->d_name, "..") == 0) {
+
+ continue;
+ }
+
+ return d->d_name;
+ }
+}
+
+static int create_dir(const char *path)
+{
+ if (mkdir(path, 0755) != 0) {
+ if (errno == EEXIST)
+ return 0;
+ else
+ return -errno;
+ }
+
+ return 0;
+}
+
+static char *get_service_name(char *conf_name)
+{
+ const char *suffix = ".conf";
+ int suffixlen = strlen(suffix);
+
+ int len = strlen(conf_name);
+ int prefixlen = len - suffixlen;
+
+ if (len > suffixlen && strcmp(&conf_name[prefixlen], suffix) == 0)
+ return strndup(conf_name, prefixlen);
+ else
+ return NULL;
+}
+
+static int create_vip_service_override(const char *service_name)
+{
+ FILE *fp;
+ char *location;
+ char *service_override;
+ int ret;
+
+ ret = asprintf(&location, "%s/%s.d", dest_path, service_name);
+ if (ret == -1)
+ return -errno;
+
+ ret = create_dir(location);
+ if (ret != 0) {
+ free(location);
+ return ret;
+ }
+
+ ret = asprintf(&service_override, "%s/faultd.conf", location);
+ free(location);
+ if (ret == -1)
+ return -errno;
+
+ fp = fopen(service_override, "w");
+ free(service_override);
+ if (fp == NULL)
+ return -errno;
+
+ fprintf(fp, "[Service]\n"
+ "Restart=no\n");
+ fclose(fp);
+
+ return 0;
+}
+
+static void init_systemd_service(struct systemd_service *s)
+{
+ assert(s);
+
+ s->dbus_path = NULL;
+ s->service_type = NULL;
+ s->recovery_unit = NULL;
+}
+
+static void free_systemd_service(struct systemd_service *s)
+{
+ if (s) {
+ free(s->dbus_path);
+ free(s->service_type);
+ free(s->recovery_unit);
+ }
+}
+
+int main(int argc, char *argv[])
+{
+ DIR *config_dir;
+ struct systemd_service s;
+ char *service_name;
+ char *service_config;
+ int ret;
+
+ /*
+ * This program follows systemd generator specification, please see:
+ * https://www.freedesktop.org/software/systemd/man/systemd.generator.html
+ */
+
+ if (argc > 1 && argc != 4) {
+ log_error("This program takes three or no arguments");
+ return EXIT_FAILURE;
+ }
+
+ if (argc > 1)
+ dest_path = argv[2];
+
+ config_dir = opendir(FAULTD_SERVICES_CONFIG_PATH);
+ if (!config_dir) {
+ log_error("Unable to open directory %s: %m", FAULTD_SERVICES_CONFIG_PATH);
+ return EXIT_FAILURE;
+ }
+
+ while ((service_config = get_next_file(config_dir)) != NULL) {
+ init_systemd_service(&s);
+
+ service_name = get_service_name(service_config);
+ if (service_name == NULL) {
+ log_error("Unable to get service name from config: %s", service_config);
+ goto cleanup;
+ }
+
+ ret = asprintf(&service_config, FAULTD_SERVICES_CONFIG_PATH "%s", service_config);
+ if (ret == -1) {
+ log_error("Unable to allocate string: %s", strerror(errno));
+ goto cleanup;
+ }
+
+ ret = parse_service_config(service_config, &s);
+ if (ret != 0) {
+ log_error("Unable to parse config file: %s", service_config);
+ free(service_config);
+ goto cleanup;
+ }
+
+ free(service_config);
+
+ if (systemd_service_is_of_type(&s, FAULTD_SERVICE_TYPE_VIP)) {
+ ret = create_vip_service_override(service_name);
+ if (ret != 0)
+ log_error("Unable to create override for VIP service %s: %s\n",
+ service_name, strerror(ret));
+ }
+
+ cleanup:
+ free(service_name);
+ free_systemd_service(&s);
+ }
+
+ closedir(config_dir);
+ return 0;
+}