From: bobijam Date: Fri, 1 Aug 2008 02:21:36 +0000 (+0000) Subject: Branch HEAD X-Git-Tag: v1_9_50~96 X-Git-Url: https://git.whamcloud.com/gitweb?a=commitdiff_plain;h=4930ab80c968075a2833cb6e0c2a237274219992;p=fs%2Flustre-release.git Branch HEAD b=15576 i=johann, adilger Description: Resolve device initialization race Details : Prevent proc handler from accessing devices added to the obd_devs array but yet be intialized. --- diff --git a/lustre/ChangeLog b/lustre/ChangeLog index 3c698ef..e1ab172 100644 --- a/lustre/ChangeLog +++ b/lustre/ChangeLog @@ -12,6 +12,12 @@ tbd Sun Microsystems, Inc. * RHEL 4 and RHEL 5/SLES 10 clients behaves differently on 'cd' to a removed cwd "./" (refer to Bugzilla 14399). +Severity : normal +Bugzilla : 15576 +Description: Resolve device initialization race +Details : Prevent proc handler from accessing devices added to the + obd_devs array but yet be intialized. + Severity : enhancement Bugzilla : 15308 Description: Update to SLES10 SP2 kernel-2.6.16.60-0.23. diff --git a/lustre/obdclass/genops.c b/lustre/obdclass/genops.c index fcb0e1b..8fd27b0 100644 --- a/lustre/obdclass/genops.c +++ b/lustre/obdclass/genops.c @@ -254,6 +254,17 @@ int class_unregister_type(const char *name) RETURN(0); } /* class_unregister_type */ +/** + * Create a new obd device. + * + * Find an empty slot in ::obd_devs[], create a new obd device in it. + * + * \param typename [in] obd device type string. + * \param name [in] obd device name. + * + * \retval NULL if create fails, otherwise return the obd device + * pointer created. + */ struct obd_device *class_newdev(const char *type_name, const char *name) { struct obd_device *result = NULL; @@ -262,7 +273,7 @@ struct obd_device *class_newdev(const char *type_name, const char *name) int i; int new_obd_minor = 0; - if (strlen(name) > MAX_OBD_NAME) { + if (strlen(name) >= MAX_OBD_NAME) { CERROR("name/uuid must be < %u bytes long\n", MAX_OBD_NAME); RETURN(ERR_PTR(-EINVAL)); } @@ -305,7 +316,8 @@ struct obd_device *class_newdev(const char *type_name, const char *name) result->obd_minor = i; new_obd_minor = i; result->obd_type = type; - memcpy(result->obd_name, name, strlen(name)); + strncpy(result->obd_name, name, + sizeof(result->obd_name)); obd_devs[i] = result; } } @@ -409,15 +421,22 @@ struct obd_device *class_uuid2obd(struct obd_uuid *uuid) return class_num2obd(dev); } +/** + * Get obd device from ::obd_devs[] + * + * \param num [in] array index + * + * \retval NULL if ::obd_devs[\a num] does not contains an obd device + * otherwise return the obd device there. + */ struct obd_device *class_num2obd(int num) { struct obd_device *obd = NULL; if (num < class_devno_max()) { obd = obd_devs[num]; - if (obd == NULL) { + if (obd == NULL) return NULL; - } LASSERTF(obd->obd_magic == OBD_DEVICE_MAGIC, "%p obd_magic %08x != %08x\n", diff --git a/lustre/obdclass/linux/linux-module.c b/lustre/obdclass/linux/linux-module.c index 714a714..137449c 100644 --- a/lustre/obdclass/linux/linux-module.c +++ b/lustre/obdclass/linux/linux-module.c @@ -262,6 +262,21 @@ int obd_proc_read_pinger(char *page, char **start, off_t off, int count, ); } +/** + * Check all obd devices health + * + * \param page + * \param start + * \param off + * \param count + * \param eof + * \param data + * proc read function parameters, please refer to kernel + * code fs/proc/generic.c proc_file_read() + * \param data [in] unused + * + * \retval number of characters printed + */ static int obd_proc_read_health(char *page, char **start, off_t off, int count, int *eof, void *data) { @@ -276,7 +291,7 @@ static int obd_proc_read_health(char *page, char **start, off_t off, struct obd_device *obd; obd = class_num2obd(i); - if (obd == NULL) + if (obd == NULL || !obd->obd_attached || !obd->obd_set_up) continue; LASSERT(obd->obd_magic == OBD_DEVICE_MAGIC); diff --git a/lustre/obdclass/obd_mount.c b/lustre/obdclass/obd_mount.c index 8c8da6f..3ba46c0 100644 --- a/lustre/obdclass/obd_mount.c +++ b/lustre/obdclass/obd_mount.c @@ -556,7 +556,12 @@ static int server_stop_mgs(struct super_block *sb) DECLARE_MUTEX(mgc_start_lock); -/* Set up a mgcobd to process startup logs */ +/** Set up a mgc obd to process startup logs + * + * \param sb [in] super block of the mgc obd + * + * \retval 0 success, otherwise error code + */ static int lustre_start_mgc(struct super_block *sb) { struct lustre_handle mgc_conn = {0, }; @@ -613,7 +618,7 @@ static int lustre_start_mgc(struct super_block *sb) mutex_down(&mgc_start_lock); obd = class_name2obd(mgcname); - if (obd) { + if (obd && !obd->obd_stopping) { /* Re-using an existing MGC */ atomic_inc(&obd->u.cli.cl_mgc_refcount);