RETURN(0);
}
-/* should this be in llite? */
-
-int connmgr_iocontrol(long cmd, struct lustre_handle *conn, int len, void *karg,
+int connmgr_iocontrol(long cmd, struct lustre_handle *hdl, int len, void *karg,
void *uarg)
{
- struct obd_device *obd = class_conn2obd(conn);
+ struct ptlrpc_connection *conn = NULL;
+ struct obd_device *obd = class_conn2obd(hdl);
struct recovd_obd *recovd = &obd->u.recovd;
+ struct obd_ioctl_data *data = karg;
+ struct list_head *tmp;
+ int rc = 0;
ENTRY;
- if (cmd == OBD_IOC_RECOVD_NEWCONN) {
- spin_lock(&recovd->recovd_lock);
- /* XXX shaver flag upcall answer */
- wake_up(&recovd->recovd_waitq);
+
+ if (cmd != OBD_IOC_RECOVD_NEWCONN && cmd != OBD_IOC_RECOVD_FAILCONN)
+ RETURN(-EINVAL); /* XXX ENOSYS? */
+
+ /* Find the connection that's been rebuilt or has failed. */
+ spin_lock(&recovd->recovd_lock);
+ list_for_each(tmp, &recovd->recovd_troubled_items) {
+ conn = list_entry(tmp, struct ptlrpc_connection,
+ c_recovd_data.rd_managed_chain);
+
+ LASSERT(conn->c_recovd_data.rd_recovd == recovd); /* sanity */
+
+ if (!strcmp(conn->c_remote_uuid, data->ioc_inlbuf1))
+ break;
+ conn = NULL;
+ }
+
+ if (!conn) {
+ if (cmd == OBD_IOC_RECOVD_NEWCONN)
+ GOTO(out, rc = -EINVAL);
+ /* XXX macroize/inline and share with loop above */
+ list_for_each(tmp, &recovd->recovd_managed_items) {
+ conn = list_entry(tmp, struct ptlrpc_connection,
+ c_recovd_data.rd_managed_chain);
+
+ LASSERT(conn->c_recovd_data.rd_recovd == recovd);
+
+ if (!strcmp(conn->c_remote_uuid, data->ioc_inlbuf1))
+ break;
+ conn = NULL;
+ }
+ if (!conn)
+ GOTO(out, rc = -EINVAL);
+ }
+
+ if (cmd == OBD_IOC_RECOVD_FAILCONN) {
spin_unlock(&recovd->recovd_lock);
- EXIT;
+ recovd_conn_fail(conn);
+ spin_lock(&recovd->recovd_lock);
+
+ /* Jump straight to the "failed" phase of recovery. */
+ conn->c_recovd_data.rd_phase = RD_FAILED;
+ goto out;
}
- return 0;
+
+ /* else (NEWCONN) */
+ if (conn->c_recovd_data.rd_phase != RD_PREPARING)
+ GOTO(out, rc = -EALREADY);
+
+ spin_lock(&conn->c_lock);
+ if (data->ioc_inllen2) {
+ CERROR("conn %p UUID change %s -> %s\n",
+ conn, conn->c_remote_uuid, data->ioc_inlbuf2);
+ strcpy(conn->c_remote_uuid, data->ioc_inlbuf2);
+ } else {
+ CERROR("conn %p UUID %s reconnected\n", conn,
+ conn->c_remote_uuid);
+ }
+ ptlrpc_readdress_connection(conn, conn->c_remote_uuid);
+ spin_unlock(&conn->c_lock);
+
+ conn->c_recovd_data.rd_phase = RD_PREPARED;
+ wake_up(&recovd->recovd_waitq);
+ out:
+ spin_unlock(&recovd->recovd_lock);
+ RETURN(rc);
}
o_setup: connmgr_setup,
o_cleanup: connmgr_cleanup,
o_iocontrol: connmgr_iocontrol,
+ o_connect: class_connect,
+ o_disconnect: class_disconnect
};
static int __init ptlrpc_init(void)