diff options
author | Andrew Shadura <andrewsh@debian.org> | 2016-04-28 09:13:13 +0200 |
---|---|---|
committer | Andrew Shadura <andrewsh@debian.org> | 2016-04-28 09:13:13 +0200 |
commit | ef08cf099c90c7f9582bd1b36a8cfa17dcb4a0c3 (patch) | |
tree | 3b8bb472524cc13e8ab39f83e8b1c30a9bd5f242 | |
parent | dbb5adb9dd88c9eedf34e8f3a0deea1152246667 (diff) | |
parent | 786c6d3813622d18e12d36c4aa722af6a417c8fa (diff) |
Merge remote-tracking branch 'origin/PSEUDO_1_7_5'
-rw-r--r-- | ChangeLog.txt | 18 | ||||
-rw-r--r-- | Makefile.in | 2 | ||||
-rw-r--r-- | ports/linux/guts/__xmknodat.c | 6 | ||||
-rw-r--r-- | ports/unix/guts/mknodat.c | 6 | ||||
-rw-r--r-- | pseudo.c | 21 | ||||
-rw-r--r-- | pseudo_client.c | 91 | ||||
-rw-r--r-- | pseudo_db.c | 2 | ||||
-rw-r--r-- | pseudo_server.c | 13 |
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) { @@ -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); |