📄 obd_mount.c
字号:
#define log2(n) ffz(~(n))#define LUSTRE_SUPER_MAGIC 0x0BD00BD1static int server_fill_super_common(struct super_block *sb){ struct inode *root = 0; ENTRY; CDEBUG(D_MOUNT, "Server sb, dev=%d\n", (int)sb->s_dev); sb->s_blocksize = 4096; sb->s_blocksize_bits = log2(sb->s_blocksize); sb->s_magic = LUSTRE_SUPER_MAGIC; sb->s_maxbytes = 0; //PAGE_CACHE_MAXBYTES; sb->s_flags |= MS_RDONLY; sb->s_op = &server_ops; root = new_inode(sb); if (!root) { CERROR("Can't make root inode\n"); RETURN(-EIO); } /* returns -EIO for every operation */ /* make_bad_inode(root); -- badness - can't umount */ /* apparently we need to be a directory for the mount to finish */ root->i_mode = S_IFDIR; sb->s_root = d_alloc_root(root); if (!sb->s_root) { CERROR("Can't make root dentry\n"); iput(root); RETURN(-EIO); } RETURN(0);}static int server_fill_super(struct super_block *sb){ struct lustre_sb_info *lsi = s2lsi(sb); struct vfsmount *mnt; int rc; ENTRY; /* the One True Mount */ mnt = server_kernel_mount(sb); if (IS_ERR(mnt)) { rc = PTR_ERR(mnt); CERROR("Unable to mount device %s: %d\n", lsi->lsi_lmd->lmd_dev, rc); lustre_put_lsi(sb); GOTO(out, rc); } lsi->lsi_srv_mnt = mnt; LASSERT(lsi->lsi_ldd); CDEBUG(D_MOUNT, "Found service %s for fs '%s' on device %s\n", lsi->lsi_ldd->ldd_svname, lsi->lsi_ldd->ldd_fsname, lsi->lsi_lmd->lmd_dev); if (class_name2obd(lsi->lsi_ldd->ldd_svname)) { LCONSOLE_ERROR_MSG(0x161, "The target named %s is already " "running. Double-mount may have compromised " "the disk journal.\n", lsi->lsi_ldd->ldd_svname); unlock_mntput(mnt); lustre_put_lsi(sb); GOTO(out, rc = -EALREADY); } /* start MGS before MGC */ if (IS_MGS(lsi->lsi_ldd)) { rc = server_start_mgs(sb); if (rc) GOTO(out_mnt, rc); } rc = lustre_start_mgc(sb); if (rc) GOTO(out_mnt, rc); /* Set up all obd devices for service */ if (!(lsi->lsi_lmd->lmd_flags & LMD_FLG_NOSVC) && (IS_OST(lsi->lsi_ldd) || IS_MDT(lsi->lsi_ldd))) { rc = server_start_targets(sb, mnt); if (rc < 0) { CERROR("Unable to start targets: %d\n", rc); GOTO(out_mnt, rc); } /* FIXME overmount client here, or can we just start a client log and client_fill_super on this sb? We need to make sure server_put_super gets called too - ll_put_super calls lustre_common_put_super; check there for LSI_SERVER flag, call s_p_s if so. Probably should start client from new thread so we can return. Client will not finish until all servers are connected. Note - MGS-only server does NOT get a client, since there is no lustre fs associated - the MGS is for all lustre fs's */ } rc = server_fill_super_common(sb); if (rc) GOTO(out_mnt, rc); LCONSOLE_WARN("Server %s on device %s has started\n", lsi->lsi_ldd->ldd_svname, lsi->lsi_lmd->lmd_dev); RETURN(0);out_mnt: server_put_super(sb);out: RETURN(rc);}/* 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(char *svname, __u32 *idx, char **endptr){ unsigned long index; int rc; char *dash = strchr(svname, '-'); if (!dash) return(-EINVAL); if (strncmp(dash + 1, "MDT", 3) == 0) rc = LDD_F_SV_TYPE_MDT; else if (strncmp(dash + 1, "OST", 3) == 0) rc = LDD_F_SV_TYPE_OST; else return(-EINVAL); index = simple_strtoul(dash + 4, endptr, 16); *idx = index; return rc;}/*************** mount common betweeen server and client ***************//* Common umount */int lustre_common_put_super(struct super_block *sb){ int rc; ENTRY; CDEBUG(D_MOUNT, "dropping sb %p\n", sb); /* Drop a ref to the MGC */ rc = lustre_stop_mgc(sb); if (rc && (rc != -ENOENT)) { if (rc != -EBUSY) { CERROR("Can't stop MGC: %d\n", rc); RETURN(rc); } /* BUSY just means that there's some other obd that needs the mgc. Let him clean it up. */ CDEBUG(D_MOUNT, "MGC still in use\n"); } /* Drop a ref to the mounted disk */ lustre_put_lsi(sb); RETURN(rc);}static void lmd_print(struct lustre_mount_data *lmd){ int i; PRINT_CMD(PRINT_MASK, " mount data:\n"); if (lmd_is_client(lmd)) PRINT_CMD(PRINT_MASK, "profile: %s\n", lmd->lmd_profile); PRINT_CMD(PRINT_MASK, "device: %s\n", lmd->lmd_dev); PRINT_CMD(PRINT_MASK, "flags: %x\n", lmd->lmd_flags); if (lmd->lmd_opts) PRINT_CMD(PRINT_MASK, "options: %s\n", lmd->lmd_opts); for (i = 0; i < lmd->lmd_exclude_count; i++) { PRINT_CMD(PRINT_MASK, "exclude %d: OST%04x\n", i, lmd->lmd_exclude[i]); }}/* Is this server on the exclusion list */int lustre_check_exclusion(struct super_block *sb, char *svname){ struct lustre_sb_info *lsi = s2lsi(sb); struct lustre_mount_data *lmd = lsi->lsi_lmd; __u32 index; int i, rc; ENTRY; rc = server_name2index(svname, &index, NULL); if (rc != LDD_F_SV_TYPE_OST) /* Only exclude OSTs */ RETURN(0); CDEBUG(D_MOUNT, "Check exclusion %s (%d) in %d of %s\n", svname, index, lmd->lmd_exclude_count, lmd->lmd_dev); for(i = 0; i < lmd->lmd_exclude_count; i++) { if (index == lmd->lmd_exclude[i]) { CWARN("Excluding %s (on exclusion list)\n", svname); RETURN(1); } } RETURN(0);}/* mount -v -o exclude=lustre-OST0001:lustre-OST0002 -t lustre ... */static int lmd_make_exclusion(struct lustre_mount_data *lmd, char *ptr){ 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); /* 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);}/* mount -v -t lustre uml1:uml2:/lustre-client /mnt/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; ENTRY; 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; /* Set default flags here */ s1 = options; while (*s1) { int clear = 0; /* 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, "nosvc", 5) == 0) { lmd->lmd_flags |= LMD_FLG_NOSVC; clear++; /* ost exclusion list */ } else if (strncmp(s1, "exclude=", 8) == 0) { rc = lmd_make_exclusion(lmd, s1 + 7); if (rc) goto invalid; clear++; } /* Linux 2.4 doesn't pass the device, so we stuck it at the end of the options. */ else if (strncmp(s1, "device=", 7) == 0) { devname = s1 + 7; /* terminate options right before device. device must be the last one. */ *s1 = '\0'; break; } /* Find next opt */ s2 = strchr(s1, ','); if (s2 == NULL) { if (clear) *s1 = '\0'; break; } s2++; if (clear) memmove(s1, s2, strlen(s2) + 1); else s1 = s2; } if (!devname) { LCONSOLE_ERROR_MSG(0x164, "Can't find the device name " "(need mount option 'device=...')\n"); goto invalid; } s1 = strrchr(devname, ':'); if (s1) { lmd->lmd_flags = LMD_FLG_CLIENT; /* Remove leading /s from fsname */ while (*++s1 == '/') ; /* Freed in lustre_free_lsi */ OBD_ALLOC(lmd->lmd_profile, strlen(s1) + 8); if (!lmd->lmd_profile) RETURN(-ENOMEM); sprintf(lmd->lmd_profile, "%s-client", s1); } /* Freed in lustre_free_lsi */ OBD_ALLOC(lmd->lmd_dev, strlen(devname) + 1); if (!lmd->lmd_dev) RETURN(-ENOMEM); strcpy(lmd->lmd_dev, devname); /* Save mount options */ s1 = options + strlen(options) - 1; while (s1 >= options && (*s1 == ',' || *s1 == ' ')) *s1-- = 0; if (*options != 0) { /* Freed in lustre_free_lsi */
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -