#include <linux/lprocfs_status.h>
#include <linux/lustre_fsfilt.h>
#include <linux/lustre_commit_confd.h>
+#include <linux/lustre_disk.h>
#include "mgs_internal.h"
-static int mgs_postsetup(struct obd_device *obd);
static int mgs_cleanup(struct obd_device *obd);
/* Establish a connection to the MGS.*/
struct obd_uuid *cluuid, struct obd_connect_data *data)
{
struct obd_export *exp;
- struct mgs_export_data *med;
- struct mgs_client_data *mcd;
- int rc, abort_recovery;
+ int rc;
ENTRY;
if (!conn || !obd || !cluuid)
RETURN(-EINVAL);
- /* Check for aborted recovery. */
- spin_lock_bh(&obd->obd_processing_task_lock);
- abort_recovery = obd->obd_abort_recovery;
- spin_unlock_bh(&obd->obd_processing_task_lock);
- if (abort_recovery)
- target_abort_recovery(obd);
-
rc = class_connect(conn, obd, cluuid);
if (rc)
RETURN(rc);
exp = class_conn2export(conn);
LASSERT(exp);
- med = &exp->exp_mgs_data;
if (data != NULL) {
- data->ocd_connect_flags &= MGS_CONNECT_SUPPORTED;
+ data->ocd_connect_flags &= MGMT_CONNECT_SUPPORTED;
exp->exp_connect_flags = data->ocd_connect_flags;
}
- OBD_ALLOC(mcd, sizeof(*mcd));
- if (!mcd) {
- CERROR("mgs: out of memory for client data\n");
- GOTO(out, rc = -ENOMEM);
- }
-
- memcpy(mcd->mcd_uuid, cluuid, sizeof(mcd->mcd_uuid));
- med->med_mcd = mcd;
-#if 0
- /* FIXME: recovery of connection*/
- rc = mgs_client_add(obd, &obd->u.mgs, med, -1);
- GOTO(out, rc);
-#endif
-out:
if (rc) {
- if (mcd) {
- OBD_FREE(mcd, sizeof(*mcd));
- med->med_mcd = NULL;
- }
class_disconnect(exp);
} else {
class_export_put(exp);
RETURN(rc);
}
-static int mgs_init_export(struct obd_export *exp)
-{
- struct mgs_export_data *med = &exp->exp_mgs_data;
-
- INIT_LIST_HEAD(&med->med_open_head);
- spin_lock_init(&med->med_open_lock);
- RETURN(0);
-}
-
static int mgs_disconnect(struct obd_export *exp)
{
unsigned long irqflags;
RETURN(rc);
}
-/* mount the file system (secretly) */
+/* Start the MGS obd */
static int mgs_setup(struct obd_device *obd, obd_count len, void *buf)
{
struct lprocfs_static_vars lvars;
- struct lustre_cfg* lcfg = buf;
- char *options = NULL;
char *ns_name = "MGS";
struct mgs_obd *mgs = &obd->u.mgs;
+ struct lustre_mount_info *lmi;
+ struct lustre_sb_info *lsi;
struct vfsmount *mnt;
- unsigned long page;
int rc = 0;
ENTRY;
- /* setup 1:/dev/loop/0 2:ext3 3:mgs 4:errors=remount-ro,iopen_nopriv*/
+ CDEBUG(D_CONFIG, "Starting MGS\n");
- if (lcfg->lcfg_bufcount < 3)
+ lmi = server_get_mount(obd->obd_name);
+ if (!lmi)
RETURN(rc = -EINVAL);
- if (LUSTRE_CFG_BUFLEN(lcfg, 1) == 0 || LUSTRE_CFG_BUFLEN(lcfg, 2) == 0)
- RETURN(rc = -EINVAL);
-
- obd->obd_fsops = fsfilt_get_ops(lustre_cfg_string(lcfg, 2));
+ mnt = lmi->lmi_mnt;
+ lsi = s2lsi(lmi->lmi_sb);
+ obd->obd_fsops = fsfilt_get_ops(MT_STR(lsi->lsi_ldd));
if (IS_ERR(obd->obd_fsops))
- RETURN(rc = PTR_ERR(obd->obd_fsops));
-
- page = __get_free_page(GFP_KERNEL);
- if (!page)
- RETURN(-ENOMEM);
-
- options = (char *)page;
- memset(options, 0, PAGE_SIZE);
-
- if (LUSTRE_CFG_BUFLEN(lcfg, 4) > 0 && lustre_cfg_buf(lcfg, 4))
- sprintf(options , ",%s", lustre_cfg_string(lcfg, 4));
-
- //FIXME mount was already done in lustre_fill_super,
- //we just need to access it
- mnt = do_kern_mount(lustre_cfg_string(lcfg, 2), 0,
- lustre_cfg_string(lcfg, 1), (void *)options);
- free_page(page);
- if (IS_ERR(mnt)) {
- rc = PTR_ERR(mnt);
- CERROR("do_kern_mount failed: rc = %d\n", rc);
- GOTO(err_ops, rc);
- }
+ GOTO(err_put, rc = PTR_ERR(obd->obd_fsops));
- CDEBUG(D_SUPER, "%s: mnt = %p\n", lustre_cfg_string(lcfg, 1), mnt);
-
- /*namespace for mgs llog */
+ /* namespace for mgs llog */
obd->obd_namespace = ldlm_namespace_new(ns_name, LDLM_NAMESPACE_SERVER);
if (obd->obd_namespace == NULL) {
mgs_cleanup(obd);
- GOTO(err_put, rc = -ENOMEM);
+ GOTO(err_ops, rc = -ENOMEM);
}
LASSERT(!lvfs_check_rdonly(lvfs_sbdev(mnt->mnt_sb)));
GOTO(err_ns, rc);
}
- INIT_LIST_HEAD(&mgs->mgs_open_llogs);
- // INIT_LIST_HEAD(&mgs->mgs_update_llhs);
-
rc = llog_start_commit_thread();
if (rc < 0)
GOTO(err_fs, rc);
- rc = mgs_postsetup(obd);
+ rc = llog_setup(obd, LLOG_CONFIG_ORIG_CTXT, obd, 0, NULL,
+ &llog_lvfs_ops);
if (rc)
GOTO(err_fs, rc);
+ mgs_init_db_list(obd);
+
lprocfs_init_vars(mgs, &lvars);
lprocfs_obd_setup(obd, lvars.obd_vars);
- if (obd->obd_recovering) {
- LCONSOLE_WARN("MGT %s now serving %s, but will be in recovery "
- "until %d %s reconnect, or if no clients "
- "reconnect for %d:%.02d; during that time new "
- "clients will not be allowed to connect. "
- "Recovery progress can be monitored by watching "
- "/proc/fs/lustre/mgs/%s/recovery_status.\n",
- obd->obd_name,
- lustre_cfg_string(lcfg, 1),
- obd->obd_recoverable_clients,
- (obd->obd_recoverable_clients == 1)
- ? "client" : "clients",
- (int)(OBD_RECOVERY_TIMEOUT / HZ) / 60,
- (int)(OBD_RECOVERY_TIMEOUT / HZ) % 60,
- obd->obd_name);
- } else {
- LCONSOLE_INFO("MGT %s now serving %s with recovery %s.\n",
- obd->obd_name,
- lustre_cfg_string(lcfg, 1),
- obd->obd_replayable ? "enabled" : "disabled");
- }
+ LCONSOLE_INFO("MGS %s started\n", obd->obd_name);
ldlm_timeout = 6;
ping_evictor_start();
err_ns:
ldlm_namespace_free(obd->obd_namespace, 0);
obd->obd_namespace = NULL;
-err_put:
- unlock_kernel();
- mntput(mgs->mgs_vfsmnt);
- mgs->mgs_sb = 0;
- lock_kernel();
err_ops:
fsfilt_put_ops(obd->obd_fsops);
+err_put:
+ server_put_mount(obd->obd_name, mgs->mgs_vfsmnt);
+ mgs->mgs_sb = 0;
return rc;
}
-static int mgs_postsetup(struct obd_device *obd)
-{
- int rc = 0;
- ENTRY;
-
- rc = llog_setup(obd, LLOG_CONFIG_ORIG_CTXT, obd, 0, NULL,
- &mgs_llog_lvfs_ops);
- RETURN(rc);
-}
-
static int mgs_precleanup(struct obd_device *obd, int stage)
{
int rc = 0;
ENTRY;
- llog_cleanup(llog_get_context(obd, LLOG_CONFIG_ORIG_CTXT));
- rc = obd_llog_finish(obd, 0);
+ switch (stage) {
+ case OBD_CLEANUP_SELF_EXP:
+ mgs_cleanup_db_list(obd);
+ llog_cleanup(llog_get_context(obd, LLOG_CONFIG_ORIG_CTXT));
+ rc = obd_llog_finish(obd, 0);
+ }
RETURN(rc);
}
{
struct mgs_obd *mgs = &obd->u.mgs;
lvfs_sbdev_type save_dev;
- int must_relock = 0;
ENTRY;
ping_evictor_stop();
RETURN(0);
save_dev = lvfs_sbdev(mgs->mgs_sb);
- lprocfs_obd_cleanup(obd);
+// lprocfs_obd_cleanup(obd);
- mgs_update_server_data(obd, 1);
+ // mgs_update_server_data(obd, 1);
- mgs_fs_cleanup(obd);
-
- if (atomic_read(&obd->u.mgs.mgs_vfsmnt->mnt_count) > 2)
- CERROR("%s: mount busy, mnt_count %d != 2\n", obd->obd_name,
- atomic_read(&obd->u.mgs.mgs_vfsmnt->mnt_count));
+ //mgs_fs_cleanup(obd);
- /* We can only unlock kernel if we are in the context of sys_ioctl,
- otherwise we never called lock_kernel */
- if (kernel_locked()) {
- unlock_kernel();
- must_relock++;
- }
-
- mntput(mgs->mgs_vfsmnt);
+ server_put_mount(obd->obd_name, mgs->mgs_vfsmnt);
mgs->mgs_sb = NULL;
ldlm_namespace_free(obd->obd_namespace, obd->obd_force);
lvfs_clear_rdonly(save_dev);
- if (must_relock)
- lock_kernel();
-
fsfilt_put_ops(obd->obd_fsops);
- LCONSOLE_INFO("MGT %s has stopped.\n", obd->obd_name);
+ LCONSOLE_INFO("MGS %s has stopped.\n", obd->obd_name);
RETURN(0);
}
+static int mgs_handle_target_add(struct ptlrpc_request *req)
+{
+ struct obd_device *obd = req->rq_export->exp_obd;
+ struct mgmt_target_info *req_mti, *mti, *rep_mti;
+ int rep_size = sizeof(*mti);
+ int rc;
+ ENTRY;
+
+ OBD_ALLOC(mti, sizeof(*mti));
+ if (!mti)
+ GOTO(out, rc = -ENOMEM);
+ req_mti = lustre_swab_reqbuf(req, 0, sizeof(*mti),
+ lustre_swab_mgmt_target_info);
+ memcpy(mti, req_mti, sizeof(*mti));
+
+ /* set the new target index if needed */
+ if (mti->mti_flags & LDD_F_NEED_INDEX) {
+ rc = mgs_set_next_index(obd, mti);
+ if (rc) {
+ CERROR("Can't get index (%d)\n", rc);
+ GOTO(out, rc);
+ }
+ }
+
+ /* create the log for the new target
+ and update the client/mdt logs */
+ rc = mgs_write_log_target(obd, mti);
+ if (rc) {
+ CERROR("Failed to write %s log (%d)\n",
+ mti->mti_svname, rc);
+ GOTO(out, rc);
+ }
+
+out:
+ lustre_pack_reply(req, 1, &rep_size, NULL);
+ /* send back the whole mti in the reply */
+ rep_mti = lustre_msg_buf(req->rq_repmsg, 0, sizeof(*rep_mti));
+ memcpy(rep_mti, mti, sizeof(*rep_mti));
+ rep_mti->mti_rc = rc;
+ RETURN(rc);
+}
+
int mgs_handle(struct ptlrpc_request *req)
{
- int fail = OBD_FAIL_MGS_ALL_REPLY_NET;
+ int fail = OBD_FAIL_MGMT_ALL_REPLY_NET;
int rc = 0;
- struct mgs_obd *mgs = NULL; /* quell gcc overwarning */
- struct obd_device *obd = NULL;
ENTRY;
+
+ CERROR("MGS handle\n");
- OBD_FAIL_RETURN(OBD_FAIL_MGS_ALL_REQUEST_NET | OBD_FAIL_ONCE, 0);
+ OBD_FAIL_RETURN(OBD_FAIL_MGMT_ALL_REQUEST_NET | OBD_FAIL_ONCE, 0);
LASSERT(current->journal_info == NULL);
- /* XXX identical to MDS */
- if (req->rq_reqmsg->opc != MGS_CONNECT) {
- struct mgs_export_data *med;
- int abort_recovery;
-
+ if (req->rq_reqmsg->opc != MGMT_CONNECT) {
if (req->rq_export == NULL) {
CERROR("lustre_mgs: operation %d on unconnected MGS\n",
req->rq_reqmsg->opc);
req->rq_status = -ENOTCONN;
GOTO(out, rc = -ENOTCONN);
}
-
- med = &req->rq_export->exp_mgs_data;
- obd = req->rq_export->exp_obd;
- mgs = &obd->u.mgs;
-
- /* sanity check: if the xid matches, the request must
- * be marked as a resent or replayed */
- if (req->rq_xid == med->med_mcd->mcd_last_xid)
- LASSERTF(lustre_msg_get_flags(req->rq_reqmsg) &
- (MSG_RESENT | MSG_REPLAY),
- "rq_xid "LPU64" matches last_xid, "
- "expected RESENT flag\n",
- req->rq_xid);
- /* else: note the opposite is not always true; a
- * RESENT req after a failover will usually not match
- * the last_xid, since it was likely never
- * committed. A REPLAYed request will almost never
- * match the last xid, however it could for a
- * committed, but still retained, open. */
-
- /* Check for aborted recovery. */
- spin_lock_bh(&obd->obd_processing_task_lock);
- abort_recovery = obd->obd_abort_recovery;
- spin_unlock_bh(&obd->obd_processing_task_lock);
- if (abort_recovery) {
- target_abort_recovery(obd);
- }
}
switch (req->rq_reqmsg->opc) {
- case MGS_CONNECT:
+ case MGMT_CONNECT:
DEBUG_REQ(D_INODE, req, "connect");
- OBD_FAIL_RETURN(OBD_FAIL_MGS_CONNECT_NET, 0);
+ OBD_FAIL_RETURN(OBD_FAIL_MGMT_CONNECT_NET, 0);
rc = target_handle_connect(req, mgs_handle);
- if (!rc) {
- /* Now that we have an export, set mgs. */
- obd = req->rq_export->exp_obd;
- mgs = mgs_req2mgs(req);
- }
break;
-
- case MGS_DISCONNECT:
+ case MGMT_DISCONNECT:
DEBUG_REQ(D_INODE, req, "disconnect");
- OBD_FAIL_RETURN(OBD_FAIL_MGS_DISCONNECT_NET, 0);
+ OBD_FAIL_RETURN(OBD_FAIL_MGMT_DISCONNECT_NET, 0);
rc = target_handle_disconnect(req);
req->rq_status = rc; /* superfluous? */
break;
+ case MGMT_TARGET_ADD:
+ CDEBUG(D_INODE, "target add\n");
+ rc = mgs_handle_target_add(req);
+ break;
+ case MGMT_TARGET_DEL:
+ CDEBUG(D_INODE, "target del\n");
+ //rc = mgs_handle_target_del(req);
+ break;
+
case LDLM_ENQUEUE:
DEBUG_REQ(D_INODE, req, "enqueue");
OBD_FAIL_RETURN(OBD_FAIL_LDLM_ENQUEUE, 0);
LASSERT(current->journal_info == NULL);
- /* If we're DISCONNECTing, the mgs_export_data is already freed */
- if (!rc && req->rq_reqmsg->opc != MGS_DISCONNECT) {
- struct mgs_export_data *med = &req->rq_export->exp_mgs_data;
- req->rq_repmsg->last_xid =
- le64_to_cpu(med->med_mcd->mcd_last_xid);
-
- target_committed_to_req(req);
- }
-
- EXIT;
out:
-
- if (lustre_msg_get_flags(req->rq_reqmsg) & MSG_LAST_REPLAY) {
- if (obd && obd->obd_recovering) {
- DEBUG_REQ(D_HA, req, "LAST_REPLAY, queuing reply");
- return target_queue_final_reply(req, rc);
- }
- /* Lost a race with recovery; let the error path DTRT. */
- rc = req->rq_status = -ENOTCONN;
- }
-
target_send_reply(req, rc, fail);
- return 0;
+ RETURN(0);
}
static int mgt_setup(struct obd_device *obd, obd_count len, void *buf)
int rc = 0;
ENTRY;
- lprocfs_init_vars(mgt, &lvars);
- lprocfs_obd_setup(obd, lvars.obd_vars);
+ lprocfs_init_vars(mgt, &lvars);
+ lprocfs_obd_setup(obd, lvars.obd_vars);
mgs->mgs_service =
ptlrpc_init_svc(MGS_NBUFS, MGS_BUFSIZE, MGS_MAXREQSIZE,
GOTO(err_lprocfs, rc = -ENOMEM);
}
- rc = ptlrpc_start_n_threads(obd, mgs->mgs_service, MGT_NUM_THREADS,
- "ll_mgt");
+ rc = ptlrpc_start_threads(obd, mgs->mgs_service, "ll_mgt");
if (rc)
GOTO(err_thread, rc);
static struct obd_ops mgs_obd_ops = {
.o_owner = THIS_MODULE,
.o_connect = mgs_connect,
- .o_init_export = mgs_init_export,
.o_disconnect = mgs_disconnect,
.o_setup = mgs_setup,
.o_precleanup = mgs_precleanup,