569 lines
15 KiB
Diff
569 lines
15 KiB
Diff
autofs-5.1.8 - switch to application wide command pipe
|
|
|
|
From: Ian Kent <raven@themaw.net>
|
|
|
|
Switch to use the functions previously added to allow a single
|
|
application wide command pipe to be used.
|
|
|
|
Signed-off-by: Ian Kent <raven@themaw.net>
|
|
---
|
|
CHANGELOG | 1
|
|
daemon/automount.c | 426 +++++++++-------------------------------------------
|
|
daemon/master.c | 2
|
|
include/automount.h | 1
|
|
modules/parse_sun.c | 1
|
|
5 files changed, 80 insertions(+), 351 deletions(-)
|
|
|
|
--- autofs-5.1.4.orig/CHANGELOG
|
|
+++ autofs-5.1.4/CHANGELOG
|
|
@@ -120,6 +120,7 @@
|
|
- add function master_find_mapent_by_devid().
|
|
- use device id to locate autofs_point when setting log priotity.
|
|
- add command pipe handling functions.
|
|
+- switch to application wide command pipe.
|
|
|
|
xx/xx/2018 autofs-5.1.5
|
|
- fix flag file permission.
|
|
--- autofs-5.1.4.orig/daemon/automount.c
|
|
+++ autofs-5.1.4/daemon/automount.c
|
|
@@ -69,10 +69,6 @@ const char *cmd_pipe_name = AUTOFS_FIFO_
|
|
int start_cmd_pipe_handler(void);
|
|
void finish_cmd_pipe_handler(void);
|
|
|
|
-/* autofs fifo name prefix */
|
|
-#define FIFO_NAME_PREFIX "autofs.fifo"
|
|
-const char *fifodir = AUTOFS_FIFO_DIR "/" FIFO_NAME_PREFIX;
|
|
-
|
|
const char *global_options; /* Global option, from command line */
|
|
|
|
static char *pid_file = NULL; /* File in which to keep pid */
|
|
@@ -801,319 +797,6 @@ static int fullread(int fd, void *ptr, s
|
|
return len;
|
|
}
|
|
|
|
-static char *automount_path_to_fifo(unsigned logopt, const char *path)
|
|
-{
|
|
- char *fifo_name, *p;
|
|
- int name_len = strlen(path) + strlen(fifodir) + 1;
|
|
- int ret;
|
|
-
|
|
- fifo_name = malloc(name_len);
|
|
- if (!fifo_name)
|
|
- return NULL;
|
|
- ret = snprintf(fifo_name, name_len, "%s%s", fifodir, path);
|
|
- if (ret >= name_len) {
|
|
- info(logopt,
|
|
- "fifo path for \"%s\" truncated to \"%s\". This may "
|
|
- "lead to --set-log-priority commands being sent to the "
|
|
- "wrong automount daemon.", path, fifo_name);
|
|
- }
|
|
-
|
|
- /*
|
|
- * An automount path can be made up of subdirectories. So, to
|
|
- * create the fifo name, we will just replace instances of '/' with
|
|
- * '-'.
|
|
- */
|
|
- p = fifo_name + strlen(fifodir);
|
|
- while (*p != '\0') {
|
|
- if (*p == '/')
|
|
- *p = '-';
|
|
- p++;
|
|
- }
|
|
-
|
|
- debug(logopt, "fifo name %s",fifo_name);
|
|
-
|
|
- return fifo_name;
|
|
-}
|
|
-
|
|
-static int create_logpri_fifo(struct autofs_point *ap)
|
|
-{
|
|
- int ret = -1;
|
|
- int fd;
|
|
- char *fifo_name;
|
|
- char buf[MAX_ERR_BUF];
|
|
-
|
|
- fifo_name = automount_path_to_fifo(ap->logopt, ap->path);
|
|
- if (!fifo_name) {
|
|
- crit(ap->logopt, "Failed to allocate memory!");
|
|
- goto out_free; /* free(NULL) is okay */
|
|
- }
|
|
-
|
|
- ret = unlink(fifo_name);
|
|
- if (ret != 0 && errno != ENOENT) {
|
|
- crit(ap->logopt,
|
|
- "Failed to unlink FIFO. Is the automount daemon "
|
|
- "already running?");
|
|
- goto out_free;
|
|
- }
|
|
-
|
|
- ret = mkfifo(fifo_name, S_IRUSR|S_IWUSR);
|
|
- if (ret != 0) {
|
|
- char *estr = strerror_r(errno, buf, MAX_ERR_BUF);
|
|
- crit(ap->logopt,
|
|
- "mkfifo for %s failed: %s", fifo_name, estr);
|
|
- goto out_free;
|
|
- }
|
|
-
|
|
- fd = open_fd(fifo_name, O_RDWR|O_NONBLOCK);
|
|
- if (fd < 0) {
|
|
- unlink(fifo_name);
|
|
- ret = -1;
|
|
- goto out_free;
|
|
- }
|
|
-
|
|
- ap->logpri_fifo = fd;
|
|
-
|
|
-out_free:
|
|
- free(fifo_name);
|
|
- return ret;
|
|
-}
|
|
-
|
|
-int destroy_logpri_fifo(struct autofs_point *ap)
|
|
-{
|
|
- int ret = -1;
|
|
- int fd = ap->logpri_fifo;
|
|
- char *fifo_name;
|
|
- char buf[MAX_ERR_BUF];
|
|
-
|
|
- if (fd == -1)
|
|
- return 0;
|
|
-
|
|
- fifo_name = automount_path_to_fifo(ap->logopt, ap->path);
|
|
- if (!fifo_name) {
|
|
- crit(ap->logopt, "Failed to allocate memory!");
|
|
- goto out_free; /* free(NULL) is okay */
|
|
- }
|
|
-
|
|
- ap->logpri_fifo = -1;
|
|
-
|
|
- ret = close(fd);
|
|
- if (ret != 0) {
|
|
- char *estr = strerror_r(errno, buf, MAX_ERR_BUF);
|
|
- warn(ap->logopt,
|
|
- "close for fifo %s: %s", fifo_name, estr);
|
|
- }
|
|
-
|
|
- ret = unlink(fifo_name);
|
|
- if (ret != 0) {
|
|
- warn(ap->logopt,
|
|
- "Failed to unlink FIFO. Was the fifo created OK?");
|
|
- }
|
|
-
|
|
-out_free:
|
|
- free(fifo_name);
|
|
- return ret;
|
|
-}
|
|
-
|
|
-static void cleanup_stale_logpri_fifo_pipes(void)
|
|
-{
|
|
- size_t prefix_len = strlen(FIFO_NAME_PREFIX);
|
|
- char *dir = AUTOFS_FIFO_DIR;
|
|
- size_t dir_len = strlen(dir);
|
|
- struct dirent *dent;
|
|
- DIR *dfd;
|
|
- int ret;
|
|
-
|
|
- dfd = opendir(dir);
|
|
- if (!dfd) {
|
|
- warn(LOGOPT_ANY, "failed to open fifo dir %s", dir);
|
|
- return;
|
|
- }
|
|
-
|
|
- while ((dent = readdir(dfd))) {
|
|
- char fifo_path[PATH_MAX];
|
|
-
|
|
- if (!(dent->d_type & DT_FIFO))
|
|
- continue;
|
|
- if (strncmp(FIFO_NAME_PREFIX, dent->d_name, prefix_len))
|
|
- continue;
|
|
- if ((dir_len + 1 + strlen(dent->d_name)) >= PATH_MAX) {
|
|
- warn(LOGOPT_ANY, "fifo path too long for buffer");
|
|
- continue;
|
|
- }
|
|
-
|
|
- strcpy(fifo_path, dir);
|
|
- strcat(fifo_path, "/");
|
|
- strcat(fifo_path, dent->d_name);
|
|
-
|
|
- ret = unlink(fifo_path);
|
|
- if (ret == -1) {
|
|
- char buf[MAX_ERR_BUF];
|
|
- char *estr = strerror_r(errno, buf, MAX_ERR_BUF);
|
|
- warn(LOGOPT_ANY, "unlink of fifo failed: %s", estr);
|
|
- }
|
|
- }
|
|
-
|
|
- closedir(dfd);
|
|
-}
|
|
-
|
|
-static void handle_fifo_message(int fd)
|
|
-{
|
|
- struct autofs_point *ap;
|
|
- int ret;
|
|
- char buffer[PIPE_BUF];
|
|
- char *end, *sep;
|
|
- long pri;
|
|
- char buf[MAX_ERR_BUF];
|
|
- dev_t devid;
|
|
-
|
|
- memset(buffer, 0, sizeof(buffer));
|
|
- ret = read(fd, &buffer, sizeof(buffer));
|
|
- if (ret < 0) {
|
|
- char *estr = strerror_r(errno, buf, MAX_ERR_BUF);
|
|
- warn(LOGOPT_ANY, "read on fifo returned error: %s", estr);
|
|
- return;
|
|
- }
|
|
-
|
|
- sep = strrchr(buffer, ' ');
|
|
- if (!sep) {
|
|
- error(LOGOPT_ANY, "Incorrect cmd message format %s.", buffer);
|
|
- return;
|
|
- }
|
|
- sep++;
|
|
-
|
|
- errno = 0;
|
|
- devid = strtol(buffer, &end, 10);
|
|
- if ((devid == LONG_MIN || devid == LONG_MAX) && errno == ERANGE) {
|
|
- debug(LOGOPT_ANY, "strtol reported a range error.");
|
|
- error(LOGOPT_ANY, "Invalid cmd message format %s.", buffer);
|
|
- return;
|
|
- }
|
|
- if ((devid == 0 && errno == EINVAL) || end == buffer) {
|
|
- debug(LOGOPT_ANY, "devid id is expected to be a integer.");
|
|
- return;
|
|
- }
|
|
-
|
|
- ap = master_find_mapent_by_devid(master_list, devid);
|
|
- if (!ap) {
|
|
- error(LOGOPT_ANY, "Can't locate autofs_point for device id %ld.", devid);
|
|
- return;
|
|
- }
|
|
-
|
|
- errno = 0;
|
|
- pri = strtol(sep, &end, 10);
|
|
- if ((pri == LONG_MIN || pri == LONG_MAX) && errno == ERANGE) {
|
|
- debug(ap->logopt, "strtol reported an %s. Failed to set "
|
|
- "log priority.", pri == LONG_MIN ? "underflow" : "overflow");
|
|
- return;
|
|
- }
|
|
- if ((pri == 0 && errno == EINVAL) || end == sep) {
|
|
- debug(ap->logopt, "priority is expected to be an integer "
|
|
- "in the range 0-7 inclusive.");
|
|
- return;
|
|
- }
|
|
-
|
|
- if (pri > LOG_DEBUG || pri < LOG_EMERG) {
|
|
- debug(ap->logopt, "invalid log priority (%ld) received "
|
|
- "on fifo", pri);
|
|
- return;
|
|
- }
|
|
-
|
|
- /*
|
|
- * OK, the message passed all of the sanity checks. The
|
|
- * automounter actually only supports three log priorities.
|
|
- * Everything is logged at log level debug, deamon messages
|
|
- * and everything except debug messages are logged with the
|
|
- * verbose setting and only error and critical messages are
|
|
- * logged when debugging isn't enabled.
|
|
- */
|
|
- if (pri >= LOG_WARNING) {
|
|
- if (pri == LOG_DEBUG) {
|
|
- set_log_debug_ap(ap);
|
|
- info(ap->logopt, "Debug logging set for %s", ap->path);
|
|
- } else {
|
|
- set_log_verbose_ap(ap);
|
|
- info(ap->logopt, "Verbose logging set for %s", ap->path);
|
|
- }
|
|
- } else {
|
|
- if (ap->logopt & LOGOPT_ANY)
|
|
- info(ap->logopt, "Basic logging set for %s", ap->path);
|
|
- set_log_norm_ap(ap);
|
|
- }
|
|
-}
|
|
-
|
|
-static int set_log_priority(const char *path, int priority)
|
|
-{
|
|
- struct ioctl_ops *ops = get_ioctl_ops();
|
|
- int fd;
|
|
- char *fifo_name;
|
|
- char buf[FIFO_BUF_SIZE];
|
|
- int ret;
|
|
- dev_t devid;
|
|
-
|
|
- if (!ops) {
|
|
- fprintf(stderr, "Could not get ioctl ops\n");
|
|
- return -1;
|
|
- } else {
|
|
- ret = ops->mount_device(LOGOPT_ANY, path, 0, &devid);
|
|
- if (ret == -1 || ret == 0) {
|
|
- fprintf(stderr,
|
|
- "Could not find device id for mount %s\n", path);
|
|
- return -1;
|
|
- }
|
|
- }
|
|
-
|
|
- if (priority > LOG_DEBUG || priority < LOG_EMERG) {
|
|
- fprintf(stderr, "Log priority %d is invalid.\n", priority);
|
|
- fprintf(stderr, "Please specify a number in the range 0-7.\n");
|
|
- return -1;
|
|
- }
|
|
-
|
|
- /*
|
|
- * This is an ascii based protocol, so we want the string
|
|
- * representation of the integer log priority.
|
|
- */
|
|
- ret = snprintf(buf, sizeof(buf), "%ld %d", devid, priority);
|
|
- if (ret >= FIFO_BUF_SIZE) {
|
|
- fprintf(stderr, "Invalid device id or log priotity\n");
|
|
- return -1;
|
|
- }
|
|
-
|
|
- fifo_name = automount_path_to_fifo(LOGOPT_NONE, path);
|
|
- if (!fifo_name) {
|
|
- fprintf(stderr, "%s: Failed to allocate memory!\n",
|
|
- __FUNCTION__);
|
|
- return -1;
|
|
- }
|
|
-
|
|
- /*
|
|
- * Specify O_NONBLOCK so that the open will fail if there is no
|
|
- * daemon reading from the other side of the FIFO.
|
|
- */
|
|
- fd = open_fd(fifo_name, O_WRONLY|O_NONBLOCK);
|
|
- if (fd < 0) {
|
|
- fprintf(stderr, "%s: open of %s failed with %s\n",
|
|
- __FUNCTION__, fifo_name, strerror(errno));
|
|
- fprintf(stderr, "%s: perhaps the fifo wasn't setup,"
|
|
- " please check your log for more information\n", __FUNCTION__);
|
|
- free(fifo_name);
|
|
- return -1;
|
|
- }
|
|
-
|
|
- if (write(fd, buf, sizeof(buf)) != sizeof(buf)) {
|
|
- fprintf(stderr, "Failed to change logging priority. ");
|
|
- fprintf(stderr, "write to fifo failed: %s.\n",
|
|
- strerror(errno));
|
|
- close(fd);
|
|
- free(fifo_name);
|
|
- return -1;
|
|
- }
|
|
- close(fd);
|
|
- free(fifo_name);
|
|
- fprintf(stdout, "Successfully set log priority for %s.\n", path);
|
|
-
|
|
- return 0;
|
|
-}
|
|
-
|
|
static void dummy(int sig)
|
|
{
|
|
}
|
|
@@ -1122,18 +805,14 @@ static int get_pkt(struct autofs_point *
|
|
{
|
|
struct sigaction sa;
|
|
sigset_t signalset;
|
|
- struct pollfd fds[2];
|
|
- int pollfds = 2;
|
|
+ struct pollfd fds[1];
|
|
+ int pollfds = 1;
|
|
char buf[MAX_ERR_BUF];
|
|
size_t read;
|
|
char *estr;
|
|
|
|
fds[0].fd = ap->pipefd;
|
|
fds[0].events = POLLIN;
|
|
- fds[1].fd = ap->logpri_fifo;
|
|
- fds[1].events = POLLIN;
|
|
- if (fds[1].fd == -1)
|
|
- pollfds--;
|
|
|
|
sa.sa_handler = dummy;
|
|
sigemptyset(&sa.sa_mask);
|
|
@@ -1172,11 +851,6 @@ static int get_pkt(struct autofs_point *
|
|
}
|
|
return read;
|
|
}
|
|
-
|
|
- if (fds[1].fd != -1 && fds[1].revents & POLLIN) {
|
|
- debug(ap->logopt, "message pending on control fifo.");
|
|
- handle_fifo_message(fds[1].fd);
|
|
- }
|
|
}
|
|
}
|
|
|
|
@@ -1235,11 +909,6 @@ static int autofs_init_ap(struct autofs_
|
|
ap->pipefd = pipefd[0];
|
|
ap->kpipefd = pipefd[1];
|
|
|
|
- if (create_logpri_fifo(ap) < 0) {
|
|
- logmsg("could not create FIFO for path %s\n", ap->path);
|
|
- logmsg("dynamic log level changes not available for %s", ap->path);
|
|
- }
|
|
-
|
|
return 0;
|
|
}
|
|
|
|
@@ -1260,11 +929,6 @@ static int mount_autofs(struct autofs_po
|
|
else
|
|
status = mount_autofs_indirect(ap, root);
|
|
|
|
- if (status < 0) {
|
|
- destroy_logpri_fifo(ap);
|
|
- return -1;
|
|
- }
|
|
-
|
|
st_add_task(ap, ST_READY);
|
|
|
|
return status;
|
|
@@ -1831,6 +1495,68 @@ static void handle_cmd_pipe_fifo_message
|
|
}
|
|
}
|
|
|
|
+static int set_log_priority(const char *path, int priority)
|
|
+{
|
|
+ struct ioctl_ops *ops = get_ioctl_ops();
|
|
+ char buf[FIFO_BUF_SIZE];
|
|
+ dev_t devid;
|
|
+ int fd;
|
|
+ int ret;
|
|
+
|
|
+ if (!ops) {
|
|
+ fprintf(stderr, "Could not get ioctl ops\n");
|
|
+ return -1;
|
|
+ } else {
|
|
+ ret = ops->mount_device(LOGOPT_ANY, path, 0, &devid);
|
|
+ if (ret == -1 || ret == 0) {
|
|
+ fprintf(stderr,
|
|
+ "Could not find device id for mount %s\n", path);
|
|
+ return -1;
|
|
+ }
|
|
+ }
|
|
+
|
|
+ if (priority > LOG_DEBUG || priority < LOG_EMERG) {
|
|
+ fprintf(stderr, "Log priority %d is invalid.\n", priority);
|
|
+ fprintf(stderr, "Please specify a number in the range 0-7.\n");
|
|
+ return -1;
|
|
+ }
|
|
+
|
|
+ /*
|
|
+ * This is an ascii based protocol, so we want the string
|
|
+ * representation of the integer log priority.
|
|
+ */
|
|
+ ret = snprintf(buf, sizeof(buf), "%ld %d", devid, priority);
|
|
+ if (ret >= FIFO_BUF_SIZE) {
|
|
+ fprintf(stderr, "Invalid device id or log priotity\n");
|
|
+ return -1;
|
|
+ }
|
|
+
|
|
+ /*
|
|
+ * Specify O_NONBLOCK so that the open will fail if there is no
|
|
+ * daemon reading from the other side of the FIFO.
|
|
+ */
|
|
+ fd = open_fd(cmd_pipe_name, O_WRONLY|O_NONBLOCK);
|
|
+ if (fd < 0) {
|
|
+ fprintf(stderr, "%s: open of %s failed with %s\n",
|
|
+ __FUNCTION__, cmd_pipe_name, strerror(errno));
|
|
+ fprintf(stderr, "%s: perhaps the fifo wasn't setup,"
|
|
+ " please check your log for more information\n", __FUNCTION__);
|
|
+ return -1;
|
|
+ }
|
|
+
|
|
+ if (write(fd, buf, sizeof(buf)) != sizeof(buf)) {
|
|
+ fprintf(stderr, "Failed to change logging priority. ");
|
|
+ fprintf(stderr, "write to fifo failed: %s.\n",
|
|
+ strerror(errno));
|
|
+ close(fd);
|
|
+ return -1;
|
|
+ }
|
|
+ close(fd);
|
|
+ fprintf(stdout, "Successfully set log priority for %s.\n", path);
|
|
+
|
|
+ return 0;
|
|
+}
|
|
+
|
|
static void cmd_pipe_dummy(int sig)
|
|
{
|
|
}
|
|
@@ -2031,8 +1757,6 @@ static void handle_mounts_cleanup(void *
|
|
master_remove_mapent(ap->entry);
|
|
master_source_unlock(ap->entry);
|
|
|
|
- destroy_logpri_fifo(ap);
|
|
-
|
|
/*
|
|
* Submounts are detached threads and don't belong to the
|
|
* master map entry list so we need to free their resources
|
|
@@ -2970,6 +2694,18 @@ int main(int argc, char *argv[])
|
|
|
|
init_ioctl_ctl();
|
|
|
|
+ if (!start_cmd_pipe_handler()) {
|
|
+ logerr("%s: failed to create command pipe handler thread!", program);
|
|
+ master_kill(master_list);
|
|
+ if (start_pipefd[1] != -1) {
|
|
+ res = write(start_pipefd[1], pst_stat, sizeof(*pst_stat));
|
|
+ close(start_pipefd[1]);
|
|
+ }
|
|
+ release_flag_file();
|
|
+ macro_free_global_table();
|
|
+ exit(1);
|
|
+ }
|
|
+
|
|
if (!alarm_start_handler()) {
|
|
logerr("%s: failed to create alarm handler thread!", program);
|
|
master_kill(master_list);
|
|
@@ -3035,13 +2771,7 @@ int main(int argc, char *argv[])
|
|
}
|
|
}
|
|
|
|
- /* If the option to unlink all autofs mounts and exit has
|
|
- * been given remove logpri fifo files as all the mounts
|
|
- * will be detached leaving them stale.
|
|
- */
|
|
- if (do_force_unlink & UNLINK_AND_EXIT)
|
|
- cleanup_stale_logpri_fifo_pipes();
|
|
- else {
|
|
+ if (!(do_force_unlink & UNLINK_AND_EXIT)) {
|
|
/*
|
|
* Mmm ... reset force unlink umount so we don't also do
|
|
* this in future when we receive a HUP signal.
|
|
@@ -3065,6 +2795,8 @@ int main(int argc, char *argv[])
|
|
|
|
master_kill(master_list);
|
|
|
|
+ finish_cmd_pipe_handler();
|
|
+
|
|
if (pid_file) {
|
|
unlink(pid_file);
|
|
pid_file = NULL;
|
|
--- autofs-5.1.4.orig/daemon/master.c
|
|
+++ autofs-5.1.4/daemon/master.c
|
|
@@ -112,8 +112,6 @@ int master_add_autofs_point(struct maste
|
|
|
|
ap->state = ST_INIT;
|
|
|
|
- ap->logpri_fifo = -1;
|
|
-
|
|
ap->path = strdup(entry->path);
|
|
if (!ap->path) {
|
|
free(ap);
|
|
--- autofs-5.1.4.orig/include/automount.h
|
|
+++ autofs-5.1.4/include/automount.h
|
|
@@ -551,7 +551,6 @@ struct autofs_point {
|
|
int pipefd; /* File descriptor for pipe */
|
|
int kpipefd; /* Kernel end descriptor for pipe */
|
|
int ioctlfd; /* File descriptor for ioctls */
|
|
- int logpri_fifo; /* FIFO used for changing log levels */
|
|
dev_t dev; /* "Device" number assigned by kernel */
|
|
struct master_mapent *entry; /* Master map entry for this mount */
|
|
unsigned int type; /* Type of map direct or indirect */
|
|
--- autofs-5.1.4.orig/modules/parse_sun.c
|
|
+++ autofs-5.1.4/modules/parse_sun.c
|
|
@@ -82,7 +82,6 @@ static struct parse_context default_cont
|
|
1 /* Do slashify_colons */
|
|
};
|
|
|
|
-int destroy_logpri_fifo(struct autofs_point *ap);
|
|
static char *concat_options(char *left, char *right);
|
|
|
|
/* Free all storage associated with this context */
|