X-Git-Url: https://www.chiark.greenend.org.uk/ucgi/~ianmdlvl/git?a=blobdiff_plain;f=name.h;h=17bb35d6a74e197c5ccba3aca693007421c81c24;hb=c22cbe2672db2c95647c9412cfb4331d2be279a7;hp=0ed1056595d44f75c8722af73de01ab81b6585e2;hpb=42f4e3c4413ad35e3815f25211fee95d775488a7;p=elogind.git diff --git a/name.h b/name.h index 0ed105659..17bb35d6a 100644 --- a/name.h +++ b/name.h @@ -8,14 +8,11 @@ typedef union Name Name; typedef struct Meta Meta; -typedef struct Service Service; -typedef struct Timer Timer; -typedef struct Socket Socket; -typedef struct Milestone Milestone; -typedef struct Device Device; -typedef struct Mount Mount; -typedef struct Automount Automount; -typedef struct Snapshot Snapshot; +typedef struct NameVTable NameVTable; +typedef enum NameType NameType; +typedef enum NameLoadState NameLoadState; +typedef enum NameActiveState NameActiveState; +typedef enum NameDependency NameDependency; #include "job.h" #include "manager.h" @@ -23,50 +20,84 @@ typedef struct Snapshot Snapshot; #include "util.h" #include "list.h" #include "socket-util.h" +#include "execute.h" +#include "util.h" + +#define NAME_MAX 32 +#define DEFAULT_TIMEOUT_USEC (20*USEC_PER_SEC) +#define DEFAULT_RESTART_USEC (100*USEC_PER_MSEC) -typedef enum NameType { +enum NameType { NAME_SERVICE = 0, NAME_TIMER, NAME_SOCKET, - NAME_MILESTONE, + NAME_TARGET, NAME_DEVICE, NAME_MOUNT, NAME_AUTOMOUNT, NAME_SNAPSHOT, _NAME_TYPE_MAX, _NAME_TYPE_INVALID = -1, -} NameType; +}; -typedef enum NameState { +enum NameLoadState { NAME_STUB, NAME_LOADED, NAME_FAILED, - _NAME_STATE_MAX -} NameState; + _NAME_LOAD_STATE_MAX +}; + +enum NameActiveState { + NAME_ACTIVE, + NAME_ACTIVE_RELOADING, + NAME_INACTIVE, + NAME_ACTIVATING, + NAME_DEACTIVATING, + _NAME_ACTIVE_STATE_MAX +}; + +static inline bool NAME_IS_ACTIVE_OR_RELOADING(NameActiveState t) { + return t == NAME_ACTIVE || t == NAME_ACTIVE_RELOADING; +} + +static inline bool NAME_IS_ACTIVE_OR_ACTIVATING(NameActiveState t) { + return t == NAME_ACTIVE || t == NAME_ACTIVATING || t == NAME_ACTIVE_RELOADING; +} + +static inline bool NAME_IS_INACTIVE_OR_DEACTIVATING(NameActiveState t) { + return t == NAME_INACTIVE || t == NAME_DEACTIVATING; +} -typedef enum NameDependency { +enum NameDependency { /* Positive dependencies */ NAME_REQUIRES, NAME_SOFT_REQUIRES, NAME_WANTS, NAME_REQUISITE, NAME_SOFT_REQUISITE, - NAME_REQUIRED_BY, /* inverse of 'requires' and 'requisite' is 'required_by' */ - NAME_WANTED_BY, /* inverse of 'wants', 'soft_requires' and 'soft_requisite' is 'wanted_by' */ + + /* Inverse of the above */ + NAME_REQUIRED_BY, /* inverse of 'requires' and 'requisite' is 'required_by' */ + NAME_SOFT_REQUIRED_BY, /* inverse of 'soft_requires' and 'soft_requisite' is 'soft_required_by' */ + NAME_WANTED_BY, /* inverse of 'wants' */ /* Negative dependencies */ - NAME_CONFLICTS, /* inverse of 'conflicts' is 'conflicts' */ + NAME_CONFLICTS, /* inverse of 'conflicts' is 'conflicts' */ /* Order */ - NAME_BEFORE, /* inverse of before is after and vice versa */ + NAME_BEFORE, /* inverse of before is after and vice versa */ NAME_AFTER, - _NAME_DEPENDENCY_MAX -} NameDependency; + + _NAME_DEPENDENCY_MAX, + _NAME_DEPENDENCY_INVALID = -1 +}; struct Meta { Manager *manager; NameType type; - NameState state; + NameLoadState load_state; + + char *id; /* One name is special because we use it for identification. Points to an entry in the names set */ Set *names; Set *dependencies[_NAME_DEPENDENCY_MAX]; @@ -78,211 +109,131 @@ struct Meta { Job *job; bool linked:1; + bool in_load_queue:1; + + usec_t active_enter_timestamp; + usec_t active_exit_timestamp; /* Load queue */ - LIST_FIELDS(Meta); + LIST_FIELDS(Meta, load_queue); }; -typedef enum ServiceState { - SERVICE_DEAD, - SERVICE_BEFORE, - SERVICE_START_PRE, - SERVICE_START, - SERVICE_START_POST, - SERVICE_RUNNING, - SERVICE_RELOAD_PRE, - SERVICE_RELOAD, - SERVICE_RELOAD_POST, - SERVICE_STOP_PRE, - SERVICE_STOP, - SERVICE_SIGTERM, - SERVICE_SIGKILL, - SERVICE_STOP_POST, - SERVICE_HOLDOFF, - SERVICE_MAINTAINANCE -} ServiceState; - -typedef enum ServiceMode { - SERVICE_ONCE, - SERVICE_RESTART -} ServiceMode; - -struct Service { - Meta meta; - - ServiceState state; - ServiceMode mode; -}; +#include "service.h" +#include "timer.h" +#include "socket.h" +#include "target.h" +#include "device.h" +#include "mount.h" +#include "automount.h" +#include "snapshot.h" -typedef enum TimerState { - TIMER_DEAD, - TIMER_BEFORE, - TIMER_START_PRE, - TIMER_START, - TIMER_START_POST, - TIMER_WAITING, - TIMER_RUNNING, - TIMER_STOP_PRE, - TIMER_STOP, - TIMER_STOP_POST, - TIMER_MAINTAINANCE -} TimerState; - -struct Timer { - Meta meta; - - TimerState state; - Service *subject; - - clockid_t clock_id; - usec_t next_elapse; -}; - -typedef enum SocketState { - SOCKET_DEAD, - SOCKET_BEFORE, - SOCKET_START_PRE, - SOCKET_START, - SOCKET_START_POST, - SOCKET_LISTENING, - SOCKET_RUNNING, - SOCKET_STOP_PRE, - SOCKET_STOP, - SOCKET_STOP_POST, - SOCKET_MAINTAINANCE, - _SOCKET_STATE_MAX -} SocketState; - -struct Socket { +union Name { Meta meta; - - SocketState state; - - Address address; - int *fds; - unsigned n_fds; - - Service *subject; + Service service; + Timer timer; + Socket socket; + Target target; + Device device; + Mount mount; + Automount automount; + Snapshot snapshot; }; -typedef enum MilestoneState { - MILESTONE_DEAD, - MILESTONE_BEFORE, - MILESTONE_ACTIVE -} MilestoneState; - -struct Milestone { - Meta meta; - - MilestoneState state; -}; +struct NameVTable { + const char *suffix; -typedef enum DeviceState { - DEVICE_DEAD, - DEVICE_BEFORE, - DEVICE_AVAILABLE -} DeviceState; + int (*init)(Name *n); + void (*done)(Name *n); -struct Device { - Meta meta; + void (*dump)(Name *n, FILE *f, const char *prefix); - DeviceState state; - char *sysfs; -}; + int (*start)(Name *n); + int (*stop)(Name *n); + int (*reload)(Name *n); -typedef enum MountState { - MOUNT_DEAD, - MOUNT_BEFORE, - MOUNT_MOUNTED -} MountState; -struct Mount { - Meta meta; + bool (*can_reload)(Name *n); - MountState state; - char *path; -}; + /* Boils down the more complex internal state of this name to + * a simpler one that the engine can understand */ + NameActiveState (*active_state)(Name *n); -typedef enum AutomountState { - AUTOMOUNT_DEAD, - AUTOMOUNT_BEFORE, - AUTOMOUNT_START_PRE, - AUTOMOUNT_START, - AUTOMOUNT_START_POST, - AUTOMOUNT_WAITING, - AUTOMOUNT_RUNNING, - AUTOMOUNT_STOP_PRE, - AUTOMOUNT_STOP, - AUTOMOUNT_STOP_POST, - AUTOMOUNT_MAINTAINANCE -} AutomountState; - -struct Automount { - Meta meta; + void (*fd_event)(Name *n, int fd, uint32_t events); + void (*sigchld_event)(Name *n, pid_t pid, int code, int status); + void (*timer_event)(Name *n, int id, uint64_t n_elapsed); - AutomountState state; - char *path; - Mount *subject; + void (*retry)(Name *n); }; -typedef enum SnapshotState { - SNAPSHOT_DEAD, - SNAPSHOT_BEFORE, - SNAPSHOT_ACTIVE -} SnapshotState; - -struct Snapshot { - Meta meta; +extern const NameVTable * const name_vtable[_NAME_TYPE_MAX]; - SnapshotState state; - bool cleanup:1; -}; - -union Name { - Meta meta; - Service service; - Timer timer; - Socket socket; - Milestone milestone; - Device device; - Mount mount; - Automount automount; - Snapshot snapshot; -}; +#define NAME_VTABLE(n) name_vtable[(n)->meta.type] /* For casting a name into the various name types */ - -#define DEFINE_CAST(UPPERCASE, MixedCase, lowercase) \ +#define DEFINE_CAST(UPPERCASE, MixedCase) \ static inline MixedCase* UPPERCASE(Name *name) { \ - if (name->meta.type != NAME_##UPPERCASE) \ + if (!name || name->meta.type != NAME_##UPPERCASE) \ return NULL; \ \ - return &name->lowercase; \ + return (MixedCase*) name; \ } -DEFINE_CAST(SERVICE, Service, service); -DEFINE_CAST(TIMER, Timer, timer); -DEFINE_CAST(SOCKET, Socket, socket); -DEFINE_CAST(MILESTONE, Milestone, milestone); -DEFINE_CAST(DEVICE, Device, device); -DEFINE_CAST(MOUNT, Mount, mount); -DEFINE_CAST(AUTOMOUNT, Automount, automount); -DEFINE_CAST(SNAPSHOT, Snapshot, snapshot); - /* For casting the various name types into a name */ #define NAME(o) ((Name*) (o)) -bool name_is_ready(Name *name); +DEFINE_CAST(SOCKET, Socket); +DEFINE_CAST(TIMER, Timer); +DEFINE_CAST(SERVICE, Service); +DEFINE_CAST(TARGET, Target); +DEFINE_CAST(DEVICE, Device); +DEFINE_CAST(MOUNT, Mount); +DEFINE_CAST(AUTOMOUNT, Automount); +DEFINE_CAST(SNAPSHOT, Snapshot); + +bool name_type_can_start(NameType t); +bool name_type_can_reload(NameType t); +bool name_can_reload(Name *n); +#define name_can_start(n) name_type_can_start((n)->meta.type) + NameType name_type_from_string(const char *n); bool name_is_valid(const char *n); Name *name_new(Manager *m); void name_free(Name *name); int name_link(Name *name); +int name_link_names(Name *name, bool replace); int name_merge(Name *name, Name *other); -int name_augment(Name *n); +int name_sanitize(Name *n); +int name_load_fragment_and_dropin(Name *n); +int name_load(Name *name); const char* name_id(Name *n); +const char *name_description(Name *n); + +int name_add_name(Name *n, const char *text); + +NameActiveState name_active_state(Name *name); + +void name_dump(Name *n, FILE *f, const char *prefix); + +int name_start(Name *n); +int name_stop(Name *n); +int name_reload(Name *n); + +void name_notify(Name *n, NameActiveState os, NameActiveState ns); + +int name_watch_fd(Name *n, int fd, uint32_t events); +void name_unwatch_fd(Name *n, int fd); + +int name_watch_pid(Name *n, pid_t pid); +void name_unwatch_pid(Name *n, pid_t pid); + +int name_watch_timer(Name *n, usec_t delay, int *id); +void name_unwatch_timer(Name *n, int *id); + +char *name_change_suffix(const char *t, const char *suffix); + +bool name_job_is_applicable(Name *n, JobType j); -void name_dump(Name *n, FILE *f); +int name_add_dependency(Name *n, NameDependency d, Name *other); #endif