File Fix-peer_device-objects.patch of Package drbd-utils.5899
commit 39380e53473963f93251ca337c39c9b2bd4490a6
Author: Philipp Reisner <philipp.reisner@linbit.com>
Date: Fri Aug 25 13:00:57 2017 +0200
drbdadm: Fix peer_device objects
Commit e7a73044 was wrong. It introduced that there is one peer_device
object per connection and d_volume. d_volume exists per host.
Revert that.
One peer_device object per volume is enough!
diff -Naur drbd-utils-9.0.0.orig/user/v9/drbdadm_adjust.c drbd-utils-9.0.0/user/v9/drbdadm_adjust.c
--- drbd-utils-9.0.0.orig/user/v9/drbdadm_adjust.c 2018-01-18 11:22:01.173513190 +0800
+++ drbd-utils-9.0.0/user/v9/drbdadm_adjust.c 2018-01-18 11:22:09.265471980 +0800
@@ -650,16 +650,16 @@
}
static void
-adjust_peer_devices(const struct cfg_ctx *ctx, struct connection *conn, struct connection *running_conn)
+adjust_peer_devices(const struct cfg_ctx *ctx, struct connection *running_conn)
{
struct adm_cmd *cmd = &peer_device_options_defaults_cmd;
struct context_def *oc = &peer_device_options_ctx;
struct peer_device *peer_device, *running_pd;
struct cfg_ctx tmp_ctx = *ctx;
- STAILQ_FOREACH(peer_device, &conn->peer_devices, connection_link) {
+ STAILQ_FOREACH(peer_device, &ctx->conn->peer_devices, connection_link) {
running_pd = matching_peer_device(peer_device, &running_conn->peer_devices);
- tmp_ctx.vol = peer_device->volume;
+ tmp_ctx.vol = volume_by_vnr(&ctx->conn->peer->volumes, peer_device->vnr);
if (!running_pd) {
schedule_deferred_cmd(cmd, &tmp_ctx, CFG_PEER_DEVICE);
continue;
@@ -682,23 +682,21 @@
struct d_host_info *me = ctx->res->me;
struct d_volume *vol;
for_each_volume(vol, &me->volumes) {
- peer_device = find_peer_device(me, tmp_ctx.conn, vol->vnr);
+ peer_device = find_peer_device(tmp_ctx.conn, vol->vnr);
if (!peer_device || STAILQ_EMPTY(&peer_device->pd_options))
continue;
- tmp_ctx.vol = peer_device->volume;
+ tmp_ctx.vol = vol;
schedule_deferred_cmd(cmd, &tmp_ctx, CFG_PEER_DEVICE | SCHEDULE_ONCE);
}
} else if (!tmp_ctx.conn) {
- STAILQ_FOREACH(peer_device, &tmp_ctx.vol->peer_devices, volume_link) {
-
- if (!peer_device->connection->paths.stqh_first->my_address ||
- !peer_device->connection->paths.stqh_first->connect_to)
- continue;
- if (STAILQ_EMPTY(&peer_device->pd_options))
+ struct connection *conn;
+ for_each_connection(conn, &ctx->res->connections) {
+ peer_device = find_peer_device(conn, tmp_ctx.vol->vnr);
+ if (!peer_device || STAILQ_EMPTY(&peer_device->pd_options))
continue;
- tmp_ctx.conn = peer_device->connection;
+ tmp_ctx.conn = conn;
schedule_deferred_cmd(cmd, &tmp_ctx, CFG_PEER_DEVICE | SCHEDULE_ONCE);
}
} else {
@@ -782,7 +780,7 @@
if (connect)
schedule_deferred_cmd(&connect_cmd, &tmp_ctx, CFG_NET_CONNECT);
- adjust_peer_devices(&tmp_ctx, conn, running_conn);
+ adjust_peer_devices(&tmp_ctx, running_conn);
}
path = STAILQ_FIRST(&conn->paths); /* multiple paths via proxy, later! */
diff -Naur drbd-utils-9.0.0.orig/user/v9/drbdadm.h drbd-utils-9.0.0/user/v9/drbdadm.h
--- drbd-utils-9.0.0.orig/user/v9/drbdadm.h 2018-01-18 11:22:01.173513190 +0800
+++ drbd-utils-9.0.0/user/v9/drbdadm.h 2018-01-18 11:22:09.265471980 +0800
@@ -72,10 +72,12 @@
int config_line; /* parsed here */
struct connection *connection;
- struct d_volume *volume; /* set in post_parese() */
+ /* No pointer to d_volume, because there are two!
+ On each side of the connection!
+ Iterate d_host_info and find the correct volume by matching vnr! */
STAILQ_ENTRY(peer_device) connection_link; /* added during parsing */
- STAILQ_ENTRY(peer_device) volume_link; /* added in post_parse() */
+ /* no volume_link !! */
unsigned int implicit:1; /* Do not dump by default */
};
@@ -437,7 +439,7 @@
int do_proxy_conn_up(const struct cfg_ctx *ctx);
int do_proxy_conn_down(const struct cfg_ctx *ctx);
int do_proxy_conn_plugins(const struct cfg_ctx *ctx);
-struct peer_device *find_peer_device(struct d_host_info *host, struct connection *conn, int vnr);
+struct peer_device *find_peer_device(struct connection *conn, int vnr);
bool peer_diskless(struct peer_device *peer_device);
extern char *config_file;
diff -Naur drbd-utils-9.0.0.orig/user/v9/drbdadm_main.c drbd-utils-9.0.0/user/v9/drbdadm_main.c
--- drbd-utils-9.0.0.orig/user/v9/drbdadm_main.c 2018-01-18 11:22:01.173513190 +0800
+++ drbd-utils-9.0.0/user/v9/drbdadm_main.c 2018-01-18 11:22:09.265471980 +0800
@@ -1683,7 +1683,7 @@
char *argv[MAX_ARGS];
int argc = 0;
- peer_device = find_peer_device(res->me, conn, vol->vnr);
+ peer_device = find_peer_device(conn, vol->vnr);
if (!peer_device) {
err("Could not find peer_device object!\n");
exit(E_THINKO);
@@ -2009,7 +2009,7 @@
continue;
tmp2_ctx = tmp_ctx;
- tmp2_ctx.vol = peer_device->volume;
+ tmp2_ctx.vol = volume_by_vnr(&conn->peer->volumes, peer_device->vnr);
schedule_deferred_cmd(&peer_device_options_cmd, &tmp2_ctx, CFG_PEER_DEVICE);
}
}
diff -Naur drbd-utils-9.0.0.orig/user/v9/drbdadm_postparse.c drbd-utils-9.0.0/user/v9/drbdadm_postparse.c
--- drbd-utils-9.0.0.orig/user/v9/drbdadm_postparse.c 2018-01-18 11:22:01.173513190 +0800
+++ drbd-utils-9.0.0/user/v9/drbdadm_postparse.c 2018-01-18 11:22:09.265471980 +0800
@@ -464,7 +464,7 @@
{
struct d_volume *vol;
- vol = volume_by_vnr(&peer_device->connection->peer->volumes, peer_device->volume->vnr);
+ vol = volume_by_vnr(&peer_device->connection->peer->volumes, peer_device->vnr);
return vol->disk == NULL;
}
@@ -1012,18 +1012,13 @@
_must_have_two_hosts(res, path);
}
-struct peer_device *find_peer_device(struct d_host_info *host, struct connection *conn, int vnr)
+struct peer_device *find_peer_device(struct connection *conn, int vnr)
{
struct peer_device *peer_device;
- struct d_volume *vol;
STAILQ_FOREACH(peer_device, &conn->peer_devices, connection_link) {
- if (peer_device->vnr == vnr) {
- for_each_volume(vol, &host->volumes) {
- if (vol == peer_device->volume)
- return peer_device;
- }
- }
+ if (peer_device->vnr == vnr)
+ return peer_device;
}
return NULL;
@@ -1044,46 +1039,30 @@
if (!some_path)
continue;
- some_host = STAILQ_FIRST(&some_path->hname_address_pairs)->host_info;
-
STAILQ_FOREACH(peer_device, &conn->peer_devices, connection_link) {
-
- vol = volume_by_vnr(&some_host->volumes, peer_device->vnr);
- if (!vol) {
- err("%s:%d: Resource %s: There is a reference to a volume %d that"
- "is not known in this resource\n",
- res->config_file, peer_device->config_line, res->name,
- peer_device->vnr);
- config_valid = 0;
+ STAILQ_FOREACH(ha, &some_path->hname_address_pairs, link) {
+ struct d_host_info *host = ha->host_info;
+ vol = volume_by_vnr(&host->volumes, peer_device->vnr);
+ if (!vol) {
+ err("%s:%d: Resource %s: There is a reference to a volume %d that"
+ "is not known in this resource\n",
+ res->config_file, peer_device->config_line, res->name,
+ peer_device->vnr);
+ config_valid = 0;
+ }
}
- peer_device->volume = vol;
- STAILQ_INSERT_TAIL(&vol->peer_devices, peer_device, volume_link);
}
- /* Take the first path, iterate over hname_address_pairs, take the host_info.
- this is the way to get hold of the two hosts of a connection. */
- STAILQ_FOREACH(ha, &some_path->hname_address_pairs, link) {
- struct d_host_info *host = ha->host_info;
-
- if (!host) {
- err("%s:%d: Resource %s: reference to unknown host '%s'\n",
- res->config_file, ha->config_line, res->name, ha->name);
- config_valid = 0;
+ some_host = STAILQ_FIRST(&some_path->hname_address_pairs)->host_info;
+ for_each_volume(vol, &some_host->volumes) {
+ peer_device = find_peer_device(conn, vol->vnr);
+ if (peer_device)
continue;
- }
-
- for_each_volume(vol, &host->volumes) {
- peer_device = find_peer_device(host, conn, vol->vnr);
- if (peer_device)
- continue;
- peer_device = alloc_peer_device();
- peer_device->vnr = vol->vnr;
- peer_device->implicit = 1;
- peer_device->connection = conn;
- peer_device->volume = vol;
- STAILQ_INSERT_TAIL(&conn->peer_devices, peer_device, connection_link);
- STAILQ_INSERT_TAIL(&vol->peer_devices, peer_device, volume_link);
- }
+ peer_device = alloc_peer_device();
+ peer_device->vnr = vol->vnr;
+ peer_device->implicit = 1;
+ peer_device->connection = conn;
+ STAILQ_INSERT_TAIL(&conn->peer_devices, peer_device, connection_link);
}
}
}
@@ -1275,9 +1254,23 @@
tie the peer_device options from the volume to peer_devices */
for_each_connection(conn, &res->connections) {
struct peer_device *peer_device;
- STAILQ_FOREACH(peer_device, &conn->peer_devices, connection_link) {
+ struct hname_address *ha;
+ struct path *some_path;
+
+ STAILQ_FOREACH(peer_device, &conn->peer_devices, connection_link)
expand_opts(&conn->pd_options, &peer_device->pd_options);
- expand_opts(&peer_device->volume->pd_options, &peer_device->pd_options);
+
+ some_path = STAILQ_FIRST(&conn->paths);
+ if (!some_path)
+ continue;
+
+ STAILQ_FOREACH(ha, &some_path->hname_address_pairs, link) {
+ h = ha->host_info;
+ for_each_volume(vol, &h->volumes) {
+ peer_device = find_peer_device(conn, vol->vnr);
+
+ expand_opts(&vol->pd_options, &peer_device->pd_options);
+ }
}
}
}
diff -Naur drbd-utils-9.0.0.orig/user/v9/drbdadm_usage_cnt.c drbd-utils-9.0.0/user/v9/drbdadm_usage_cnt.c
--- drbd-utils-9.0.0.orig/user/v9/drbdadm_usage_cnt.c 2018-01-18 11:22:01.173513190 +0800
+++ drbd-utils-9.0.0/user/v9/drbdadm_usage_cnt.c 2018-01-18 11:22:09.269471957 +0800
@@ -544,6 +544,18 @@
return NULL;
}
+static bool peer_completely_diskless(struct d_host_info *peer)
+{
+ struct d_volume *vol;
+
+ for_each_volume(vol, &peer->volumes) {
+ if (vol->disk)
+ return false;
+ }
+
+ return true;
+}
+
int adm_create_md(const struct cfg_ctx *ctx)
{
char answer[ANSWER_SIZE];
@@ -562,15 +574,17 @@
if (b_opt_max_peers) {
max_peers_str = ssprintf("%s", b_opt_max_peers->name + strlen(opt_max_peers));
} else {
- struct peer_device *peer_device;
+ struct connection *conn;
int max_peers = 0;
set_peer_in_resource(ctx->res, true);
- STAILQ_FOREACH(peer_device, &ctx->vol->peer_devices, volume_link) {
- if (peer_device->connection->ignore || peer_diskless(peer_device))
+ for_each_connection(conn, &ctx->res->connections) {
+ if (conn->ignore)
continue;
- max_peers++;
+
+ if (!peer_completely_diskless(conn->peer))
+ max_peers++;
}
if (max_peers == 0)