* Copyright (c) 2007, 2010, Oracle and/or its affiliates. All rights reserved.
* Use is subject to license terms.
*
- * Copyright (c) 2011, 2012, Intel Corporation.
+ * Copyright (c) 2011, 2013, Intel Corporation.
*/
/*
* This file is part of Lustre, http://www.lustre.org/
#define PRINT_CMD CDEBUG
#include <obd.h>
-#include <lvfs.h>
-#include <lustre_fsfilt.h>
#include <obd_class.h>
#include <lustre/lustre_user.h>
#include <linux/version.h>
GOTO(out_free, rc);
/* Re-using an existing MGC */
- cfs_atomic_inc(&obd->u.cli.cl_mgc_refcount);
+ atomic_inc(&obd->u.cli.cl_mgc_refcount);
/* IR compatibility check, only for clients */
if (lmd_is_client(lsi->lsi_lmd)) {
sprintf(niduuid, "%s_%x", mgcname, i);
if (IS_SERVER(lsi)) {
ptr = lsi->lsi_lmd->lmd_mgs;
+ CDEBUG(D_MOUNT, "mgs nids %s.\n", ptr);
if (IS_MGS(lsi)) {
- /* Use local nids (including LO) */
- lnet_process_id_t id;
- while ((rc = LNetGetId(i++, &id)) != -ENOENT) {
- rc = do_lcfg(mgcname, id.nid,
- LCFG_ADD_UUID, niduuid, 0,0,0);
- }
- } else {
- /* Use mgsnode= nids */
+ /* Use local nids (including LO) */
+ lnet_process_id_t id;
+ while ((rc = LNetGetId(i++, &id)) != -ENOENT) {
+ rc = do_lcfg(mgcname, id.nid, LCFG_ADD_UUID,
+ niduuid, 0, 0, 0);
+ }
+ } else {
+ /* Use mgsnode= nids */
/* mount -o mgsnode=nid */
if (lsi->lsi_lmd->lmd_mgs) {
ptr = lsi->lsi_lmd->lmd_mgs;
} else if (class_find_param(ptr, PARAM_MGSNODE,
&ptr) != 0) {
- CERROR("No MGS nids given.\n");
- GOTO(out_free, rc = -EINVAL);
- }
- while (class_parse_nid(ptr, &nid, &ptr) == 0) {
- rc = do_lcfg(mgcname, nid,
- LCFG_ADD_UUID, niduuid, 0,0,0);
- i++;
- }
- }
+ CERROR("No MGS nids given.\n");
+ GOTO(out_free, rc = -EINVAL);
+ }
+ /*
+ * LU-3829.
+ * Here we only take the first mgsnid as its primary
+ * serving mgs node, the rest mgsnid will be taken as
+ * failover mgs node, otherwise they would be takens
+ * as multiple nids of a single mgs node.
+ */
+ while (class_parse_nid(ptr, &nid, &ptr) == 0) {
+ rc = do_lcfg(mgcname, nid, LCFG_ADD_UUID,
+ niduuid, 0, 0, 0);
+ if (rc == 0) {
+ i = 1;
+ break;
+ }
+ }
+ }
} else { /* client */
/* Use nids from mount line: uml1,1@elan:uml2,2@elan:/lustre */
ptr = lsi->lsi_lmd->lmd_dev;
while (class_parse_nid(ptr, &nid, &ptr) == 0) {
- rc = do_lcfg(mgcname, nid,
- LCFG_ADD_UUID, niduuid, 0,0,0);
- i++;
+ rc = do_lcfg(mgcname, nid, LCFG_ADD_UUID,
+ niduuid, 0, 0, 0);
+ if (rc == 0)
+ ++i;
/* Stop at the first failover nid */
if (*ptr == ':')
break;
i = 1;
while (ptr && ((*ptr == ':' ||
class_find_param(ptr, PARAM_MGSNODE, &ptr) == 0))) {
- /* New failover node */
- sprintf(niduuid, "%s_%x", mgcname, i);
- j = 0;
+ /* New failover node */
+ sprintf(niduuid, "%s_%x", mgcname, i);
+ j = 0;
while (class_parse_nid_quiet(ptr, &nid, &ptr) == 0) {
- j++;
- rc = do_lcfg(mgcname, nid,
- LCFG_ADD_UUID, niduuid, 0,0,0);
- if (*ptr == ':')
- break;
- }
- if (j > 0) {
- rc = do_lcfg(mgcname, 0, LCFG_ADD_CONN,
- niduuid, 0, 0, 0);
- i++;
+ rc = do_lcfg(mgcname, nid, LCFG_ADD_UUID,
+ niduuid, 0, 0, 0);
+ if (rc == 0)
+ ++j;
+ if (*ptr == ':')
+ break;
+ }
+ if (j > 0) {
+ rc = do_lcfg(mgcname, 0, LCFG_ADD_CONN,
+ niduuid, 0, 0, 0);
+ if (rc == 0)
+ ++i;
} else {
/* at ":/fsname" */
break;
/* Keep a refcount of servers/clients who started with "mount",
so we know when we can get rid of the mgc. */
- cfs_atomic_set(&obd->u.cli.cl_mgc_refcount, 1);
+ atomic_set(&obd->u.cli.cl_mgc_refcount, 1);
/* Try all connections, but only once. */
recov_bk = 1;
lsi->lsi_mgc = NULL;
mutex_lock(&mgc_start_lock);
- LASSERT(cfs_atomic_read(&obd->u.cli.cl_mgc_refcount) > 0);
- if (!cfs_atomic_dec_and_test(&obd->u.cli.cl_mgc_refcount)) {
+ LASSERT(atomic_read(&obd->u.cli.cl_mgc_refcount) > 0);
+ if (!atomic_dec_and_test(&obd->u.cli.cl_mgc_refcount)) {
/* This is not fatal, every client that stops
will call in here. */
CDEBUG(D_MOUNT, "mgc still has %d references.\n",
- cfs_atomic_read(&obd->u.cli.cl_mgc_refcount));
+ atomic_read(&obd->u.cli.cl_mgc_refcount));
GOTO(out, rc = -EBUSY);
}
lsi->lsi_lmd->lmd_recovery_time_hard = 0;
s2lsi_nocast(sb) = lsi;
/* we take 1 extra ref for our setup */
- cfs_atomic_set(&lsi->lsi_mounts, 1);
+ atomic_set(&lsi->lsi_mounts, 1);
/* Default umount style */
lsi->lsi_flags = LSI_UMOUNT_FAILOVER;
CDEBUG(D_MOUNT, "Freeing lsi %p\n", lsi);
/* someone didn't call server_put_mount. */
- LASSERT(cfs_atomic_read(&lsi->lsi_mounts) == 0);
+ LASSERT(atomic_read(&lsi->lsi_mounts) == 0);
if (lsi->lsi_lmd != NULL) {
if (lsi->lsi_lmd->lmd_dev != NULL)
LASSERT(lsi != NULL);
- CDEBUG(D_MOUNT, "put %p %d\n", sb, cfs_atomic_read(&lsi->lsi_mounts));
- if (cfs_atomic_dec_and_test(&lsi->lsi_mounts)) {
+ CDEBUG(D_MOUNT, "put %p %d\n", sb, atomic_read(&lsi->lsi_mounts));
+ if (atomic_dec_and_test(&lsi->lsi_mounts)) {
if (IS_SERVER(lsi) && lsi->lsi_osd_exp) {
+ lu_device_put(&lsi->lsi_dt_dev->dd_lu_dev);
+ lsi->lsi_osd_exp->exp_obd->obd_lvfs_ctxt.dt = NULL;
+ lsi->lsi_dt_dev = NULL;
obd_disconnect(lsi->lsi_osd_exp);
/* wait till OSD is gone */
obd_zombie_barrier();
RETURN(0);
}
+/*** SERVER NAME ***
+ * <FSNAME><SEPERATOR><TYPE><INDEX>
+ * FSNAME is between 1 and 8 characters (inclusive).
+ * Excluded characters are '/' and ':'
+ * SEPERATOR is either ':' or '-'
+ * TYPE: "OST", "MDT", etc.
+ * INDEX: Hex representation of the index
+ */
+
/** Get the fsname ("lustre") from the server name ("lustre-OST003F").
* @param [in] svname server name including type and index
* @param [out] fsname Buffer to copy filesystem name prefix into.
*/
int server_name2fsname(const char *svname, char *fsname, const char **endptr)
{
- const char *dash = strrchr(svname, '-');
- if (!dash) {
- dash = strrchr(svname, ':');
- if (!dash)
- return -EINVAL;
- }
+ const char *dash;
- /* interpret <fsname>-MDTXXXXX-mdc as mdt, the better way is to pass
- * in the fsname, then determine the server index */
- if (!strcmp(LUSTRE_MDC_NAME, dash + 1)) {
- dash--;
- for (; dash > svname && *dash != '-' && *dash != ':'; dash--)
- ;
- if (dash == svname)
- return -EINVAL;
- }
+ dash = svname + strnlen(svname, 8); /* max fsname length is 8 */
+ for (; dash > svname && *dash != '-' && *dash != ':'; dash--)
+ ;
+ if (dash == svname)
+ return -EINVAL;
if (fsname != NULL) {
strncpy(fsname, svname, dash - svname);
size_t svsize)
{
int rc;
- const const char *dash;
+ const char *dash;
/* We use server_name2fsname() just for parsing */
rc = server_name2fsname(label, NULL, &dash);
if (rc != 0)
return rc;
- if (*dash != '-')
- return -1;
+ if (endptr != NULL)
+ *endptr = dash;
if (strlcpy(svname, dash + 1, svsize) >= svsize)
return -E2BIG;
}
EXPORT_SYMBOL(server_name2svname);
-
-/* Get the index from the obd name.
- rc = server type, or
- rc < 0 on error
- if endptr isn't NULL it is set to end of name */
-int server_name2index(const char *svname, __u32 *idx, const char **endptr)
+/**
+ * check server name is OST.
+ **/
+int server_name_is_ost(const char *svname)
{
- unsigned long index;
- int rc;
const char *dash;
+ int rc;
/* We use server_name2fsname() just for parsing */
rc = server_name2fsname(svname, NULL, &dash);
if (rc != 0)
return rc;
- if (*dash != '-')
- return -EINVAL;
-
dash++;
+ if (strncmp(dash, "OST", 3) == 0)
+ return 1;
+ return 0;
+}
+EXPORT_SYMBOL(server_name_is_ost);
+
+/**
+ * Get the index from the target name MDTXXXX/OSTXXXX
+ * rc = server type, or rc < 0 on error
+ **/
+int target_name2index(const char *tgtname, __u32 *idx, const char **endptr)
+{
+ const char *dash = tgtname;
+ unsigned long index;
+ int rc;
+
if (strncmp(dash, "MDT", 3) == 0)
rc = LDD_F_SV_TYPE_MDT;
else if (strncmp(dash, "OST", 3) == 0)
dash += 3;
- if (strcmp(dash, "all") == 0)
+ if (strncmp(dash, "all", 3) == 0) {
+ if (endptr != NULL)
+ *endptr = dash + 3;
return rc | LDD_F_SV_ALL;
+ }
index = simple_strtoul(dash, (char **)endptr, 16);
- *idx = index;
+ if (idx != NULL)
+ *idx = index;
+ return rc;
+}
+EXPORT_SYMBOL(target_name2index);
+
+/* Get the index from the obd name.
+ rc = server type, or
+ rc < 0 on error
+ if endptr isn't NULL it is set to end of name */
+int server_name2index(const char *svname, __u32 *idx, const char **endptr)
+{
+ const char *dash;
+ int rc;
+
+ /* We use server_name2fsname() just for parsing */
+ rc = server_name2fsname(svname, NULL, &dash);
+ if (rc != 0)
+ return rc;
+
+ dash++;
+ rc = target_name2index(dash, idx, endptr);
+ if (rc < 0)
+ return rc;
+
+ /* Account for -mdc after index that is possible when specifying mdt */
+ if (endptr != NULL && strncmp(LUSTRE_MDC_NAME, *endptr + 1,
+ sizeof(LUSTRE_MDC_NAME)-1) == 0)
+ *endptr += sizeof(LUSTRE_MDC_NAME);
return rc;
}
static int lmd_make_exclusion(struct lustre_mount_data *lmd, const char *ptr)
{
const char *s1 = ptr, *s2;
- __u32 index, *exclude_list;
- int rc = 0, devmax;
- ENTRY;
-
- /* The shortest an ost name can be is 8 chars: -OST0000.
- We don't actually know the fsname at this time, so in fact
- a user could specify any fsname. */
- devmax = strlen(ptr) / 8 + 1;
-
- /* temp storage until we figure out how many we have */
- OBD_ALLOC(exclude_list, sizeof(index) * devmax);
- if (!exclude_list)
- RETURN(-ENOMEM);
+ __u32 index, *exclude_list;
+ int rc = 0, devmax;
+ ENTRY;
+
+ /* The shortest an ost name can be is 8 chars: -OST0000.
+ We don't actually know the fsname at this time, so in fact
+ a user could specify any fsname. */
+ devmax = strlen(ptr) / 8 + 1;
+
+ /* temp storage until we figure out how many we have */
+ OBD_ALLOC(exclude_list, sizeof(index) * devmax);
+ if (!exclude_list)
+ RETURN(-ENOMEM);
- /* we enter this fn pointing at the '=' */
- while (*s1 && *s1 != ' ' && *s1 != ',') {
- s1++;
- rc = server_name2index(s1, &index, &s2);
- if (rc < 0) {
- CERROR("Can't parse server name '%s'\n", s1);
- break;
- }
- if (rc == LDD_F_SV_TYPE_OST)
- exclude_list[lmd->lmd_exclude_count++] = index;
- else
- CDEBUG(D_MOUNT, "ignoring exclude %.7s\n", s1);
- s1 = s2;
- /* now we are pointing at ':' (next exclude)
- or ',' (end of excludes) */
- if (lmd->lmd_exclude_count >= devmax)
- break;
- }
- if (rc >= 0) /* non-err */
- rc = 0;
-
- if (lmd->lmd_exclude_count) {
- /* permanent, freed in lustre_free_lsi */
- OBD_ALLOC(lmd->lmd_exclude, sizeof(index) *
- lmd->lmd_exclude_count);
- if (lmd->lmd_exclude) {
- memcpy(lmd->lmd_exclude, exclude_list,
- sizeof(index) * lmd->lmd_exclude_count);
- } else {
- rc = -ENOMEM;
- lmd->lmd_exclude_count = 0;
- }
- }
- OBD_FREE(exclude_list, sizeof(index) * devmax);
- RETURN(rc);
+ /* we enter this fn pointing at the '=' */
+ while (*s1 && *s1 != ' ' && *s1 != ',') {
+ s1++;
+ rc = server_name2index(s1, &index, &s2);
+ if (rc < 0) {
+ CERROR("Can't parse server name '%s': rc = %d\n",
+ s1, rc);
+ break;
+ }
+ if (rc == LDD_F_SV_TYPE_OST)
+ exclude_list[lmd->lmd_exclude_count++] = index;
+ else
+ CDEBUG(D_MOUNT, "ignoring exclude %.*s: type = %#x\n",
+ (uint)(s2-s1), s1, rc);
+ s1 = s2;
+ /* now we are pointing at ':' (next exclude)
+ or ',' (end of excludes) */
+ if (lmd->lmd_exclude_count >= devmax)
+ break;
+ }
+ if (rc >= 0) /* non-err */
+ rc = 0;
+
+ if (lmd->lmd_exclude_count) {
+ /* permanent, freed in lustre_free_lsi */
+ OBD_ALLOC(lmd->lmd_exclude, sizeof(index) *
+ lmd->lmd_exclude_count);
+ if (lmd->lmd_exclude) {
+ memcpy(lmd->lmd_exclude, exclude_list,
+ sizeof(index) * lmd->lmd_exclude_count);
+ } else {
+ rc = -ENOMEM;
+ lmd->lmd_exclude_count = 0;
+ }
+ }
+ OBD_FREE(exclude_list, sizeof(index) * devmax);
+ RETURN(rc);
}
static int lmd_parse_mgssec(struct lustre_mount_data *lmd, char *ptr)