/* rc=0 means ok 1 means update <0 means error */ static int mgs_check_target(struct obd_device *obd, struct mgs_target_info *mti) { int rc; ENTRY; rc = mgs_check_index(obd, mti); if (rc == 0) { LCONSOLE_ERROR_MSG(0x13b, "%s claims to have registered, but " "this MGS does not know about it, preventing " "registration.\n", mti->mti_svname); rc = -ENOENT; } else if (rc == -1) { LCONSOLE_ERROR_MSG(0x13c, "Client log %s-client has " "disappeared! Regenerating all logs.\n", mti->mti_fsname); mti->mti_flags |= LDD_F_WRITECONF; rc = 1; } else { /* Index is correctly marked as used */ /* If the logs don't contain the mti_nids then add them as failover nids */ rc = mgs_check_failnid(obd, mti); } RETURN(rc); }
void lnet_connect_console_error (int rc, lnet_nid_t peer_nid, __u32 peer_ip, int peer_port) { switch (rc) { /* "normal" errors */ case -ECONNREFUSED: CDEBUG(D_NETERROR, "Connection to %s at host %u.%u.%u.%u " "on port %d was refused: " "check that Lustre is running on that node.\n", libcfs_nid2str(peer_nid), HIPQUAD(peer_ip), peer_port); break; case -EHOSTUNREACH: case -ENETUNREACH: CDEBUG(D_NETERROR, "Connection to %s at host %u.%u.%u.%u " "was unreachable: the network or that node may " "be down, or Lustre may be misconfigured.\n", libcfs_nid2str(peer_nid), HIPQUAD(peer_ip)); break; case -ETIMEDOUT: CDEBUG(D_NETERROR, "Connection to %s at host %u.%u.%u.%u on " "port %d took too long: that node may be hung " "or experiencing high load.\n", libcfs_nid2str(peer_nid), HIPQUAD(peer_ip), peer_port); break; case -ECONNRESET: LCONSOLE_ERROR_MSG(0x11b, "Connection to %s at host %u.%u.%u.%u" " on port %d was reset: " "is it running a compatible version of " "Lustre and is %s one of its NIDs?\n", libcfs_nid2str(peer_nid), HIPQUAD(peer_ip), peer_port, libcfs_nid2str(peer_nid)); break; case -EPROTO: LCONSOLE_ERROR_MSG(0x11c, "Protocol error connecting to %s at " "host %u.%u.%u.%u on port %d: is it running " "a compatible version of Lustre?\n", libcfs_nid2str(peer_nid), HIPQUAD(peer_ip), peer_port); break; case -EADDRINUSE: LCONSOLE_ERROR_MSG(0x11d, "No privileged ports available to " "connect to %s at host %u.%u.%u.%u on port " "%d\n", libcfs_nid2str(peer_nid), HIPQUAD(peer_ip), peer_port); break; default: LCONSOLE_ERROR_MSG(0x11e, "Unexpected error %d connecting to %s" " at host %u.%u.%u.%u on port %d\n", rc, libcfs_nid2str(peer_nid), HIPQUAD(peer_ip), peer_port); break; } }
/** Parse mount line options * e.g. mount -v -t lustre -o abort_recov uml1:uml2:/lustre-client /mnt/lustre * dev is passed as device=uml1:/lustre by mount.lustre */ static int lmd_parse(char *options, struct lustre_mount_data *lmd) { char *s1, *s2, *devname = NULL; struct lustre_mount_data *raw = (struct lustre_mount_data *)options; int rc = 0; LASSERT(lmd); if (!options) { LCONSOLE_ERROR_MSG(0x162, "Missing mount data: check that " "/sbin/mount.lustre is installed.\n"); return -EINVAL; } /* Options should be a string - try to detect old lmd data */ if ((raw->lmd_magic & 0xffffff00) == (LMD_MAGIC & 0xffffff00)) { LCONSOLE_ERROR_MSG(0x163, "You're using an old version of " "/sbin/mount.lustre. Please install " "version %s\n", LUSTRE_VERSION_STRING); return -EINVAL; } lmd->lmd_magic = LMD_MAGIC; OBD_ALLOC(lmd->lmd_params, 4096); if (lmd->lmd_params == NULL) return -ENOMEM; lmd->lmd_params[0] = '\0'; /* Set default flags here */ s1 = options; while (*s1) { int clear = 0; int time_min = OBD_RECOVERY_TIME_MIN; /* Skip whitespace and extra commas */ while (*s1 == ' ' || *s1 == ',') s1++; /* Client options are parsed in ll_options: eg. flock, user_xattr, acl */ /* Parse non-ldiskfs options here. Rather than modifying ldiskfs, we just zero these out here */ if (strncmp(s1, "abort_recov", 11) == 0) { lmd->lmd_flags |= LMD_FLG_ABORT_RECOV; clear++; } else if (strncmp(s1, "recovery_time_soft=", 19) == 0) { lmd->lmd_recovery_time_soft = max_t(int, simple_strtoul(s1 + 19, NULL, 10), time_min); clear++; } else if (strncmp(s1, "recovery_time_hard=", 19) == 0) {
/* Ghastly hack to allow LNET to inter-operate with portals. * NET type 0 becomes an alias for whatever local network we have, and * this assignment here means we can parse and print its NIDs */ LASSERT (nf != NULL); LASSERT (nf0->nf_type < 0); nf0->nf_name = "zero";//nf->nf_name; nf0->nf_modname = nf->nf_modname; nf0->nf_addr2str = nf->nf_addr2str; nf0->nf_str2addr = nf->nf_str2addr; mb(); nf0->nf_type = 0; } EXPORT_SYMBOL(libcfs_isknown_lnd); EXPORT_SYMBOL(libcfs_lnd2modname); EXPORT_SYMBOL(libcfs_lnd2str); EXPORT_SYMBOL(libcfs_str2lnd); EXPORT_SYMBOL(libcfs_net2str); EXPORT_SYMBOL(libcfs_nid2str); EXPORT_SYMBOL(libcfs_str2net); EXPORT_SYMBOL(libcfs_str2nid); EXPORT_SYMBOL(libcfs_id2str); EXPORT_SYMBOL(libcfs_str2anynid); EXPORT_SYMBOL(libcfs_setnet0alias); #else /* __KERNEL__ */ void libcfs_setnet0alias(__unusedx int lnd) { LCONSOLE_ERROR_MSG(0x125, "Liblustre cannot interoperate with old " "Portals.\nportals_compatibility must be set to " "'none'.\n"); }
static void lnet_syntax(char *name, char *str, int offset, int width) { static char dots[LNET_SINGLE_TEXTBUF_NOB]; static char dashes[LNET_SINGLE_TEXTBUF_NOB]; memset(dots, '.', sizeof(dots)); dots[sizeof(dots)-1] = 0; memset(dashes, '-', sizeof(dashes)); dashes[sizeof(dashes)-1] = 0; LCONSOLE_ERROR_MSG(0x10f, "Error parsing '%s=\"%s\"'\n", name, str); LCONSOLE_ERROR_MSG(0x110, "here...........%.*s..%.*s|%.*s|\n", (int)strlen(name), dots, offset, dots, (width < 1) ? 0 : width - 1, dashes); }
/** Get a config log from the MGS and process it. * This func is called for both clients and servers. * Continue to process new statements appended to the logs * (whenever the config lock is revoked) until lustre_end_log * is called. * @param sb The superblock is used by the MGC to write to the local copy of * the config log * @param logname The name of the llog to replicate from the MGS * @param cfg Since the same mgc may be used to follow multiple config logs * (e.g. ost1, ost2, client), the config_llog_instance keeps the state for * this log, and is added to the mgc's list of logs to follow. */ int lustre_process_log(struct super_block *sb, char *logname, struct config_llog_instance *cfg) { struct lustre_cfg *lcfg; struct lustre_cfg_bufs *bufs; struct lustre_sb_info *lsi = s2lsi(sb); struct obd_device *mgc = lsi->lsi_mgc; int rc; LASSERT(mgc); LASSERT(cfg); OBD_ALLOC_PTR(bufs); if (bufs == NULL) return -ENOMEM; /* mgc_process_config */ 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); OBD_FREE_PTR(bufs); if (rc == -EINVAL) LCONSOLE_ERROR_MSG(0x15b, "%s: The configuration from log '%s'" "failed from the MGS (%d). Make sure this " "client and the MGS are running compatible " "versions of Lustre.\n", mgc->obd_name, logname, rc); if (rc) LCONSOLE_ERROR_MSG(0x15c, "%s: The configuration from log '%s' " "failed (%d). This may be the result of " "communication errors between this node and " "the MGS, a bad configuration, or other " "errors. See the syslog for more " "information.\n", mgc->obd_name, logname, rc); /* class_obd_list(); */ return rc; }
static inline int accept2secure(const char *acc, long *sec) { if (!strcmp(acc, "secure")) { *sec = 1; return 1; } else if (!strcmp(acc, "all")) { *sec = 0; return 1; } else if (!strcmp(acc, "none")) { return 0; } else { LCONSOLE_ERROR_MSG(0x124, "Can't parse 'accept=\"%s\"'\n", acc); return -EINVAL; } }
/* Collect multiple values for mgsnid specifiers */ static int lmd_parse_mgs(struct lustre_mount_data *lmd, char **ptr) { lnet_nid_t nid; char *tail = *ptr; char *mgsnid; int length; int oldlen = 0; /* Find end of nidlist */ while (class_parse_nid_quiet(tail, &nid, &tail) == 0) ; length = tail - *ptr; if (length == 0) { LCONSOLE_ERROR_MSG(0x159, "Can't parse NID '%s'\n", *ptr); return -EINVAL; } if (lmd->lmd_mgs != NULL) oldlen = strlen(lmd->lmd_mgs) + 1; mgsnid = kzalloc(oldlen + length + 1, GFP_NOFS); if (!mgsnid) return -ENOMEM; if (lmd->lmd_mgs != NULL) { /* Multiple mgsnid= are taken to mean failover locations */ memcpy(mgsnid, lmd->lmd_mgs, oldlen); mgsnid[oldlen - 1] = ':'; kfree(lmd->lmd_mgs); } memcpy(mgsnid + oldlen, *ptr, length); mgsnid[oldlen + length] = '\0'; lmd->lmd_mgs = mgsnid; *ptr = tail; return 0; }
/** * Match client and OST server connection feature flags. * * Compute the compatibility flags for a connection request based on * features mutually supported by client and server. * * The obd_export::exp_connect_data.ocd_connect_flags field in \a exp * must not be updated here, otherwise a partially initialized value may * be exposed. After the connection request is successfully processed, * the top-level tgt_connect() request handler atomically updates the export * connect flags from the obd_connect_data::ocd_connect_flags field of the * reply. \see tgt_connect(). * * \param[in] env execution environment * \param[in] exp the obd_export associated with this * client/target pair * \param[in] data stores data for this connect request * \param[in] new_connection is this connection new or not * * \retval 0 if success * \retval -EPROTO client and server feature requirements are * incompatible * \retval -EBADF OST index in connect request doesn't match * real OST index */ static int ofd_parse_connect_data(const struct lu_env *env, struct obd_export *exp, struct obd_connect_data *data, bool new_connection) { struct ofd_device *ofd = ofd_exp(exp); struct filter_export_data *fed = &exp->exp_filter_data; if (!data) RETURN(0); CDEBUG(D_RPCTRACE, "%s: cli %s/%p ocd_connect_flags: "LPX64 " ocd_version: %x ocd_grant: %d ocd_index: %u" " ocd_group %u\n", exp->exp_obd->obd_name, exp->exp_client_uuid.uuid, exp, data->ocd_connect_flags, data->ocd_version, data->ocd_grant, data->ocd_index, data->ocd_group); if (fed->fed_group != 0 && fed->fed_group != data->ocd_group) { CWARN("!!! This export (nid %s) used object group %d " "earlier; now it's trying to use group %d! This could " "be a bug in the MDS. Please report to " "https://jira.hpdd.intel.com/\n", obd_export_nid2str(exp), fed->fed_group, data->ocd_group); RETURN(-EPROTO); } fed->fed_group = data->ocd_group; data->ocd_connect_flags &= OST_CONNECT_SUPPORTED; data->ocd_version = LUSTRE_VERSION_CODE; /* Kindly make sure the SKIP_ORPHAN flag is from MDS. */ if (data->ocd_connect_flags & OBD_CONNECT_MDS) CDEBUG(D_HA, "%s: Received MDS connection for group %u\n", exp->exp_obd->obd_name, data->ocd_group); else if (data->ocd_connect_flags & OBD_CONNECT_SKIP_ORPHAN) RETURN(-EPROTO); if (ofd_grant_param_supp(exp)) { exp->exp_filter_data.fed_pagesize = data->ocd_blocksize; /* ocd_{blocksize,inodespace} are log2 values */ data->ocd_blocksize = ofd->ofd_blockbits; data->ocd_inodespace = ofd->ofd_dt_conf.ddp_inodespace; /* ocd_grant_extent is in 1K blocks */ data->ocd_grant_extent = ofd->ofd_dt_conf.ddp_grant_frag >> 10; } if (data->ocd_connect_flags & OBD_CONNECT_GRANT) data->ocd_grant = ofd_grant_connect(env, exp, data->ocd_grant, new_connection); if (data->ocd_connect_flags & OBD_CONNECT_INDEX) { struct lr_server_data *lsd = &ofd->ofd_lut.lut_lsd; int index = lsd->lsd_osd_index; if (index != data->ocd_index) { LCONSOLE_ERROR_MSG(0x136, "Connection from %s to index" " %u doesn't match actual OST index" " %u in last_rcvd file, bad " "configuration?\n", obd_export_nid2str(exp), index, data->ocd_index); RETURN(-EBADF); } if (!(lsd->lsd_feature_compat & OBD_COMPAT_OST)) { /* this will only happen on the first connect */ lsd->lsd_feature_compat |= OBD_COMPAT_OST; /* sync is not needed here as lut_client_add will * set exp_need_sync flag */ tgt_server_data_update(env, &ofd->ofd_lut, 0); } } if (OBD_FAIL_CHECK(OBD_FAIL_OST_BRW_SIZE)) { data->ocd_brw_size = 65536; } else if (data->ocd_connect_flags & OBD_CONNECT_BRW_SIZE) { data->ocd_brw_size = min(data->ocd_brw_size, (__u32)DT_MAX_BRW_SIZE); if (data->ocd_brw_size == 0) { CERROR("%s: cli %s/%p ocd_connect_flags: "LPX64 " ocd_version: %x ocd_grant: %d ocd_index: %u " "ocd_brw_size is unexpectedly zero, " "network data corruption?" "Refusing connection of this client\n", exp->exp_obd->obd_name, exp->exp_client_uuid.uuid, exp, data->ocd_connect_flags, data->ocd_version, data->ocd_grant, data->ocd_index); RETURN(-EPROTO); } } if (data->ocd_connect_flags & OBD_CONNECT_CKSUM) { __u32 cksum_types = data->ocd_cksum_types; /* The client set in ocd_cksum_types the checksum types it * supports. We have to mask off the algorithms that we don't * support */ data->ocd_cksum_types &= cksum_types_supported_server(); if (unlikely(data->ocd_cksum_types == 0)) { CERROR("%s: Connect with checksum support but no " "ocd_cksum_types is set\n", exp->exp_obd->obd_name); RETURN(-EPROTO); } CDEBUG(D_RPCTRACE, "%s: cli %s supports cksum type %x, return " "%x\n", exp->exp_obd->obd_name, obd_export_nid2str(exp), cksum_types, data->ocd_cksum_types); } else { /* This client does not support OBD_CONNECT_CKSUM * fall back to CRC32 */ CDEBUG(D_RPCTRACE, "%s: cli %s does not support " "OBD_CONNECT_CKSUM, CRC32 will be used\n", exp->exp_obd->obd_name, obd_export_nid2str(exp)); } if (data->ocd_connect_flags & OBD_CONNECT_MAXBYTES) data->ocd_maxbytes = ofd->ofd_dt_conf.ddp_maxbytes; if (OCD_HAS_FLAG(data, PINGLESS)) { if (ptlrpc_pinger_suppress_pings()) { spin_lock(&exp->exp_obd->obd_dev_lock); list_del_init(&exp->exp_obd_chain_timed); spin_unlock(&exp->exp_obd->obd_dev_lock); } else { data->ocd_connect_flags &= ~OBD_CONNECT_PINGLESS; } } RETURN(0); }
int lnet_acceptor(void *arg) { socket_t *newsock; int rc; __u32 magic; __u32 peer_ip; int peer_port; int secure = (int)((long_ptr_t)arg); LASSERT(lnet_acceptor_state.pta_sock == NULL); cfs_block_allsigs(); rc = libcfs_sock_listen(&lnet_acceptor_state.pta_sock, 0, accept_port, accept_backlog); if (rc != 0) { if (rc == -EADDRINUSE) LCONSOLE_ERROR_MSG(0x122, "Can't start acceptor on port %d: port already in use\n", accept_port); else LCONSOLE_ERROR_MSG(0x123, "Can't start acceptor on port %d: unexpected error %d\n", accept_port, rc); lnet_acceptor_state.pta_sock = NULL; } else { LCONSOLE(0, "Accept %s, port %d\n", accept_type, accept_port); } /* set init status and unblock parent */ lnet_acceptor_state.pta_shutdown = rc; complete(&lnet_acceptor_state.pta_signal); if (rc != 0) return rc; while (!lnet_acceptor_state.pta_shutdown) { rc = libcfs_sock_accept(&newsock, lnet_acceptor_state.pta_sock); if (rc != 0) { if (rc != -EAGAIN) { CWARN("Accept error %d: pausing...\n", rc); cfs_pause(cfs_time_seconds(1)); } continue; } /* maybe we're waken up with libcfs_sock_abort_accept() */ if (lnet_acceptor_state.pta_shutdown) { libcfs_sock_release(newsock); break; } rc = libcfs_sock_getaddr(newsock, 1, &peer_ip, &peer_port); if (rc != 0) { CERROR("Can't determine new connection's address\n"); goto failed; } if (secure && peer_port > LNET_ACCEPTOR_MAX_RESERVED_PORT) { CERROR("Refusing connection from %pI4h: insecure port %d\n", &peer_ip, peer_port); goto failed; } rc = libcfs_sock_read(newsock, &magic, sizeof(magic), accept_timeout); if (rc != 0) { CERROR("Error %d reading connection request from %pI4h\n", rc, &peer_ip); goto failed; } rc = lnet_accept(newsock, magic); if (rc != 0) goto failed; continue; failed: libcfs_sock_release(newsock); } libcfs_sock_release(lnet_acceptor_state.pta_sock); lnet_acceptor_state.pta_sock = NULL; CDEBUG(D_NET, "Acceptor stopping\n"); /* unblock lnet_acceptor_stop() */ complete(&lnet_acceptor_state.pta_signal); return 0; }
int lnet_accept(socket_t *sock, __u32 magic) { lnet_acceptor_connreq_t cr; __u32 peer_ip; int peer_port; int rc; int flip; lnet_ni_t *ni; char *str; LASSERT(sizeof(cr) <= 16); /* not too big for the stack */ rc = libcfs_sock_getaddr(sock, 1, &peer_ip, &peer_port); LASSERT(rc == 0); /* we succeeded before */ if (!lnet_accept_magic(magic, LNET_PROTO_ACCEPTOR_MAGIC)) { if (lnet_accept_magic(magic, LNET_PROTO_MAGIC)) { /* future version compatibility! * When LNET unifies protocols over all LNDs, the first * thing sent will be a version query. I send back * LNET_PROTO_ACCEPTOR_MAGIC to tell her I'm "old" */ memset(&cr, 0, sizeof(cr)); cr.acr_magic = LNET_PROTO_ACCEPTOR_MAGIC; cr.acr_version = LNET_PROTO_ACCEPTOR_VERSION; rc = libcfs_sock_write(sock, &cr, sizeof(cr), accept_timeout); if (rc != 0) CERROR("Error sending magic+version in response to LNET magic from %pI4h: %d\n", &peer_ip, rc); return -EPROTO; } if (magic == le32_to_cpu(LNET_PROTO_TCP_MAGIC)) str = "'old' socknal/tcpnal"; else if (lnet_accept_magic(magic, LNET_PROTO_RA_MAGIC)) str = "'old' ranal"; else str = "unrecognised"; LCONSOLE_ERROR_MSG(0x11f, "Refusing connection from %pI4h magic %08x: %s acceptor protocol\n", &peer_ip, magic, str); return -EPROTO; } flip = (magic != LNET_PROTO_ACCEPTOR_MAGIC); rc = libcfs_sock_read(sock, &cr.acr_version, sizeof(cr.acr_version), accept_timeout); if (rc != 0) { CERROR("Error %d reading connection request version from %pI4h\n", rc, &peer_ip); return -EIO; } if (flip) __swab32s(&cr.acr_version); if (cr.acr_version != LNET_PROTO_ACCEPTOR_VERSION) { /* future version compatibility! * An acceptor-specific protocol rev will first send a version * query. I send back my current version to tell her I'm * "old". */ int peer_version = cr.acr_version; memset(&cr, 0, sizeof(cr)); cr.acr_magic = LNET_PROTO_ACCEPTOR_MAGIC; cr.acr_version = LNET_PROTO_ACCEPTOR_VERSION; rc = libcfs_sock_write(sock, &cr, sizeof(cr), accept_timeout); if (rc != 0) CERROR("Error sending magic+version in response to version %d from %pI4h: %d\n", peer_version, &peer_ip, rc); return -EPROTO; } rc = libcfs_sock_read(sock, &cr.acr_nid, sizeof(cr) - offsetof(lnet_acceptor_connreq_t, acr_nid), accept_timeout); if (rc != 0) { CERROR("Error %d reading connection request from %pI4h\n", rc, &peer_ip); return -EIO; } if (flip) __swab64s(&cr.acr_nid); ni = lnet_net2ni(LNET_NIDNET(cr.acr_nid)); if (ni == NULL || /* no matching net */ ni->ni_nid != cr.acr_nid) { /* right NET, wrong NID! */ if (ni != NULL) lnet_ni_decref(ni); LCONSOLE_ERROR_MSG(0x120, "Refusing connection from %pI4h for %s: No matching NI\n", &peer_ip, libcfs_nid2str(cr.acr_nid)); return -EPERM; } if (ni->ni_lnd->lnd_accept == NULL) { /* This catches a request for the loopback LND */ lnet_ni_decref(ni); LCONSOLE_ERROR_MSG(0x121, "Refusing connection from %pI4h for %s: NI doesn not accept IP connections\n", &peer_ip, libcfs_nid2str(cr.acr_nid)); return -EPERM; } CDEBUG(D_NET, "Accept %s from %pI4h\n", libcfs_nid2str(cr.acr_nid), &peer_ip); rc = ni->ni_lnd->lnd_accept(ni, sock); lnet_ni_decref(ni); return rc; }