Commit 6b75dced authored by Philipp Reisner's avatar Philipp Reisner

drbd: conn_khelper() for user mode callbacks for connections

Signed-off-by: default avatarPhilipp Reisner <philipp.reisner@linbit.com>
Signed-off-by: default avatarLars Ellenberg <lars.ellenberg@linbit.com>
parent 047e95e2
...@@ -252,43 +252,47 @@ static int drbd_adm_finish(struct genl_info *info, int retcode) ...@@ -252,43 +252,47 @@ static int drbd_adm_finish(struct genl_info *info, int retcode)
return 0; return 0;
} }
int drbd_khelper(struct drbd_conf *mdev, char *cmd) static void setup_khelper_env(struct drbd_tconn *tconn, char **envp)
{ {
char *envp[] = { "HOME=/", char *afs;
"TERM=linux",
"PATH=/sbin:/usr/sbin:/bin:/usr/bin",
NULL, /* Will be set to address family */
NULL, /* Will be set to address */
NULL };
char mb[12], af[20], ad[60], *afs;
char *argv[] = {usermode_helper, cmd, mb, NULL };
struct sib_info sib;
int ret;
snprintf(mb, 12, "minor-%d", mdev_to_minor(mdev));
if (get_net_conf(mdev->tconn)) { if (get_net_conf(tconn)) {
switch (((struct sockaddr *)mdev->tconn->net_conf->peer_addr)->sa_family) { switch (((struct sockaddr *)tconn->net_conf->peer_addr)->sa_family) {
case AF_INET6: case AF_INET6:
afs = "ipv6"; afs = "ipv6";
snprintf(ad, 60, "DRBD_PEER_ADDRESS=%pI6", snprintf(envp[4], 60, "DRBD_PEER_ADDRESS=%pI6",
&((struct sockaddr_in6 *)mdev->tconn->net_conf->peer_addr)->sin6_addr); &((struct sockaddr_in6 *)tconn->net_conf->peer_addr)->sin6_addr);
break; break;
case AF_INET: case AF_INET:
afs = "ipv4"; afs = "ipv4";
snprintf(ad, 60, "DRBD_PEER_ADDRESS=%pI4", snprintf(envp[4], 60, "DRBD_PEER_ADDRESS=%pI4",
&((struct sockaddr_in *)mdev->tconn->net_conf->peer_addr)->sin_addr); &((struct sockaddr_in *)tconn->net_conf->peer_addr)->sin_addr);
break; break;
default: default:
afs = "ssocks"; afs = "ssocks";
snprintf(ad, 60, "DRBD_PEER_ADDRESS=%pI4", snprintf(envp[4], 60, "DRBD_PEER_ADDRESS=%pI4",
&((struct sockaddr_in *)mdev->tconn->net_conf->peer_addr)->sin_addr); &((struct sockaddr_in *)tconn->net_conf->peer_addr)->sin_addr);
} }
snprintf(af, 20, "DRBD_PEER_AF=%s", afs); snprintf(envp[3], 20, "DRBD_PEER_AF=%s", afs);
envp[3]=af; put_net_conf(tconn);
envp[4]=ad;
put_net_conf(mdev->tconn);
} }
}
int drbd_khelper(struct drbd_conf *mdev, char *cmd)
{
char *envp[] = { "HOME=/",
"TERM=linux",
"PATH=/sbin:/usr/sbin:/bin:/usr/bin",
(char[20]) { }, /* address family */
(char[60]) { }, /* address */
NULL };
char mb[12];
char *argv[] = {usermode_helper, cmd, mb, NULL };
struct sib_info sib;
int ret;
snprintf(mb, 12, "minor-%d", mdev_to_minor(mdev));
setup_khelper_env(mdev->tconn, envp);
/* The helper may take some time. /* The helper may take some time.
* write out any unsynced meta data changes now */ * write out any unsynced meta data changes now */
...@@ -317,6 +321,49 @@ int drbd_khelper(struct drbd_conf *mdev, char *cmd) ...@@ -317,6 +321,49 @@ int drbd_khelper(struct drbd_conf *mdev, char *cmd)
return ret; return ret;
} }
static void conn_md_sync(struct drbd_tconn *tconn)
{
struct drbd_conf *mdev;
int minor;
idr_for_each_entry(&tconn->volumes, mdev, minor)
drbd_md_sync(mdev);
}
int conn_khelper(struct drbd_tconn *tconn, char *cmd)
{
char *envp[] = { "HOME=/",
"TERM=linux",
"PATH=/sbin:/usr/sbin:/bin:/usr/bin",
(char[20]) { }, /* address family */
(char[60]) { }, /* address */
NULL };
char *argv[] = {usermode_helper, cmd, tconn->name, NULL };
int ret;
setup_khelper_env(tconn, envp);
conn_md_sync(tconn);
conn_info(tconn, "helper command: %s %s %s\n", usermode_helper, cmd, tconn->name);
/* TODO: conn_bcast_event() ?? */
ret = call_usermodehelper(usermode_helper, argv, envp, 1);
if (ret)
conn_warn(tconn, "helper command: %s %s %s exit code %u (0x%x)\n",
usermode_helper, cmd, tconn->name,
(ret >> 8) & 0xff, ret);
else
conn_info(tconn, "helper command: %s %s %s exit code %u (0x%x)\n",
usermode_helper, cmd, tconn->name,
(ret >> 8) & 0xff, ret);
/* TODO: conn_bcast_event() ?? */
if (ret < 0) /* Ignore any ERRNOs we got. */
ret = 0;
return ret;
}
enum drbd_disk_state drbd_try_outdate_peer(struct drbd_conf *mdev) enum drbd_disk_state drbd_try_outdate_peer(struct drbd_conf *mdev)
{ {
char *ex_to_string; char *ex_to_string;
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment