summaryrefslogtreecommitdiff
path: root/misc
diff options
context:
space:
mode:
authorTheodore Ts'o <tytso@mit.edu>2008-02-15 21:24:30 -0500
committerTheodore Ts'o <tytso@mit.edu>2008-02-17 17:33:48 -0500
commitcfa30fd554a5ec905ef1e4e3f2b1f8ba9ba8b7e5 (patch)
tree48e2751079a35ff264006bdb088b9457f83e61a6 /misc
parente70f32b79d29e287f8347c5d41c6716f094cc654 (diff)
downloade2fsprogs-cfa30fd554a5ec905ef1e4e3f2b1f8ba9ba8b7e5.tar.gz
uuidd: Fix pid file so it has the correct pid number
The pid file was getting created before the fork(), so it had the incorrect pid number. No one noticed for a while, since "uuidd -k" will kill the daemon and it has enough automatic convenience functions that it's usually not necessary to refer to the pid file except as a convenient place for uuidd to lock against multiple instances of the daemon starting up. Addresses-Sourceforge-Bug: #1893244 Signed-off-by: "Theodore Ts'o" <tytso@mit.edu>
Diffstat (limited to 'misc')
-rw-r--r--misc/uuidd.c264
1 files changed, 132 insertions, 132 deletions
diff --git a/misc/uuidd.c b/misc/uuidd.c
index 2fb10575..1b2deddd 100644
--- a/misc/uuidd.c
+++ b/misc/uuidd.c
@@ -24,6 +24,7 @@
#include <sys/un.h>
#include <fcntl.h>
#include <signal.h>
+#include <string.h>
#ifdef HAVE_GETOPT_H
#include <getopt.h>
#else
@@ -107,17 +108,138 @@ static void terminate_intr(int signo CODE_ATTR((unused)))
exit(0);
}
-static void server_loop(const char *socket_path, int debug,
- int fd_pidfile, int timeout, int quiet)
+static int call_daemon(const char *socket_path, int op, char *buf,
+ int buflen, int *num, const char **err_context)
+{
+ char op_buf[8];
+ int op_len;
+ int s;
+ ssize_t ret;
+ int32_t reply_len = 0;
+ struct sockaddr_un srv_addr;
+
+ if (((op == 4) || (op == 5)) && !num) {
+ if (err_context)
+ *err_context = _("bad arguments");
+ errno = EINVAL;
+ return -1;
+ }
+
+ if ((s = socket(AF_UNIX, SOCK_STREAM, 0)) < 0) {
+ if (err_context)
+ *err_context = _("socket");
+ return -1;
+ }
+
+ srv_addr.sun_family = AF_UNIX;
+ strcpy(srv_addr.sun_path, socket_path);
+
+ if (connect(s, (const struct sockaddr *) &srv_addr,
+ sizeof(struct sockaddr_un)) < 0) {
+ if (err_context)
+ *err_context = _("connect");
+ close(s);
+ return -1;
+ }
+
+ if (op == 5) {
+ if ((*num)*16 > buflen-4)
+ *num = (buflen-4) / 16;
+ }
+ op_buf[0] = op;
+ op_len = 1;
+ if ((op == 4) || (op == 5)) {
+ memcpy(op_buf+1, num, sizeof(int));
+ op_len += sizeof(int);
+ }
+
+ ret = write(s, op_buf, op_len);
+ if (ret < op_len) {
+ if (err_context)
+ *err_context = _("write");
+ close(s);
+ return -1;
+ }
+
+ ret = read_all(s, (char *) &reply_len, sizeof(reply_len));
+ if (ret < 0) {
+ if (err_context)
+ *err_context = _("read count");
+ close(s);
+ return -1;
+ }
+ if (reply_len < 0 || reply_len > buflen) {
+ if (err_context)
+ *err_context = _("bad response length");
+ close(s);
+ return -1;
+ }
+ ret = read_all(s, (char *) buf, reply_len);
+
+ if ((ret > 0) && (op == 4)) {
+ if (reply_len >= (int) (16+sizeof(int)))
+ memcpy(buf+16, num, sizeof(int));
+ else
+ *num = -1;
+ }
+ if ((ret > 0) && (op == 5)) {
+ if (*num >= (int) sizeof(int))
+ memcpy(buf, num, sizeof(int));
+ else
+ *num = -1;
+ }
+
+ close(s);
+
+ return ret;
+}
+
+static void server_loop(const char *socket_path, const char *pidfile_path,
+ int debug, int timeout, int quiet)
{
struct sockaddr_un my_addr, from_addr;
unsigned char reply_buf[1024], *cp;
+ struct flock fl;
socklen_t fromlen;
int32_t reply_len = 0;
uuid_t uu;
mode_t save_umask;
char op, str[37];
int i, s, ns, len, num;
+ int fd_pidfile, ret;
+
+ fd_pidfile = open(pidfile_path, O_CREAT | O_RDWR, 0664);
+ if (fd_pidfile < 0) {
+ if (!quiet)
+ fprintf(stderr, "Failed to open/create %s: %s\n",
+ pidfile_path, strerror(errno));
+ exit(1);
+ }
+ cleanup_pidfile = pidfile_path;
+ cleanup_socket = 0;
+ signal(SIGALRM, terminate_intr);
+ alarm(30);
+ fl.l_type = F_WRLCK;
+ fl.l_whence = SEEK_SET;
+ fl.l_start = 0;
+ fl.l_len = 0;
+ fl.l_pid = 0;
+ while (fcntl(fd_pidfile, F_SETLKW, &fl) < 0) {
+ if ((errno == EAGAIN) || (errno == EINTR))
+ continue;
+ if (!quiet)
+ fprintf(stderr, "Failed to lock %s: %s\n",
+ pidfile_path, strerror(errno));
+ exit(1);
+ }
+ ret = call_daemon(socket_path, 0, reply_buf, sizeof(reply_buf), 0, 0);
+ if (ret > 0) {
+ if (!quiet)
+ printf(_("uuidd daemon already running at pid %s\n"),
+ reply_buf);
+ exit(1);
+ }
+ alarm(0);
if ((s = socket(AF_UNIX, SOCK_STREAM, 0)) < 0) {
if (!quiet)
@@ -151,8 +273,6 @@ static void server_loop(const char *socket_path, int debug,
exit(1);
}
- if (fd_pidfile > 1)
- close(fd_pidfile); /* Unlock the pid file */
cleanup_socket = socket_path;
if (!debug)
create_daemon();
@@ -162,6 +282,12 @@ static void server_loop(const char *socket_path, int debug,
signal(SIGALRM, terminate_intr);
signal(SIGPIPE, SIG_IGN);
+ sprintf(reply_buf, "%d\n", getpid());
+ ftruncate(fd_pidfile, 0);
+ write(fd_pidfile, reply_buf, strlen(reply_buf));
+ if (fd_pidfile > 1)
+ close(fd_pidfile); /* Unlock the pid file */
+
while (1) {
fromlen = sizeof(from_addr);
if (timeout > 0)
@@ -264,130 +390,6 @@ static void server_loop(const char *socket_path, int debug,
}
}
-static int call_daemon(const char *socket_path, int op, char *buf,
- int buflen, int *num, const char **err_context)
-{
- char op_buf[8];
- int op_len;
- int s;
- ssize_t ret;
- int32_t reply_len = 0;
- struct sockaddr_un srv_addr;
-
- if (((op == 4) || (op == 5)) && !num) {
- if (err_context)
- *err_context = _("bad arguments");
- errno = EINVAL;
- return -1;
- }
-
- if ((s = socket(AF_UNIX, SOCK_STREAM, 0)) < 0) {
- if (err_context)
- *err_context = _("socket");
- return -1;
- }
-
- srv_addr.sun_family = AF_UNIX;
- strcpy(srv_addr.sun_path, socket_path);
-
- if (connect(s, (const struct sockaddr *) &srv_addr,
- sizeof(struct sockaddr_un)) < 0) {
- if (err_context)
- *err_context = _("connect");
- close(s);
- return -1;
- }
-
- if (op == 5) {
- if ((*num)*16 > buflen-4)
- *num = (buflen-4) / 16;
- }
- op_buf[0] = op;
- op_len = 1;
- if ((op == 4) || (op == 5)) {
- memcpy(op_buf+1, num, sizeof(int));
- op_len += sizeof(int);
- }
-
- ret = write(s, op_buf, op_len);
- if (ret < op_len) {
- if (err_context)
- *err_context = _("write");
- close(s);
- return -1;
- }
-
- ret = read_all(s, (char *) &reply_len, sizeof(reply_len));
- if (ret < 0) {
- if (err_context)
- *err_context = _("read count");
- close(s);
- return -1;
- }
- if (reply_len < 0 || reply_len > buflen) {
- if (err_context)
- *err_context = _("bad response length");
- close(s);
- return -1;
- }
- ret = read_all(s, (char *) buf, reply_len);
-
- if ((ret > 0) && (op == 4)) {
- if (reply_len >= (int) (16+sizeof(int)))
- memcpy(buf+16, num, sizeof(int));
- else
- *num = -1;
- }
- if ((ret > 0) && (op == 5)) {
- if (*num >= (int) sizeof(int))
- memcpy(buf, num, sizeof(int));
- else
- *num = -1;
- }
-
- close(s);
-
- return ret;
-}
-
-static int create_pidfile(const char *socket_path, const char *pidfile_path,
- int quiet)
-{
- int fd, ret;
- char buf[20];
-
- fd = open(pidfile_path, O_CREAT | O_RDWR, 0664);
- if (fd < 0) {
- if (!quiet)
- fprintf(stderr, "Failed to open/create %s: %s\n",
- pidfile_path, strerror(errno));
- exit(1);
- }
- cleanup_pidfile = pidfile_path;
- cleanup_socket = 0;
- signal(SIGALRM, terminate_intr);
- alarm(30);
- if (lockf(fd, F_LOCK, 0) < 0) {
- if (!quiet)
- fprintf(stderr, "Failed to lock %s: %s\n",
- pidfile_path, strerror(errno));
- exit(1);
- }
- ret = call_daemon(socket_path, 0, buf, sizeof(buf), 0, 0);
- if (ret > 0) {
- if (!quiet)
- printf(_("uuidd daemon already running at pid %s\n"),
- buf);
- exit(1);
- }
- alarm(0);
-
- sprintf(buf, "%d\n", getpid());
- ftruncate(fd, 0);
- write(fd, buf, strlen(buf));
- return(fd);
-}
-
int main(int argc, char **argv)
{
const char *socket_path = UUIDD_SOCKET_PATH;
@@ -398,7 +400,7 @@ int main(int argc, char **argv)
uuid_t uu;
uid_t uid;
gid_t gid;
- int i, c, ret, fd_pidfile = -1;
+ int i, c, ret;
int debug = 0, do_type = 0, do_kill = 0, num = 0;
int timeout = 0, quiet = 0, drop_privs = 0;
@@ -535,8 +537,6 @@ int main(int argc, char **argv)
exit(0);
}
- fd_pidfile = create_pidfile(socket_path, pidfile_path, quiet);
-
- server_loop(socket_path, debug, fd_pidfile, timeout, quiet);
+ server_loop(socket_path, pidfile_path, debug, timeout, quiet);
return 0;
}