#include "dbus-unit.h"
#include "fd-util.h"
#include "format-util.h"
+#include "fstab-util.h"
#include "io-util.h"
#include "label.h"
-#include "mkdir.h"
+#include "mkdir-label.h"
#include "mount-util.h"
#include "mount.h"
#include "mountpoint-util.h"
static void automount_init(Unit *u) {
Automount *a = AUTOMOUNT(u);
+ assert(a);
assert(u);
assert(u->load_state == UNIT_STUB);
unmount_autofs(a);
a->where = mfree(a->where);
+ a->extra_options = mfree(a->extra_options);
a->tokens = set_free(a->tokens);
a->expire_tokens = set_free(a->expire_tokens);
}
static int automount_verify(Automount *a) {
+ static const char *const reserved_options[] = {
+ "fd\0",
+ "pgrp\0",
+ "minproto\0",
+ "maxproto\0",
+ "direct\0",
+ "indirect\0",
+ };
+
_cleanup_free_ char *e = NULL;
int r;
if (!unit_has_name(UNIT(a), e))
return log_unit_error_errno(UNIT(a), SYNTHETIC_ERRNO(ENOEXEC), "Where= setting doesn't match unit name. Refusing.");
+ for (size_t i = 0; i < ELEMENTSOF(reserved_options); i++)
+ if (fstab_test_option(a->extra_options, reserved_options[i]))
+ return log_unit_error_errno(
+ UNIT(a),
+ SYNTHETIC_ERRNO(ENOEXEC),
+ "ExtraOptions= setting may not contain reserved option %s.",
+ reserved_options[i]);
+
return 0;
}
"%sAutomount State: %s\n"
"%sResult: %s\n"
"%sWhere: %s\n"
+ "%sExtraOptions: %s\n"
"%sDirectoryMode: %04o\n"
"%sTimeoutIdleUSec: %s\n",
prefix, automount_state_to_string(a->state),
prefix, automount_result_to_string(a->result),
prefix, a->where,
+ prefix, a->extra_options,
prefix, a->directory_mode,
prefix, FORMAT_TIMESPAN(a->timeout_idle_usec, USEC_PER_SEC));
}
assert(where);
l = sizeof(struct autofs_dev_ioctl) + strlen(where) + 1;
- param = alloca(l);
+ param = alloca_safe(l);
init_autofs_dev_ioctl(param);
param->size = l;
/* Convert to seconds, rounding up. */
param.timeout.timeout = DIV_ROUND_UP(usec, USEC_PER_SEC);
- if (ioctl(dev_autofs_fd, AUTOFS_DEV_IOCTL_TIMEOUT, ¶m) < 0)
- return -errno;
-
- return 0;
+ return RET_NERRNO(ioctl(dev_autofs_fd, AUTOFS_DEV_IOCTL_TIMEOUT, ¶m));
}
static int autofs_send_ready(int dev_autofs_fd, int ioctl_fd, uint32_t token, int status) {
} else
param.ready.token = token;
- if (ioctl(dev_autofs_fd, status ? AUTOFS_DEV_IOCTL_FAIL : AUTOFS_DEV_IOCTL_READY, ¶m) < 0)
- return -errno;
-
- return 0;
+ return RET_NERRNO(ioctl(dev_autofs_fd, status ? AUTOFS_DEV_IOCTL_FAIL : AUTOFS_DEV_IOCTL_READY, ¶m));
}
static int automount_send_ready(Automount *a, Set *tokens, int status) {
_cleanup_close_ int ioctl_fd = -1;
int p[2] = { -1, -1 };
char name[STRLEN("systemd-") + DECIMAL_STR_MAX(pid_t) + 1];
- char options[STRLEN("fd=,pgrp=,minproto=5,maxproto=5,direct")
- + DECIMAL_STR_MAX(int) + DECIMAL_STR_MAX(gid_t) + 1];
+ _cleanup_free_ char *options = NULL;
bool mounted = false;
int r, dev_autofs_fd;
struct stat st;
if (r < 0)
goto fail;
- xsprintf(options, "fd=%i,pgrp="PID_FMT",minproto=5,maxproto=5,direct", p[1], getpgrp());
+ if (asprintf(
+ &options,
+ "fd=%i,pgrp="PID_FMT",minproto=5,maxproto=5,direct%s%s",
+ p[1],
+ getpgrp(),
+ isempty(a->extra_options) ? "" : ",",
+ strempty(a->extra_options)) < 0) {
+ r = -ENOMEM;
+ goto fail;
+ }
+
xsprintf(name, "systemd-"PID_FMT, getpid_cached());
r = mount_nofollow(name, a->where, "autofs", 0, options);
if (r < 0)
return supported;
}
-static int automount_test_start_limit(Unit *u) {
+static int automount_can_start(Unit *u) {
Automount *a = AUTOMOUNT(u);
int r;
return r;
}
- return 0;
+ return 1;
}
static const char* const automount_result_table[_AUTOMOUNT_RESULT_MAX] = {
},
},
- .test_start_limit = automount_test_start_limit,
+ .can_start = automount_can_start,
};