summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAndrew Shadura <andrewsh@debian.org>2016-04-28 09:13:13 +0200
committerAndrew Shadura <andrewsh@debian.org>2016-04-28 09:13:13 +0200
commitef08cf099c90c7f9582bd1b36a8cfa17dcb4a0c3 (patch)
tree3b8bb472524cc13e8ab39f83e8b1c30a9bd5f242
parentdbb5adb9dd88c9eedf34e8f3a0deea1152246667 (diff)
parent786c6d3813622d18e12d36c4aa722af6a417c8fa (diff)
Merge remote-tracking branch 'origin/PSEUDO_1_7_5'
-rw-r--r--ChangeLog.txt18
-rw-r--r--Makefile.in2
-rw-r--r--ports/linux/guts/__xmknodat.c6
-rw-r--r--ports/unix/guts/mknodat.c6
-rw-r--r--pseudo.c21
-rw-r--r--pseudo_client.c91
-rw-r--r--pseudo_db.c2
-rw-r--r--pseudo_server.c13
8 files changed, 107 insertions, 52 deletions
diff --git a/ChangeLog.txt b/ChangeLog.txt
index 5431f1e..eb72127 100644
--- a/ChangeLog.txt
+++ b/ChangeLog.txt
@@ -1,3 +1,21 @@
+2016-02-09:
+ * (seebs) 1.7.5 release
+
+2016-02-08:
+ * (seebs) require -S to shutdown server when running a command.
+ * (seebs) improve logic for server shutdowns, increase short timeout
+ * (seebs) rework client server-spawning logic significantly
+ * (seebs) make abort messages make it out, display message on abort
+
+2016-02-05:
+ * (seebs) don't abort search for server on first try.
+ * (seebs) new clients cancel a shutdown request.
+ * (seebs) sort xattrs when returning list.
+ * (seebs) add retry interval, rather than instant retries.
+
+2016-01-22:
+ * (seebs) Mask in S_IFREG when mknod called with no S_IFMT bits.
+
2015-09-22:
* (seebs) Fix modes after fopen/fopen64.
diff --git a/Makefile.in b/Makefile.in
index 7fa5149..6511814 100644
--- a/Makefile.in
+++ b/Makefile.in
@@ -44,7 +44,7 @@ BITS=@BITS@
ARCH_FLAGS=@ARCH_FLAGS@
MARK64=@MARK64@
RPATH=@RPATH@
-VERSION=1.7.4
+VERSION=1.7.5
LIB=@LIB@
BIN=bin
diff --git a/ports/linux/guts/__xmknodat.c b/ports/linux/guts/__xmknodat.c
index 296918a..4fa021b 100644
--- a/ports/linux/guts/__xmknodat.c
+++ b/ports/linux/guts/__xmknodat.c
@@ -11,6 +11,12 @@
/* mask out mode bits appropriately */
mode = mode & ~pseudo_umask;
+ /* if you don't specify a type, assume regular file */
+ if (!(mode & S_IFMT)) {
+ mode |= S_IFREG;
+ }
+ pseudo_debug(PDBGF_FILE, "xmknodat creating '%s', mode 0%o\n",
+ path ? path : "<no name>", (int) mode);
/* we don't use underlying call, so _ver is irrelevant to us */
(void) ver;
diff --git a/ports/unix/guts/mknodat.c b/ports/unix/guts/mknodat.c
index 76e4dd9..afeab46 100644
--- a/ports/unix/guts/mknodat.c
+++ b/ports/unix/guts/mknodat.c
@@ -12,6 +12,12 @@
/* mask out mode bits appropriately */
mode = mode & ~pseudo_umask;
+ /* if you don't specify a type, assume regular file */
+ if (!(mode & S_IFMT)) {
+ mode |= S_IFREG;
+ }
+ pseudo_debug(PDBGF_FILE, "mknodat creating '%s', mode 0%o\n",
+ path ? path : "<no name>", (int) mode);
#ifdef PSEUDO_NO_REAL_AT_FUNCTIONS
if (dirfd != AT_FDCWD) {
diff --git a/pseudo.c b/pseudo.c
index 5715af2..4451992 100644
--- a/pseudo.c
+++ b/pseudo.c
@@ -343,7 +343,8 @@ main(int argc, char *argv[]) {
return pseudo_db_check(opt_B);
}
- if (opt_S) {
+ /* If you didn't specify a command, opt_S shuts down here. */
+ if (opt_S && argc <= optind) {
return pseudo_client_shutdown();
}
@@ -418,8 +419,17 @@ main(int argc, char *argv[]) {
/* try to hint that we don't think we still need
* the server.
*/
- pseudo_client_shutdown();
- return WEXITSTATUS(rc);
+ if (opt_S) {
+ pseudo_client_shutdown();
+ }
+ if (WIFEXITED(rc)) {
+ return WEXITSTATUS(rc);
+ } else if (WIFSIGNALED(rc)) {
+ kill(getpid(), WTERMSIG(rc));
+ exit(1);
+ } else {
+ exit(1);
+ }
} else {
rc = execv(fullpath, argv);
if (rc == -1) {
@@ -1067,9 +1077,10 @@ pseudo_op(pseudo_msg_t *msg, const char *program, const char *tag, char **respon
msg->uid = (uid_t) -1;
msg->gid = (gid_t) -1;
#endif
- pseudo_debug(PDBGF_DB, "linking %s (uid -1 if xattr) for %s\n",
+ pseudo_debug(PDBGF_DB | PDBGF_XATTR, "linking %s (uid -1 if xattr) for %s, mode 0%o\n",
msg->pathlen ? msg->path : "no path",
- pseudo_op_name(msg->op));
+ pseudo_op_name(msg->op),
+ (int) msg->mode);
pdb_link_file(msg, &row);
}
if (pdb_set_xattr(row, oldpath, oldpathlen, xattr_flags)) {
diff --git a/pseudo_client.c b/pseudo_client.c
index 4eb91df..b02657f 100644
--- a/pseudo_client.c
+++ b/pseudo_client.c
@@ -25,6 +25,7 @@
#include <stdlib.h>
#include <string.h>
#include <limits.h>
+#include <time.h>
#include <unistd.h>
#include <errno.h>
#include <sys/socket.h>
@@ -1200,7 +1201,8 @@ pseudo_client_setup(void) {
}
pseudo_debug(PDBGF_CLIENT, "server seems to be gone, trying to restart\n");
if (client_spawn_server()) {
- pseudo_debug(PDBGF_CLIENT, "failed to spawn server, giving up.\n");
+
+ pseudo_debug(PDBGF_CLIENT, "failed to spawn server, waiting for retry.\n");
return 1;
} else {
pseudo_debug(PDBGF_CLIENT, "restarted, new pid %d\n", server_pid);
@@ -1208,10 +1210,11 @@ pseudo_client_setup(void) {
return 0;
}
}
- pseudo_debug(PDBGF_CLIENT, "couldn't get a server, giving up.\n");
+ pseudo_debug(PDBGF_CLIENT, "couldn't get or spawn a server.\n");
return 1;
}
+#define PSEUDO_RETRIES 50
static pseudo_msg_t *
pseudo_client_request(pseudo_msg_t *msg, size_t len, const char *path) {
pseudo_msg_t *response = 0;
@@ -1221,51 +1224,55 @@ pseudo_client_request(pseudo_msg_t *msg, size_t len, const char *path) {
if (!msg)
return 0;
- do {
- do {
- pseudo_debug(PDBGF_CLIENT | PDBGF_VERBOSE, "sending a message: ino %llu\n",
- (unsigned long long) msg->ino);
- if (connect_fd < 0) {
- pseudo_debug(PDBGF_CLIENT, "trying to get server\n");
- if (pseudo_client_setup()) {
- return 0;
- }
+ /* Try to send a message. If sending fails, try to spawn a server,
+ * and whether or not we succeed, wait a little bit and retry sending.
+ * It's okay if we can't start a server sometimes, because another
+ * client may have done it.
+ */
+ for (tries = 0; tries < PSEUDO_RETRIES; ++tries) {
+ pseudo_debug(PDBGF_CLIENT | PDBGF_VERBOSE, "sending a message: ino %llu\n",
+ (unsigned long long) msg->ino);
+ rc = pseudo_msg_send(connect_fd, msg, len, path);
+ if (rc != 0) {
+ pseudo_debug(PDBGF_CLIENT | PDBGF_VERBOSE, "msg_send: %d%s\n",
+ rc,
+ rc == -1 ? " (sigpipe)" :
+ " (short write)");
+ pseudo_debug(PDBGF_CLIENT, "trying to get server, try %d\n", tries);
+ /* try to open server; if we fail, wait a bit before
+ * retry.
+ */
+ if (pseudo_client_setup()) {
+ int ms = (getpid() % 5) + 3 + tries;
+ struct timespec delay = { .tv_sec = 0, .tv_nsec = ms * 1000000 };
+ nanosleep(&delay, NULL);
}
- rc = pseudo_msg_send(connect_fd, msg, len, path);
- if (rc != 0) {
- pseudo_debug(PDBGF_CLIENT | PDBGF_VERBOSE, "msg_send: %d%s\n",
- rc,
- rc == -1 ? " (sigpipe)" :
- " (short write)");
- pseudo_client_setup();
- ++tries;
- if (tries > 3) {
- pseudo_debug(PDBGF_CLIENT, "Can't get server going again.\n");
+ continue;
+ }
+ /* note "continue" above; we only get here if rc was 0,
+ * indicating a successful send.
+ */
+ pseudo_debug(PDBGF_CLIENT | PDBGF_VERBOSE, "sent!\n");
+ if (msg->type != PSEUDO_MSG_FASTOP) {
+ response = pseudo_msg_receive(connect_fd);
+ if (!response) {
+ pseudo_debug(PDBGF_CLIENT, "expected response did not occur; retrying\n");
+ } else {
+ if (response->type != PSEUDO_MSG_ACK) {
+ pseudo_debug(PDBGF_CLIENT, "got non-ack response %d\n", response->type);
return 0;
+ } else {
+ pseudo_debug(PDBGF_CLIENT | PDBGF_VERBOSE, "got response type %d\n", response->type);
+ return response;
}
}
- } while (rc != 0);
- pseudo_debug(PDBGF_CLIENT | PDBGF_VERBOSE, "sent!\n");
- if (msg->type != PSEUDO_MSG_FASTOP) {
- response = pseudo_msg_receive(connect_fd);
- if (!response) {
- ++tries;
- if (tries > 3) {
- pseudo_debug(PDBGF_CLIENT, "Can't get responses.\n");
- return 0;
- }
- }
- } else {
- return 0;
- }
- } while (response == 0);
- if (response->type != PSEUDO_MSG_ACK) {
- pseudo_debug(PDBGF_CLIENT, "got non-ack response %d\n", response->type);
- return 0;
- } else {
- pseudo_debug(PDBGF_CLIENT | PDBGF_VERBOSE, "got response type %d\n", response->type);
+ } else {
+ return 0;
+ }
}
- return response;
+ pseudo_diag("pseudo: server connection persistently failed, aborting.\n");
+ abort();
+ return 0;
}
int
diff --git a/pseudo_db.c b/pseudo_db.c
index f60f0ab..c387cb5 100644
--- a/pseudo_db.c
+++ b/pseudo_db.c
@@ -2235,7 +2235,7 @@ pdb_list_xattr(long long file_id, char **value, size_t *len) {
size_t used = 0;
char *buffer = 0;
int rc;
- char *sql = "SELECT name FROM xattrs WHERE file_id = ?;";
+ char *sql = "SELECT name FROM xattrs WHERE file_id = ? ORDER BY name;";
/* if we don't have a record of the file, it must not have
* any extended attributes...
diff --git a/pseudo_server.c b/pseudo_server.c
index 1fdadcb..4ceaa47 100644
--- a/pseudo_server.c
+++ b/pseudo_server.c
@@ -58,7 +58,8 @@ pseudo_client_t *clients;
static int active_clients = 0, highest_client = 0, max_clients = 0;
#define LOOP_DELAY 2
-int pseudo_server_timeout = 30;
+#define DEFAULT_PSEUDO_SERVER_TIMEOUT 30
+int pseudo_server_timeout = DEFAULT_PSEUDO_SERVER_TIMEOUT;
static int die_peacefully = 0;
static int die_forcefully = 0;
@@ -345,7 +346,7 @@ serve_client(int i) {
}
in->pathlen = (s - response_path) + 1;
/* exit quickly once clients go away, though */
- pseudo_server_timeout = 1;
+ pseudo_server_timeout = 3;
} else {
in->type = PSEUDO_MSG_ACK;
in->pathlen = 0;
@@ -474,13 +475,19 @@ pseudo_server_loop(void) {
if (die_forcefully)
break;
}
- if (!(die_peacefully || die_forcefully) &&
+ if (!die_forcefully &&
(FD_ISSET(clients[0].fd, &events) ||
FD_ISSET(clients[0].fd, &reads))) {
len = sizeof(client);
if ((fd = accept(listen_fd, (struct sockaddr *) &client, &len)) != -1) {
pseudo_debug(PDBGF_SERVER, "new client fd %d\n", fd);
open_client(fd);
+ /* A new client implicitly cancels any
+ * previous shutdown request, or a
+ * shutdown for lack of clients.
+ */
+ pseudo_server_timeout = DEFAULT_PSEUDO_SERVER_TIMEOUT;
+ die_peacefully = 0;
}
}
pseudo_debug(PDBGF_SERVER, "server loop complete [%d clients left]\n", active_clients);