state = unit_active_state(u);
if (UNIT_IS_ACTIVE_OR_RELOADING(state))
return -EALREADY;
+ if (state == UNIT_MAINTENANCE)
+ return -EAGAIN;
/* Units that aren't loaded cannot be started */
if (u->load_state != UNIT_LOADED)
return 0;
}
+int unit_clean(Unit *u, ExecCleanMask mask) {
+ UnitActiveState state;
+
+ assert(u);
+
+ /* Special return values:
+ *
+ * -EOPNOTSUPP → cleaning not supported for this unit type
+ * -EUNATCH → cleaning not defined for this resource type
+ * -EBUSY → unit currently can't be cleaned since it's running or not properly loaded, or has
+ * a job queued or similar
+ */
+
+ if (!UNIT_VTABLE(u)->clean)
+ return -EOPNOTSUPP;
+
+ if (mask == 0)
+ return -EUNATCH;
+
+ if (u->load_state != UNIT_LOADED)
+ return -EBUSY;
+
+ if (u->job)
+ return -EBUSY;
+
+ state = unit_active_state(u);
+ if (!IN_SET(state, UNIT_INACTIVE))
+ return -EBUSY;
+
+ return UNIT_VTABLE(u)->clean(u, mask);
+}
+
+int unit_can_clean(Unit *u, ExecCleanMask *ret) {
+ assert(u);
+
+ if (!UNIT_VTABLE(u)->clean ||
+ u->load_state != UNIT_LOADED) {
+ *ret = 0;
+ return 0;
+ }
+
+ /* When the clean() method is set, can_clean() really should be set too */
+ assert(UNIT_VTABLE(u)->can_clean);
+
+ return UNIT_VTABLE(u)->can_clean(u, ret);
+}
+
static const char* const collect_mode_table[_COLLECT_MODE_MAX] = {
[COLLECT_INACTIVE] = "inactive",
[COLLECT_INACTIVE_OR_FAILED] = "inactive-or-failed",