RETURN(0);
}
-/* should this be in llite? */
-
int connmgr_iocontrol(long cmd, struct lustre_handle *hdl, int len, void *karg,
void *uarg)
{
struct obd_device *obd = class_conn2obd(hdl);
struct recovd_obd *recovd = &obd->u.recovd;
struct obd_ioctl_data *data = karg;
-#if 0 && PARALLEL_RECOVERY
struct list_head *tmp;
-#endif
+ int rc = 0;
ENTRY;
- if (cmd != OBD_IOC_RECOVD_NEWCONN)
- RETURN(0);
+ if (cmd != OBD_IOC_RECOVD_NEWCONN && cmd != OBD_IOC_RECOVD_FAILCONN)
+ RETURN(-EINVAL); /* XXX ENOSYS? */
- /* Find the connection that's been rebuilt. */
+ /* Find the connection that's been rebuilt or has failed. */
spin_lock(&recovd->recovd_lock);
-#if 0 && PARALLEL_RECOVERY
list_for_each(tmp, &recovd->recovd_troubled_items) {
conn = list_entry(tmp, struct ptlrpc_connection,
c_recovd_data.rd_managed_chain);
break;
conn = NULL;
}
-#endif
- if (!recovd->recovd_current_rd) {
- spin_unlock(&recovd->recovd_lock);
- LBUG();
- }
- conn = class_rd2conn(recovd->recovd_current_rd);
- spin_unlock(&recovd->recovd_lock);
+ 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);
+ }
- spin_lock(&conn->c_lock);
+ if (cmd == OBD_IOC_RECOVD_FAILCONN) {
+ spin_unlock(&recovd->recovd_lock);
+ recovd_conn_fail(conn);
+ spin_lock(&recovd->recovd_lock);
- if (strcmp(conn->c_remote_uuid, data->ioc_inlbuf1)) {
- CERROR("NEWCONN for %s: currently recovering %s\n",
- data->ioc_inlbuf1, conn->c_remote_uuid);
- spin_unlock(&conn->c_lock);
- RETURN(-EINVAL);
+ /* Jump straight to the "failed" phase of recovery. */
+ conn->c_recovd_data.rd_phase = RD_FAILED;
+ goto out;
}
+ /* 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);
conn->c_remote_uuid);
}
ptlrpc_readdress_connection(conn, conn->c_remote_uuid);
+ spin_unlock(&conn->c_lock);
- spin_lock(&recovd->recovd_lock);
-#if 0 && PARALLEL_RECOVERY
- if (conn->c_recovd_data->rd_state != RECOVD_PREPARING)
- LBUG();
- conn->c_recovd_data->rd_state = RECOVD_PREPARED;
-#endif
- if (recovd->recovd_phase != RECOVD_PREPARING ||
- recovd->recovd_next_phase != RECOVD_PREPARED ||
- recovd->recovd_current_rd != &conn->c_recovd_data) {
- LBUG();
- }
- recovd->recovd_phase = RECOVD_PREPARED;
+ conn->c_recovd_data.rd_phase = RD_PREPARED;
wake_up(&recovd->recovd_waitq);
+ out:
spin_unlock(&recovd->recovd_lock);
- spin_unlock(&conn->c_lock);
- RETURN(0);
+ RETURN(rc);
}