diff --git a/manager/context.c b/manager/context.c index 1eb37c9..c751495 100644 --- a/manager/context.c +++ b/manager/context.c @@ -45,13 +45,17 @@ const char *mgr_ovz_id(void) static void cleanup_spfs_mount(struct spfs_manager_context_s *ctx, struct spfs_info_s *info, int status) { - bool killed = WIFSIGNALED(status); + bool failed = WIFSIGNALED(status) || !!WEXITSTATUS(status); - pr_debug("removing info %s from the list\n", info->mnt.id); + pr_debug("removing info %s from the list (replacer pid %d)\n", + info->mnt.id, info->replacer); - if (killed) - /* SPFS master was killed. We need to release the reference */ + if (failed) { + /* SPFS master was failed. We need to release the reference */ spfs_release_mnt(info); + if (info->replacer > 0 && kill(info->replacer, SIGKILL)) + pr_perror("Failed to kill replacer"); + } info->dead = true; del_spfs_info(ctx->spfs_mounts, info); @@ -59,11 +63,19 @@ static void cleanup_spfs_mount(struct spfs_manager_context_s *ctx, if (unlink(info->socket_path)) pr_perror("failed to unlink %s", info->socket_path); - spfs_cleanup_env(info, killed); + spfs_cleanup_env(info, failed); close_namespaces(info->ns_fds); } +static inline void pr_term_mnt_service_info(pid_t pid, int status, const char *mnt, const char* tag) +{ + if (WIFEXITED(status)) + pr_debug("spfs (mnt_id %s) %s (pid %d) exited, status=%d\n", mnt, tag, pid, WEXITSTATUS(status)); + else + pr_err("spfs (mnt_id %s) %s (pid %d) killed by signal %d (%s)\n", mnt, tag, pid, WTERMSIG(status), strsignal(WTERMSIG(status))); +} + static void sigchld_handler(int signal, siginfo_t *siginfo, void *data) { struct spfs_manager_context_s *ctx = &spfs_manager_context; @@ -75,29 +87,26 @@ static void sigchld_handler(int signal, siginfo_t *siginfo, void *data) while ((pid = waitpid(-1, &status, WNOHANG)) > 0) { struct spfs_info_s *info; - if (WIFEXITED(status)) - pr_debug("%d exited, status=%d\n", pid, WEXITSTATUS(status)); - else - pr_err("%d killed by signal %d (%s)\n", pid, WTERMSIG(status), strsignal(WTERMSIG(status))); - - info = find_spfs_by_replacer(ctx->spfs_mounts, pid); - if (info) { + if ((info = find_spfs_by_replacer(ctx->spfs_mounts, pid))) { if (WEXITSTATUS(status) == 0) /* SPFS has been successfully replaced. * Now we can release spfs mount by closing * corresponding fd. */ spfs_release_mnt(info); - } else { - info = find_spfs_by_pid(ctx->spfs_mounts, pid); - if (info) { - pr_info("spfs %s master has exited\n", info->mnt.id); - cleanup_spfs_mount(ctx, info, status); - if (list_empty(&ctx->spfs_mounts->list) && ctx->exit_with_spfs) { - pr_info("spfs list is empty. Exiting.\n"); - exit(0); - } + + pr_term_mnt_service_info(pid, status, info->mnt.id, "replacer"); + info->replacer = -1; + } else if ((info = find_spfs_by_pid(ctx->spfs_mounts, pid))) { + pr_term_mnt_service_info(pid, status, info->mnt.id, "master"); + + cleanup_spfs_mount(ctx, info, status); + if (list_empty(&ctx->spfs_mounts->list) && ctx->exit_with_spfs) { + pr_info("spfs list is empty. Exiting.\n"); + exit(0); } + } else { + pr_term_mnt_service_info(pid, status, "unknown", "unknown"); } } diff --git a/manager/file_obj.c b/manager/file_obj.c index 387a6dc..a97aaa4 100644 --- a/manager/file_obj.c +++ b/manager/file_obj.c @@ -198,6 +198,10 @@ fobj_ops_t fobj_ops[] = { .early_open = unix_sk_early_open, .close = reg_file_close, }, + [FTYPE_LINK] = { + .open = reg_file_open, + .close = reg_file_close, + }, }; static file_type_t convert_mode_to_type(mode_t mode) @@ -233,9 +237,9 @@ static int get_file_ops(mode_t mode, fobj_ops_t **ops) case FTYPE_DIR: case FTYPE_FIFO: case FTYPE_SOCK: + case FTYPE_LINK: *ops = &fobj_ops[type]; return 0; - case FTYPE_LINK: case FTYPE_CHR: case FTYPE_BLK: break; diff --git a/manager/spfs.c b/manager/spfs.c index 3e0f667..7ee582f 100644 --- a/manager/spfs.c +++ b/manager/spfs.c @@ -107,6 +107,7 @@ int create_spfs_info(const char *id, INIT_LIST_HEAD(&info->processes); info->mode = SPFS_REPLACE_MODE_HOLD; + info->replacer = -1; *i = info; @@ -409,9 +410,9 @@ int spfs_prepare_env(struct spfs_info_s *info, const char *proxy_dir) return err ? err : res; } -static int __spfs_cleanup_env(struct spfs_info_s *info, bool killed) +static int __spfs_cleanup_env(struct spfs_info_s *info, bool failed) { - if (killed && umount(info->work_dir)) { + if (failed && umount(info->work_dir)) { pr_perror("failed to umount %s", info->work_dir); return -errno; } @@ -423,7 +424,7 @@ static int __spfs_cleanup_env(struct spfs_info_s *info, bool killed) return 0; } -int spfs_cleanup_env(struct spfs_info_s *info, bool killed) +int spfs_cleanup_env(struct spfs_info_s *info, bool failed) { int err, res; unsigned orig_ns_mask; @@ -432,7 +433,7 @@ int spfs_cleanup_env(struct spfs_info_s *info, bool killed) if (res) return res; - err = __spfs_cleanup_env(info, killed); + err = __spfs_cleanup_env(info, failed); res = leave_spfs_context(info, orig_ns_mask); diff --git a/src/socket.c b/src/socket.c index 05f171c..1184d69 100644 --- a/src/socket.c +++ b/src/socket.c @@ -76,7 +76,7 @@ int unreliable_conn_handler(int sock, void *data, return -errno; } if (bytes == 0) { - pr_debug("%s: peer was closed\n", __func__); + pr_debug("%s: peer was closed for fd %d\n", __func__, sock); return -ECONNABORTED; } @@ -105,7 +105,7 @@ int unreliable_socket_loop(int psock, void *data, bool async, break; } - pr_debug("%s: accepted new socket\n", __func__); + pr_debug("%s: accepted new socket fd %d\n", __func__, sock); do { err = unreliable_conn_handler(sock, data, packet_handler);