struct config_llog_instance *cfg);
struct lustre_mount_info *server_get_mount(char *name);
int server_put_mount(char *name, struct vfsmount *mnt);
+int server_register_target(struct super_block *sb);
/* mgc_request.c */
int mgc_logname2resid(char *logname, struct ldlm_res_id *res_id);
struct fs_db {
char fd_name[8];
struct list_head fd_list;
+ struct semaphore fd_sem;
void* fd_ost_index_map;
void* fd_mdt_index_map;
__u32 fd_flags;
__u32 fd_gen;
- //FIXME add a semaphore for locking the fs_db (and logs)
};
int mgs_fs_setup(struct obd_device *obd, struct vfsmount *mnt);
/* list of active configuration logs */
struct config_llog_data {
char *cld_logname;
+ struct super_block *cld_sb;
struct ldlm_res_id cld_resid;
struct config_llog_instance cld_cfg;
struct list_head cld_list_chain;
/* Add this log to our list of active logs.
We have one active log per "mount" - client instance or servername.
Each instance may be at a different point in the log. */
-static int config_log_add(char *logname, struct config_llog_instance *cfg)
+static int config_log_add(char *logname, struct config_llog_instance *cfg,
+ struct super_block *sb)
{
struct config_llog_data *cld;
int rc;
GOTO(out, rc = -ENOMEM);
}
strcpy(cld->cld_logname, logname);
+ cld->cld_sb = sb;
cld->cld_cfg = *cfg;
cld->cld_cfg.cfg_last_idx = 0;
if (cfg->cfg_instance != NULL) {
LASSERT(the_mgc);
class_export_get(the_mgc->obd_self_export);
+ /* FIXME sleep a few seconds here to allow the server who caused
+ the lock revocation to finish its setup */
+
+ /* re-send server info every time, in case MGS needs to regen its
+ logs */
+ server_register_target(cld->cld_sb);
rc = mgc_process_log(the_mgc, cld);
class_export_put(the_mgc->obd_self_export);
}
#endif
-/* Get index and add to config llog, depending on flags */
-int mgc_target_add(struct obd_export *exp, struct mgs_target_info *mti)
+/* Send target_add message to MGS */
+static int mgc_target_add(struct obd_export *exp, struct mgs_target_info *mti)
{
struct ptlrpc_request *req;
struct mgs_target_info *req_mti, *rep_mti;
RETURN(rc);
}
-/* Remove from config llog */
-int mgc_target_del(struct obd_export *exp, struct mgs_target_info *mti)
-{
- struct ptlrpc_request *req;
- struct mgs_target_info *req_mti, *rep_mti;
- int size = sizeof(*req_mti);
- int rc;
- ENTRY;
-
- req = ptlrpc_prep_req(class_exp2cliimp(exp), LUSTRE_MGS_VERSION,
- MGS_TARGET_DEL, 1, &size, NULL);
- if (!req)
- RETURN(rc = -ENOMEM);
-
- req_mti = lustre_msg_buf(req->rq_reqmsg, 0, sizeof(*req_mti));
- memcpy(req_mti, mti, sizeof(*req_mti));
-
- rc = ptlrpc_queue_wait(req);
- if (!rc) {
- int index;
- rep_mti = lustre_swab_repbuf(req, 0, sizeof(*rep_mti),
- lustre_swab_mgs_target_info);
- index = rep_mti->mti_stripe_index;
- if (index != mti->mti_stripe_index) {
- CERROR ("OST DEL failed. rc=%d\n", index);
- GOTO (out, rc = -EINVAL);
- }
- CERROR("OST DEL OK.(old index = %d)\n", index);
- }
-out:
- ptlrpc_req_finished(req);
-
- RETURN(rc);
-}
-
int mgc_set_info(struct obd_export *exp, obd_count keylen,
void *key, obd_count vallen, void *val)
{
imp->imp_obd->obd_name,
imp->imp_deactive, imp->imp_invalid,
imp->imp_state);
+ /* can't put this in obdclass, module loop with ptlrpc*/
+ /* remove 'invalid' flag */
ptlrpc_activate_import(imp);
- // lustre_reconnect_mgc(obd);
+ /* reconnect */
ptlrpc_set_import_active(imp, 1);
//ptlrpc_recover_import(imp);
}
int rc, rc2;
ENTRY;
- CDEBUG(D_MGC, "Copy remote log %s\n", logname);
-
/* open local log */
rc = llog_create(lctxt, &local_llh, NULL, logname);
if (rc)
rc2 = llog_close(local_llh);
if (!rc)
rc = rc2;
+
+ CDEBUG(D_MGC, "Copied remote log %s (%d)\n", logname, rc);
RETURN(rc);
}
struct lustre_handle lockh;
struct client_obd *cli = &mgc->u.cli;
struct lvfs_run_ctxt saved;
+ struct lustre_sb_info *lsi = s2lsi(cld->cld_sb);
int rc, rcl, flags = 0, must_pop = 0;
ENTRY;
if (rcl)
CERROR("Can't get cfg lock: %d\n", rcl);
+ lctxt = llog_get_context(mgc, LLOG_CONFIG_ORIG_CTXT);
+
/* Copy the setup log locally if we can. Don't mess around if we're
running an MGS though (logs are already local). */
- /* FIXME What if MGC has a disk set up but a client/another server gets
- updated in the meantime? We'll copy the other log onto the
- currently set-up disk. This won't hurt the current disk, but
- the other server won't get his update written to disk. Next time it
- starts it will update, so this isn't a huge deal... */
- if (cli->cl_mgc_vfsmnt &&
- ((lctxt = llog_get_context(mgc, LLOG_CONFIG_ORIG_CTXT)) != NULL) &&
- (class_name2obd(LUSTRE_MGS_OBDNAME) == NULL)) {
+ if (lctxt && lsi && (lsi->lsi_flags & LSI_SERVER) &&
+ (lsi->lsi_srv_mnt == cli->cl_mgc_vfsmnt) &&
+ !IS_MGS(lsi->lsi_ldd)) {
push_ctxt(&saved, &mgc->obd_lvfs_ctxt, NULL);
must_pop++;
if (rcl == 0)
break;
}
case LCFG_LOV_DEL_OBD:
- /* Unimplemented */
+ /* FIXME */
CERROR("lov_del_obd unimplemented\n");
rc = -ENOSYS;
break;
case LCFG_LOG_START: {
struct config_llog_data *cld;
struct config_llog_instance *cfg;
+ struct super_block *sb;
char *logname = lustre_cfg_string(lcfg, 1);
-
cfg = (struct config_llog_instance *)lustre_cfg_buf(lcfg, 2);
+ sb = *(struct super_block **)lustre_cfg_buf(lcfg, 3);
+
CDEBUG(D_MGC, "parse_log %s from %d\n", logname,
cfg->cfg_last_idx);
/* We're only called through here on the initial mount */
- config_log_add(logname, cfg);
+ config_log_add(logname, cfg, sb);
cld = config_log_get(logname, cfg);
if (IS_ERR(cld))
if (!(mti->mti_flags & (LDD_F_WRITECONF | LDD_F_UPGRADE14 |
LDD_F_NEED_REGISTER))) {
/* We're just here as a startup ping. */
- CDEBUG(D_MGS, "Server %s has started on %s\n", mti->mti_svname,
- obd_export_nid2str(req->rq_export));
+ CDEBUG(D_MGS, "Server %s is running on %s\n",
+ mti->mti_svname, obd_export_nid2str(req->rq_export));
rc = mgs_check_target(obd, mti);
/* above will set appropriate mti flags */
if (!rc)
down(&obd->u.mgs.mgs_log_sem);
if (mti->mti_flags & LDD_F_WRITECONF) {
- CERROR("regen all logs for fs %s\n", mti->mti_fsname);
rc = mgs_erase_logs(obd, mti->mti_fsname);
mti->mti_flags |= LDD_F_NEED_REGISTER;
- /* FIXME regen the rest of the logs too. Special lock revoke
- flag? */
- LCONSOLE_ERROR("All servers must be restarted in order to "
- "regenerate the configuration logs.\n");
-
+ LCONSOLE_WARNING("Logs for fs %s were removed by user request. "
+ "All servers must re-register in order to "
+ "regenerate the client log.\n",
+ mti->mti_fsname);
mti->mti_flags &= ~LDD_F_WRITECONF;
mti->mti_flags |= LDD_F_REWRITE;
}
int rc, rc2;
ENTRY;
+ down(&db->fd_sem);
push_ctxt(&saved, &obd->obd_lvfs_ctxt, NULL);
-
+
rc = llog_create(llog_get_context(obd, LLOG_CONFIG_ORIG_CTXT),
&loghandle, NULL, logname);
if (rc)
out_pop:
pop_ctxt(&saved, &obd->obd_lvfs_ctxt, NULL);
+ up(&db->fd_sem);
RETURN(rc);
}
#define INDEX_MAP_SIZE 4096
+/* caller must hold the mgs->mgs_fs_db_lock */
static struct fs_db *mgs_new_db(struct obd_device *obd, char *fsname)
{
struct mgs_obd *mgs = &obd->u.mgs;
}
strncpy(db->fd_name, fsname, sizeof(db->fd_name));
- //INIT_LIST_HEAD(&db->ost_infos);
-
- spin_lock(&mgs->mgs_fs_db_lock);
+ sema_init(&db->fd_sem, 1);
list_add(&db->fd_list, &mgs->mgs_fs_db_list);
- spin_unlock(&mgs->mgs_fs_db_lock);
RETURN(db);
err:
static void mgs_free_db(struct fs_db *db)
{
+ /* wait for anyone with the sem */
+ down(&db->fd_sem);
list_del(&db->fd_list);
OBD_FREE(db->fd_ost_index_map, INDEX_MAP_SIZE);
OBD_FREE(db->fd_mdt_index_map, INDEX_MAP_SIZE);
static int mgs_find_or_make_db(struct obd_device *obd, char *name,
struct fs_db **dbh)
{
+ struct mgs_obd *mgs = &obd->u.mgs;
struct fs_db *db;
char *cliname;
int rc = 0;
+ spin_lock(&mgs->mgs_fs_db_lock);
db = mgs_find_db(obd, name);
if (db) {
+ spin_unlock(&mgs->mgs_fs_db_lock);
*dbh = db;
return 0;
}
CDEBUG(D_MGS, "Creating new db\n");
db = mgs_new_db(obd, name);
+ spin_unlock(&mgs->mgs_fs_db_lock);
if (!db)
return -ENOMEM;
if (test_bit(mti->mti_stripe_index, imap)) {
LCONSOLE_ERROR("Server %s requested index %d, but that "
- "index is already in use in the %s "
- "filesystem. This server "
- "may have been reformatted, or the "
- "index changed. (To reformat the entire "
- "filesystem, specify 'destroy_fs' "
- "when reformatting a MDT.)\n",
- mti->mti_svname, mti->mti_stripe_index,
- mti->mti_fsname);
- /* FIXME implement destroy_fs! */
+ "index is already in use\n",
+ mti->mti_svname, mti->mti_stripe_index);
RETURN(-EADDRINUSE);
}
return rc;
}
+ down(&db->fd_sem);
if (mti->mti_flags & LDD_F_SV_TYPE_MDT) {
rc = mgs_write_log_mdt(obd, db, mti);
} else if (mti->mti_flags & LDD_F_SV_TYPE_OST) {
CERROR("Unknown target type %#x, can't create log for %s\n",
mti->mti_flags, mti->mti_svname);
}
+ up(&db->fd_sem);
if (!rc)
db->fd_flags &= ~FSDB_EMPTY;
int mgs_erase_logs(struct obd_device *obd, char *fsname)
{
struct mgs_obd *mgs = &obd->u.mgs;
+ static struct fs_db *db;
struct list_head dentry_list;
struct l_linux_dirent *dirent, *n;
int rc, len = strlen(fsname);
ENTRY;
-
+
/* Find all the logs in the CONFIGS directory */
rc = dentry_readdir(obd, mgs->mgs_configs_dir,
mgs->mgs_vfsmnt, &dentry_list);
RETURN(rc);
}
+ /* Delete the fs db */
+ spin_lock(&mgs->mgs_fs_db_lock);
+ db = mgs_find_db(obd, fsname);
+ if (db)
+ mgs_free_db(db);
+ spin_unlock(&mgs->mgs_fs_db_lock);
+
list_for_each_entry_safe(dirent, n, &dentry_list, lld_list) {
list_del(&dirent->lld_list);
if (strncmp(fsname, dirent->lld_name, len) == 0) {
}
OBD_FREE(dirent, sizeof(*dirent));
}
+
RETURN(rc);
}
lustre_cfg_bufs_reset(&bufs, mgc->obd_name);
lustre_cfg_bufs_set_string(&bufs, 1, logname);
lustre_cfg_bufs_set(&bufs, 2, cfg, sizeof(*cfg));
+ lustre_cfg_bufs_set(&bufs, 3, &sb, sizeof(sb));
lcfg = lustre_cfg_new(LCFG_LOG_START, &bufs);
rc = obd_process_config(mgc, sizeof(*lcfg), lcfg);
lustre_cfg_free(lcfg);
strlen(KEY_INIT_RECOV_BACKUP),
KEY_INIT_RECOV_BACKUP,
sizeof(recov_bk), &recov_bk);
-
-#if 0
- /* induces a module loop with ptlrpc */
- if (imp->imp_invalid) {
- /* Resurrect if we previously died */
- CDEBUG(D_MOUNT, "Reactivate %s %d:%d:%d\n",
- imp->imp_obd->obd_name,
- imp->imp_deactive, imp->imp_invalid,
- imp->imp_state);
- ptlrpc_activate_import(imp);
- // lustre_reconnect_mgc(obd);
- ptlrpc_set_import_active(imp, 1);
- //ptlrpc_recover_import(imp);
- }
-#endif
GOTO(out, rc = 0);
}
RETURN(rc);
}
-/* Register an old or new target with the MGS. If needed MGS will construct
- startup logs and assign index */
-static int server_register_target(struct super_block *sb, struct vfsmount *mnt)
+static int server_sb2mti(struct super_block *sb, struct mgs_target_info *mti)
{
- struct lustre_sb_info *lsi = s2lsi(sb);
- struct obd_device *mgc = lsi->lsi_mgc;
+ struct lustre_sb_info *lsi = s2lsi(sb);
struct lustre_disk_data *ldd = lsi->lsi_ldd;
- struct mgs_target_info *mti = NULL;
- lnet_process_id_t id;
+ lnet_process_id_t id;
int i = 0;
- int rc;
ENTRY;
- LASSERT(mgc);
-
- OBD_ALLOC(mti, sizeof(*mti));
- if (!mti) {
+ if (!mti)
RETURN(-ENOMEM);
- }
+ if (!(lsi->lsi_flags & LSI_SERVER))
+ RETURN(-EINVAL);
+
strncpy(mti->mti_fsname, ldd->ldd_fsname,
sizeof(mti->mti_fsname));
strncpy(mti->mti_svname, ldd->ldd_svname,
sizeof(mti->mti_svname));
mti->mti_nid_count = 0;
- while ((rc = LNetGetId(i++, &id)) != -ENOENT) {
+ while (LNetGetId(i++, &id) != -ENOENT) {
if (LNET_NETTYP(LNET_NIDNET(id.nid)) == LOLND)
continue;
mti->mti_nids[mti->mti_nid_count] = id.nid;
mti->mti_stripe_pattern = ldd->ldd_stripe_pattern;
mti->mti_stripe_size = ldd->ldd_stripe_sz;
mti->mti_stripe_offset = ldd->ldd_stripe_offset;
+ RETURN(0);
+}
+
+/* Register an old or new target with the MGS. If needed MGS will construct
+ startup logs and assign index */
+int server_register_target(struct super_block *sb)
+{
+ struct lustre_sb_info *lsi = s2lsi(sb);
+ struct obd_device *mgc = lsi->lsi_mgc;
+ struct lustre_disk_data *ldd = lsi->lsi_ldd;
+ struct mgs_target_info *mti = NULL;
+ int rc;
+ ENTRY;
+
+ LASSERT(mgc);
+
+ if (!(lsi->lsi_flags & LSI_SERVER))
+ RETURN(-EINVAL);
+
+ OBD_ALLOC_PTR(mti);
+ rc = server_sb2mti(sb, mti);
+ if (rc)
+ GOTO(out, rc);
CDEBUG(D_MOUNT, "%sregistration %s, fs=%s, %s, index=%04x, flags=%#x\n",
mti->mti_flags & LDD_F_NEED_REGISTER ? "Initial " : "",
out:
if (mti)
- OBD_FREE(mti, sizeof(*mti));
+ OBD_FREE_PTR(mti);
RETURN(rc);
}
server_mgc_set_fs(lsi->lsi_mgc, sb);
/* Register with MGS */
- rc = server_register_target(sb, mnt);
+ rc = server_register_target(sb);
if (rc && (lsi->lsi_ldd->ldd_flags &
(LDD_F_NEED_INDEX | LDD_F_NEED_REGISTER | LDD_F_UPGRADE14))){
CERROR("Required refistration failed for %s: %d\n",
EXPORT_SYMBOL(lustre_end_log);
EXPORT_SYMBOL(server_get_mount);
EXPORT_SYMBOL(server_put_mount);
+EXPORT_SYMBOL(server_register_target);
+
#include <linux/fs.h> // for BLKGETSIZE64
#include <linux/lustre_disk.h>
#include <lnet/lnetctl.h>
+#include <linux/lustre_ver.h>
#include "obdctl.h"
/* So obd.o will link */
void usage(FILE *out)
{
+ fprintf(out, "%s v"LUSTRE_VERSION_STRING"\n", progname);
fprintf(out, "usage: %s <target types> [options] <device>\n", progname);
fprintf(out,
"\t<device>:block device or file (e.g /dev/sda or /tmp/ost1)\n"
printf("Lustre FS: %s\n", ldd->ldd_fsname);
printf("Mount type: %s\n", MT_STR(ldd));
printf("Flags: %#x\n", ldd->ldd_flags);
- printf(" (%s%s%s%s%s%s)\n",
+ printf(" (%s%s%s%s%s%s%s)\n",
IS_MDT(ldd) ? "MDT ":"",
IS_OST(ldd) ? "OST ":"",
IS_MGS(ldd) ? "MGS ":"",
ldd->ldd_flags & LDD_F_NEED_INDEX ? "needs_index ":"",
ldd->ldd_flags & LDD_F_NEED_REGISTER ? "must_register ":"",
+ ldd->ldd_flags & LDD_F_WRITECONF ? "writeconf ":"",
ldd->ldd_flags & LDD_F_UPGRADE14 ? "upgrade1.4 ":"");
printf("Persistent mount opts: %s\n", ldd->ldd_mount_opts);
printf("MGS nids: ");
{"index", 1, 0, 'i'},
{"timeout", 1, 0, 't'},
{"verbose", 0, 0, 'v'},
- {"writeconf", 1, 0, 'w'},
+ {"writeconf", 0, 0, 'w'},
{0, 0, 0, 0}
};
- char *optstring = "b:C:d:n:f:hI:MGm:k:No:Opqrw:c:s:i:t:v";
+ char *optstring = "b:C:d:n:f:hI:MGm:k:No:Opqrw:c:s:i:t:vw";
char opt;
int longidx;
{
struct mkfs_opts mop;
char *mountopts = NULL;
- char default_mountopts[1024] = "";
+ char always_mountopts[512] = "";
+ char default_mountopts[512] = "";
int ret = 0;
if ((progname = strrchr(argv[0], '/')) != NULL)
switch (mop.mo_ldd.ldd_mount_type) {
case LDD_MT_EXT3:
case LDD_MT_LDISKFS: {
- sprintf(default_mountopts, "errors=remount-ro");
+ sprintf(always_mountopts, "errors=remount-ro");
if (IS_MDT(&mop.mo_ldd) || IS_MGS(&mop.mo_ldd))
- strcat(default_mountopts,
+ strcat(always_mountopts,
",iopen_nopriv,user_xattr");
if ((get_os_version() == 24) && IS_OST(&mop.mo_ldd))
- strcat(default_mountopts, ",asyncdel");
+ strcat(always_mountopts, ",asyncdel");
+#if 0
/* Files created while extents are enabled cannot be read if
mounted with a kernel that doesn't include the CFS patches.*/
if (IS_OST(&mop.mo_ldd) &&
mop.mo_ldd.ldd_mount_type == LDD_MT_LDISKFS) {
strcat(default_mountopts, ",extents,mballoc");
}
-
+#endif
break;
}
case LDD_MT_SMFS: {
mop.mo_flags |= MO_IS_LOOP;
- sprintf(default_mountopts, "type=ext3,dev=%s",
+ sprintf(always_mountopts, "type=ext3,dev=%s",
mop.mo_device);
break;
}
}
}
-#ifndef TUNEFS /* mkfs.lustre */
- if (mountopts)
- /* If user specifies mount opts, assume no defaults */
- strcpy(mop.mo_ldd.ldd_mount_opts, mountopts);
- /* sprintf(mop.mo_ldd.ldd_mount_opts, "%s,%s",
- default_mountopts, mountopts); */
- else
- strcpy(mop.mo_ldd.ldd_mount_opts, default_mountopts);
-#else /* tunefs.lustre - if mountopts are specified, they override
- whatever we had before, so no defaults. */
- if (mountopts)
- strcpy(mop.mo_ldd.ldd_mount_opts, mountopts);
- else if (*mop.mo_ldd.ldd_mount_opts == 0)
- /* no mount opts were set ever, use the defaults. */
- strcpy(mop.mo_ldd.ldd_mount_opts, default_mountopts);
- /* otherwise, use the old. */
+ if (mountopts) {
+ /* If user specifies mount opts, don't use defaults,
+ but always use always_mountopts */
+ sprintf(mop.mo_ldd.ldd_mount_opts, "%s,%s",
+ always_mountopts, mountopts);
+ } else {
+#ifdef TUNEFS
+ if (*mop.mo_ldd.ldd_mount_opts == 0)
+ /* use the defaults unless old opts exist */
#endif
+ {
+ if (default_mountopts[0])
+ sprintf(mop.mo_ldd.ldd_mount_opts, "%s,%s",
+ always_mountopts, default_mountopts);
+ else
+ strcpy(mop.mo_ldd.ldd_mount_opts,
+ always_mountopts);
+ }
+ }
ldd_make_sv_name(&(mop.mo_ldd));
#include <mntent.h>
#include <getopt.h>
#include <sys/utsname.h>
-
+#include <linux/lustre_ver.h>
#include "obdctl.h"
int verbose = 0;
void usage(FILE *out)
{
- fprintf(out, "%s v2.0\n", progname);
+ fprintf(out, "%s v"LUSTRE_VERSION_STRING"\n", progname);
fprintf(out, "usage: %s [-fhnv] [-o <mntopt>] <device> <mountpt>\n",
progname);
fprintf(out,