- fix expire calling kernel more often than needed.

- fix unlink of mount tree incorrectly causing autofs mount fail.
- add miscellaneous device node interface library.
- use miscellaneous device node, if available, for active restart.
- device node and active restart fixes.
- update is_mounted to use device node ioctl, if available.
This commit is contained in:
Ian Kent 2008-02-25 00:40:55 +00:00
parent eb1a40f905
commit e6cf324f87
7 changed files with 5006 additions and 1 deletions

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,134 @@
diff --git a/include/dev-ioctl-lib.h b/include/dev-ioctl-lib.h
index 5851c4c..007d7a6 100644
--- a/include/dev-ioctl-lib.h
+++ b/include/dev-ioctl-lib.h
@@ -26,7 +26,7 @@
#define CONTROL_DEVICE "/dev/autofs"
-#define DEV_IOCTL_IS_MOUNTED 0x0001
+#define DEV_IOCTL_IS_MOUNTPOINT 0x0001
#define DEV_IOCTL_IS_AUTOFS 0x0002
#define DEV_IOCTL_IS_OTHER 0x0004
diff --git a/include/mounts.h b/include/mounts.h
index ca7dee9..679a508 100644
--- a/include/mounts.h
+++ b/include/mounts.h
@@ -65,7 +65,7 @@ struct mnt_list {
unsigned int query_kproto_ver(void);
unsigned int get_kver_major(void);
unsigned int get_kver_minor(void);
-char *make_options_string(char *path, int kernel_pipefd, char *extra);
+char *make_options_string(char *path, int kernel_pipefd, const char *extra);
char *make_mnt_name_string(char *path);
struct mnt_list *get_mnt_list(const char *table, const char *path, int include);
struct mnt_list *reverse_mnt_list(struct mnt_list *list);
diff --git a/lib/dev-ioctl-lib.c b/lib/dev-ioctl-lib.c
index 8d4be77..719747f 100644
--- a/lib/dev-ioctl-lib.c
+++ b/lib/dev-ioctl-lib.c
@@ -698,11 +698,18 @@ static int ioctl_askumount(unsigned int logopt,
/*
* Check if the given path is a mountpoint.
*
- * The path is considered a mountpoint if it is itself a mountpoint
- * or contains a mount, such as a multi-mount without a root mount.
- * In addition, if the path is itself a mountpoint we return whether
- * the mounted file system is an autofs filesystem or other file
- * system.
+ * If we supply a file descriptor of an autofs mount we're
+ * looking for a specific mount. In this case the path is
+ * considered a mountpoint if it is itself a mountpoint or
+ * contains a mount, such as a multi-mount without a root
+ * mount.
+ *
+ * If we don't supply a file descriptor then we just want
+ * to know if the given path is an autofs mount point or
+ * is mounted within an autofs filesystem.
+ *
+ * In both cases we get an indication of whether the path
+ * is a mount point and the super magic of the top mount.
*/
static int dev_ioctl_ismountpoint(unsigned int logopt,
int ioctlfd, const char *path,
@@ -731,7 +738,7 @@ static int dev_ioctl_ismountpoint(unsigned int logopt,
}
if (param->arg1) {
- *mountpoint = DEV_IOCTL_IS_MOUNTED;
+ *mountpoint = DEV_IOCTL_IS_MOUNTPOINT;
if (param->arg2) {
if (param->arg2 == AUTOFS_SUPER_MAGIC)
diff --git a/lib/mounts.c b/lib/mounts.c
index 959fe99..ba49099 100644
--- a/lib/mounts.c
+++ b/lib/mounts.c
@@ -129,7 +129,7 @@ unsigned int get_kver_minor(void)
/*
* Make common autofs mount options string
*/
-char *make_options_string(char *path, int pipefd, char *extra)
+char *make_options_string(char *path, int pipefd, const char *extra)
{
char *options;
int len;
@@ -1207,8 +1207,8 @@ free_tsv:
const char *mount_type_str(const unsigned int type)
{
static const char *str_type[] = {
- "direct",
"indirect",
+ "direct",
"offset"
};
unsigned int pos, i;
@@ -1225,13 +1225,13 @@ void notify_mount_result(struct autofs_point *ap,
{
if (ap->exp_timeout)
info(ap->logopt,
- "mounted %s on %s with timeout %u, freq %u seconds",
+ "mounted %s mount on %s with timeout %u, freq %u seconds",
type, path,
(unsigned int) ap->exp_timeout,
(unsigned int) ap->exp_runfreq);
else
info(ap->logopt,
- "mounted %s on %s with timeouts disabled",
+ "mounted %s mount on %s with timeouts disabled",
type, path);
return;
diff --git a/modules/mount_nfs.c b/modules/mount_nfs.c
index 1a9bef2..d493cde 100644
--- a/modules/mount_nfs.c
+++ b/modules/mount_nfs.c
@@ -173,6 +173,13 @@ int mount_mount(struct autofs_point *ap, const char *root, const char *name, int
len = sprintf(fullpath, "%s", root);
fullpath[len] = '\0';
+ if (is_mounted(_PATH_MOUNTED, fullpath, MNTS_REAL)) {
+ info(ap->logopt, MODPREFIX
+ "%s is already mounted or is being re-mounted", fullpath);
+ free_host_list(&hosts);
+ return 0;
+ }
+
debug(ap->logopt, MODPREFIX "calling mkdir_path %s", fullpath);
status = mkdir_path(fullpath, 0555);
@@ -197,13 +204,6 @@ int mount_mount(struct autofs_point *ap, const char *root, const char *name, int
while (this) {
char *loc, *port_opt = NULL;
- if (is_mounted(_PATH_MOUNTED, fullpath, MNTS_REAL)) {
- info(ap->logopt, MODPREFIX
- "%s is already mounted or is being re-mounted", fullpath);
- free_host_list(&hosts);
- return 0;
- }
-
/*
* If the "port" option is specified, then we don't want
* a bind mount. Use the "port" option if you want to

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,74 @@
diff -up autofs-5.0.3/daemon/direct.c.expire-works-too-hard autofs-5.0.3/daemon/direct.c
--- autofs-5.0.3/daemon/direct.c.expire-works-too-hard 2008-01-14 13:39:16.000000000 +0900
+++ autofs-5.0.3/daemon/direct.c 2008-02-25 08:48:08.000000000 +0900
@@ -808,7 +808,7 @@ static int expire_direct(int ioctlfd, co
if (fstat(ioctlfd, &st) == -1) {
char *estr = strerror_r(errno, buf, MAX_ERR_BUF);
- error(logopt, "fstat failed: %s", estr);
+ debug(logopt, "fstat failed: %s", estr);
return 0;
}
@@ -824,11 +824,16 @@ static int expire_direct(int ioctlfd, co
if (errno == EBADF || errno == EINVAL)
return 1;
- /* Other than need to wait for the kernel ? */
- if (errno != EAGAIN)
- return 0;
+ /*
+ * Other than EAGAIN is an expire error so continue.
+ * Kernel try the same mount again, limited by
+ * retries (ie. number of mounts directly under
+ * mount point, should always be one for direct
+ * mounts).
+ */
+ if (errno == EAGAIN)
+ break;
}
-
nanosleep(&tm, NULL);
}
diff -up autofs-5.0.3/daemon/indirect.c.expire-works-too-hard autofs-5.0.3/daemon/indirect.c
--- autofs-5.0.3/daemon/indirect.c.expire-works-too-hard 2008-01-14 13:39:16.000000000 +0900
+++ autofs-5.0.3/daemon/indirect.c 2008-02-25 08:48:53.000000000 +0900
@@ -328,7 +328,7 @@ static int expire_indirect(struct autofs
if (fstat(ioctlfd, &st) == -1) {
char *estr = strerror_r(errno, buf, MAX_ERR_BUF);
- error(ap->logopt, "fstat failed: %s", estr);
+ debug(ap->logopt, "fstat failed: %s", estr);
return 0;
}
@@ -344,11 +344,13 @@ static int expire_indirect(struct autofs
if (errno == EBADF || errno == EINVAL)
return 1;
- /* Other than need to wait for the kernel ? */
- if (errno != EAGAIN)
- return 0;
+ /*
+ * Other than EAGAIN is an expire error so continue.
+ * Kernel will try the next mount.
+ */
+ if (errno == EAGAIN)
+ break;
}
-
nanosleep(&tm, NULL);
}
diff -up autofs-5.0.3/CHANGELOG.expire-works-too-hard autofs-5.0.3/CHANGELOG
--- autofs-5.0.3/CHANGELOG.expire-works-too-hard 2008-02-25 08:44:54.000000000 +0900
+++ autofs-5.0.3/CHANGELOG 2008-02-25 08:48:08.000000000 +0900
@@ -6,6 +6,7 @@
- avoid using UDP for probing NFSv4 mount requests.
- use libldap instead of libldap_r (Guillaume Rousse).
- another fix for don't fail on empty master map.
+- fix expire working harder than needed.
14/01/2008 autofs-5.0.3
-----------------------

View File

@ -0,0 +1,49 @@
diff --git a/lib/mounts.c b/lib/mounts.c
index ba49099..e3e8066 100644
--- a/lib/mounts.c
+++ b/lib/mounts.c
@@ -391,7 +391,7 @@ int contained_in_local_fs(const char *path)
return ret;
}
-int is_mounted(const char *table, const char *path, unsigned int type)
+static int table_is_mounted(const char *table, const char *path, unsigned int type)
{
struct mntent *mnt;
struct mntent mnt_wrk;
@@ -437,6 +437,35 @@ int is_mounted(const char *table, const char *path, unsigned int type)
return ret;
}
+static int ioctl_is_mounted(const char *path, unsigned int type)
+{
+ struct ioctl_ops *ops = get_ioctl_ops();
+ unsigned int mounted;
+
+ ops->ismountpoint(LOGOPT_NONE, -1, path, &mounted);
+ if (mounted) {
+ switch (type) {
+ case MNTS_ALL:
+ return 1;
+ case MNTS_AUTOFS:
+ return (mounted & DEV_IOCTL_IS_AUTOFS);
+ case MNTS_REAL:
+ return (mounted & DEV_IOCTL_IS_OTHER);
+ }
+ }
+ return 0;
+}
+
+int is_mounted(const char *table, const char *path, unsigned int type)
+{
+ struct ioctl_ops *ops = get_ioctl_ops();
+
+ if (ops->version)
+ return ioctl_is_mounted(path, type);
+ else
+ return table_is_mounted(table, path, type);
+}
+
int has_fstab_option(const char *opt)
{
struct mntent *mnt;

View File

@ -0,0 +1,52 @@
diff --git a/CHANGELOG b/CHANGELOG
index eb4cce1..a0c7fa3 100644
--- a/CHANGELOG
+++ b/CHANGELOG
@@ -7,6 +7,7 @@
- use libldap instead of libldap_r (Guillaume Rousse).
- another fix for don't fail on empty master map.
- fix expire working harder than needed.
+- fix unlink of mount tree incorrectly causing autofs mount fail.
14/01/2008 autofs-5.0.3
-----------------------
diff --git a/daemon/direct.c b/daemon/direct.c
index 760fbd4..8d1e9c6 100644
--- a/daemon/direct.c
+++ b/daemon/direct.c
@@ -275,7 +275,6 @@ static int unlink_mount_tree(struct autofs_point *ap, struct list_head *list)
else
rv = umount2(mnt->path, MNT_DETACH);
if (rv == -1) {
- ret = 0;
debug(ap->logopt,
"can't unlink %s from mount tree", mnt->path);
@@ -287,6 +286,7 @@ static int unlink_mount_tree(struct autofs_point *ap, struct list_head *list)
case ENOENT:
case EFAULT:
+ ret = 0;
warn(ap->logopt, "bad path for mount");
break;
}
diff --git a/daemon/indirect.c b/daemon/indirect.c
index 39b42da..f0409ac 100644
--- a/daemon/indirect.c
+++ b/daemon/indirect.c
@@ -65,7 +65,6 @@ static int unlink_mount_tree(struct autofs_point *ap, struct mnt_list *mnts)
else
rv = umount2(this->path, MNT_DETACH);
if (rv == -1) {
- ret = 0;
debug(ap->logopt,
"can't unlink %s from mount tree", this->path);
@@ -77,6 +76,7 @@ static int unlink_mount_tree(struct autofs_point *ap, struct mnt_list *mnts)
case ENOENT:
case EFAULT:
+ ret = 0;
warn(ap->logopt, "bad path for mount");
break;
}

View File

@ -4,7 +4,7 @@
Summary: A tool for automatically mounting and unmounting filesystems
Name: autofs
Version: 5.0.3
Release: 5
Release: 6
Epoch: 1
License: GPL
Group: System Environment/Daemons
@ -16,6 +16,12 @@ Patch3: autofs-5.0.3-basedn-with-spaces-fix-3.patch
Patch4: autofs-5.0.3-nfs4-tcp-only.patch
Patch5: autofs-5.0.3-correct-ldap-lib.patch
Patch6: autofs-5.0.3-dont-fail-on-empty-master-fix-2.patch
Patch7: autofs-5.0.3-expire-works-too-hard.patch
Patch8: autofs-5.0.3-unlink-mount-return-fix.patch
Patch9: autofs-5.0.3-device-node-control.patch
Patch10: autofs-5.0.3-active-restart.patch
Patch11: autofs-5.0.3-device-node-and-active-restart-fixes.patch
Patch12: autofs-5.0.3-make-is_mounted-use-dev-ioctl.patch
Buildroot: %{_tmppath}/%{name}-%{version}-%{release}-root-%(%{__id_u} -n)
BuildRequires: autoconf, hesiod-devel, openldap-devel, bison, flex, libxml2-devel, cyrus-sasl-devel, openssl-devel module-init-tools util-linux nfs-utils e2fsprogs
Conflicts: kernel < 2.6.17
@ -63,6 +69,12 @@ echo %{version}-%{release} > .version
%patch4 -p1
%patch5 -p1
%patch6 -p1
%patch7 -p1
%patch8 -p1
%patch9 -p1
%patch10 -p1
%patch11 -p1
%patch12 -p1
%build
#CFLAGS="$RPM_OPT_FLAGS" ./configure --prefix=/usr --libdir=%{_libdir}
@ -115,6 +127,14 @@ fi
%{_libdir}/autofs/
%changelog
* Mon Feb 25 2008 Ian Kent <ikent@redhat.com> - 5.0.3-6
- fix expire calling kernel more often than needed.
- fix unlink of mount tree incorrectly causing autofs mount fail.
- add miscellaneous device node interface library.
- use miscellaneous device node, if available, for active restart.
- device node and active restart fixes.
- update is_mounted to use device node ioctl, if available.
* Fri Feb 1 2008 Ian Kent <ikent@redhat.com> - 5.0.3-5
- another fix for don't fail on empty master map.