summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--source3/client/smbmount.c73
-rw-r--r--source3/client/smbumount.c8
2 files changed, 63 insertions, 18 deletions
diff --git a/source3/client/smbmount.c b/source3/client/smbmount.c
index 2cfd166688..3c2d207498 100644
--- a/source3/client/smbmount.c
+++ b/source3/client/smbmount.c
@@ -38,7 +38,7 @@ static struct smb_conn_opt conn_options;
#endif
/* Uncomment this to allow debug the smbmount daemon */
-#define SMBFS_DEBUG 1
+/* #define SMBFS_DEBUG 1 */
pstring cur_dir = "\\";
pstring cd_path = "";
@@ -71,7 +71,6 @@ extern int name_type;
extern int max_protocol;
int port = SMB_PORT;
-
time_t newer_than = 0;
int archive_level = 0;
@@ -182,19 +181,50 @@ static BOOL chkpath(char *path,BOOL report)
}
static void
+exit_parent( int sig )
+{
+ /* parent simply exits when child says go... */
+ exit(0);
+}
+
+static void
daemonize(void)
{
- int i;
- if ((i = fork()) < 0)
+ int j, status;
+ pid_t child_pid;
+
+ signal( SIGTERM, exit_parent );
+
+ if ((child_pid = fork()) < 0)
{
DEBUG(0, ("could not fork\n"));
}
- if (i > 0)
+ if (child_pid > 0)
{
- /* parent simply exits */
- exit(0);
+ while( 1 ) {
+ j = waitpid( child_pid, &status, 0 );
+ if( j < 0 ) {
+ if( EINTR == errno ) {
+ continue;
+ }
+ status = errno;
+ }
+ break;
+ }
+ /* If we get here - the child exited with some error status */
+ exit(status);
}
- setsid();
+ /* Programmers Note:
+ Danger Will Robinson! Danger!
+
+ There use to be a call to setsid() here. This does no
+ harm to normal mount operations, but it broke automounting.
+ The setsid call has been moved to just before the child
+ sends the SIGTERM to the parent. All of our deadly embrace
+ conditions with autofs will have been cleared by then...
+ -mhw-
+ */
+ signal( SIGTERM, SIG_DFL );
chdir("/");
}
@@ -255,7 +285,8 @@ static void
send_fs_socket(char *mount_point, char *inbuf, char *outbuf)
{
int fd, closed = 0, res = 1;
- int first_time = 1;
+
+ pid_t parentpid = getppid();
while (1)
{
@@ -278,6 +309,15 @@ send_fs_socket(char *mount_point, char *inbuf, char *outbuf)
DEBUG(0, ("smbmount: ioctl failed, res=%d\n", res));
}
+ if( parentpid ) {
+ /* Ok... We are going to kill the parent. Now
+ is the time to break the process group... */
+ setsid();
+ /* Send a signal to the parent to terminate */
+ kill( parentpid, SIGTERM );
+ parentpid = 0;
+ }
+
close_sockets();
close(fd);
/*
@@ -291,15 +331,6 @@ send_fs_socket(char *mount_point, char *inbuf, char *outbuf)
}
#endif
- if( first_time ) {
- /*
- * Create the background process after trying the mount.
- * to avoid race conditions with automount and other processes.
- */
- first_time = 0;
- daemonize();
- }
-
/*
* Wait for a signal from smbfs ...
*/
@@ -368,6 +399,12 @@ static void cmd_mount(char *inbuf,char *outbuf)
DEBUG(3, ("mount command: %s\n", mount_command));
+ /*
+ Set up to return as a daemon child and wait in the parent
+ until the child say it's ready...
+ */
+ daemonize();
+
if ((retval = system(mount_command)) != 0)
{
DEBUG(0,("mount failed\n"));
diff --git a/source3/client/smbumount.c b/source3/client/smbumount.c
index 5e072274c9..84188542e5 100644
--- a/source3/client/smbumount.c
+++ b/source3/client/smbumount.c
@@ -15,6 +15,14 @@
#include <linux/smb_mount.h>
#include <linux/smb_fs.h>
+/* This is a (hopefully) temporary hack due to the fact that
+ sizeof( uid_t ) != sizeof( __kernel_uid_t ) under glibc.
+ This may change in the future and smb.h may get fixed in the
+ future. In the mean time, it's ugly hack time - get over it.
+*/
+#undef SMB_IOC_GETMOUNTUID
+#define SMB_IOC_GETMOUNTUID _IOR('u', 1, __kernel_uid_t)
+
static char *progname;
static void