浏览代码

totemknet: retry knet_handle_new if it fails

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>
Dan Streetman 5 年之前
父节点
当前提交
4f171ea584
共有 4 个文件被更改,包括 39 次插入3 次删除
  1. 1 0
      exec/cfg.c
  2. 8 0
      exec/coroparse.c
  3. 19 3
      exec/totemknet.c
  4. 11 0
      man/corosync.conf.5

+ 1 - 0
exec/cfg.c

@@ -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");

+ 8 - 0
exec/coroparse.c

@@ -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:

+ 19 - 3
exec/totemknet.c

@@ -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");

+ 11 - 0
man/corosync.conf.5

@@ -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