]> git.proxmox.com Git - mirror_corosync.git/commitdiff
totemknet: retry knet_handle_new if it fails
authorDan Streetman <ddstreet@canonical.com>
Fri, 12 Mar 2021 12:31:47 +0000 (07:31 -0500)
committerJan Friesse <jfriesse@redhat.com>
Thu, 18 Mar 2021 16:21:06 +0000 (17:21 +0100)
Retry knet_handle_new without privileged operations if it fails

knet_handle_new can fail with ENAMETOOLONG if its privileged operations
fail, which can happen if we're running as a user process or in an
unprivileged container.

This adds a cmap key 'allow_knet_handle_fallback' that defaults to no,
which is the current behavior of exiting with error if the knet_handle
can't be created with privileged operations. If the new cmap key is set
to 'yes' and the knet_handle creation fails, fallback to creating the
handle using unprivileged operations is tried.

Signed-off-by: Dan Streetman <ddstreet@canonical.com>
Reviewed-by: Jan Friesse <jfriesse@redhat.com>
exec/cfg.c
exec/coroparse.c
exec/totemknet.c
man/corosync.conf.5

index 05b0ede53aefb56259d31420f11999fac88a03db..d0e89524135bd73c17e9ec8f306c3784d0d3d0df 100644 (file)
@@ -640,6 +640,7 @@ static void remove_ro_entries(icmap_map_t temp_map)
        delete_and_notify_if_changed(temp_map, "totem.cluster_name");
        delete_and_notify_if_changed(temp_map, "quorum.provider");
        delete_and_notify_if_changed(temp_map, "system.move_to_root_cgroup");
+       delete_and_notify_if_changed(temp_map, "system.allow_knet_handle_fallback");
        delete_and_notify_if_changed(temp_map, "system.sched_rr");
        delete_and_notify_if_changed(temp_map, "system.priority");
        delete_and_notify_if_changed(temp_map, "system.qb_ipc_type");
index 0acb4c2401ba4ee02cb443a7f81f07d062748578..0d36161471d23099396f7cc82af053e9fb7c59e4 100644 (file)
@@ -808,6 +808,14 @@ static int main_config_parser_cb(const char *path,
                                        return (0);
                                }
                        }
+                       if (strcmp(path, "system.allow_knet_handle_fallback") == 0) {
+                               if ((strcmp(value, "yes") != 0) &&
+                                   (strcmp(value, "no") != 0)) {
+                                       *error_string = "Invalid system.allow_knet_handle_fallback";
+
+                                       return (0);
+                               }
+                       }
                        break;
 
                case MAIN_CP_CB_DATA_STATE_INTERFACE:
index 772752c5e43a3c9d0112160a33a70409352a211e..2a5107951d552ca805de3e1454be22aa381bdaf2 100644 (file)
@@ -1081,7 +1081,9 @@ int totemknet_initialize (
                void *context))
 {
        struct totemknet_instance *instance;
+       char *tmp_str;
        int8_t channel=0;
+       int allow_knet_handle_fallback=0;
        int res;
        int i;
 
@@ -1146,13 +1148,27 @@ int totemknet_initialize (
                goto exit_error;
        }
 
+       if (icmap_get_string("system.allow_knet_handle_fallback", &tmp_str) == CS_OK) {
+               if (strcmp(tmp_str, "yes") == 0) {
+                       allow_knet_handle_fallback = 1;
+               }
+               free(tmp_str);
+       }
 
-#if !defined(KNET_API_VER) || (KNET_API_VER == 1)
+#if defined(KNET_API_VER) && (KNET_API_VER == 2)
+       instance->knet_handle = knet_handle_new(instance->totem_config->node_id, instance->logpipes[1], KNET_LOG_DEBUG, KNET_HANDLE_FLAG_PRIVILEGED);
+#else
        instance->knet_handle = knet_handle_new(instance->totem_config->node_id, instance->logpipes[1], KNET_LOG_DEBUG);
 #endif
-#if KNET_API_VER == 2
-       instance->knet_handle = knet_handle_new(instance->totem_config->node_id, instance->logpipes[1], KNET_LOG_DEBUG, KNET_HANDLE_FLAG_PRIVILEGED);
+
+       if (allow_knet_handle_fallback && !instance->knet_handle && errno == ENAMETOOLONG) {
+               KNET_LOGSYS_PERROR(errno, LOGSYS_LEVEL_WARNING, "knet_handle_new failed, trying unprivileged");
+#if defined(KNET_API_VER) && (KNET_API_VER == 2)
+               instance->knet_handle = knet_handle_new(instance->totem_config->node_id, instance->logpipes[1], KNET_LOG_DEBUG, 0);
+#else
+               instance->knet_handle = knet_handle_new_ex(instance->totem_config->node_id, instance->logpipes[1], KNET_LOG_DEBUG, 0);
 #endif
+       }
 
        if (!instance->knet_handle) {
                KNET_LOGSYS_PERROR(errno, LOGSYS_LEVEL_CRIT, "knet_handle_new failed");
index e29995d795a509c6176511bf4f4879750cf07860..3fdf823ff8c5008871e682e4951bbc327d9fef76 100644 (file)
@@ -801,6 +801,17 @@ Should be set to yes (default) if corosync should try to move itself to root
 cgroup. This feature is available only for systems with cgroups with RT
 sched enabled (Linux with CONFIG_RT_GROUP_SCHED kernel option).
 
+.TP
+allow_knet_handle_fallback
+If knet handle creation fails using privileged operations, allow fallback to
+creating knet handle using unprivileged operations. Defaults to no, meaning
+if privileged knet handle creation fails, corosync will refuse to start.
+
+The knet handle will always be created using privileged operations if possible,
+setting this to yes only allows fallback to unprivileged operations. This fallback
+may result in performance issues, but if running in an unprivileged environment,
+e.g. as a normal user or in unprivileged container, this may be required.
+
 .TP
 state_dir
 Existing directory where corosync should chdir into. Corosync stores