diff --git a/lustre/ChangeLog b/lustre/ChangeLog
index acc00b64e01ff6cdd4da5c04e4c16ea4c2fc9af1..34a1498574c142d3bcdb39134179735b14713b63 100644
--- a/lustre/ChangeLog
+++ b/lustre/ChangeLog
@@ -24,6 +24,13 @@ tbd Sun Microsystems, Inc.
 	  	'tunefs.lustre --param="mdt.quota_type=ug1" $MDTDEV'.
 	  For more information, please refer to bugzilla 13904.
 
+Severity   : major
+Bugzilla   : 14134
+Description: enable MGS and MDT services start separately
+Details    : add a 'nomgs' option in mount.lustre to enable start a MDT with
+             a co-located MGS without starting the MGS, which is a complement
+             to 'nosvc' mount option.
+
 Severity   : normal
 Frequency  : always, on ppc.
 Bugzilla   : 14856
diff --git a/lustre/doc/mount.lustre.8 b/lustre/doc/mount.lustre.8
index ae3c8423fb2a09e467eca25feb24dc805dd8ef0a..4980db37c63f6df82462b44663f99ca47cd2fa89 100644
--- a/lustre/doc/mount.lustre.8
+++ b/lustre/doc/mount.lustre.8
@@ -96,6 +96,9 @@ options:
 .BI nosvc
 Only start the MGC (and MGS, if co-located) for a target service, and not the actual service.
 .TP
+.BI nomgs
+Start a MDT with a co-located MGS without starting the MGS.
+.TP
 .BI exclude= ostlist
 Start a client or MDT with a (colon-separated) list of known inactive OSTs.
 .TP
diff --git a/lustre/include/lustre_disk.h b/lustre/include/lustre_disk.h
index 805cf40fba2c5aa4681612a184e9ae458407f16b..5dd36a3497294ae065c16860febc268f27855c04 100644
--- a/lustre/include/lustre_disk.h
+++ b/lustre/include/lustre_disk.h
@@ -151,6 +151,8 @@ struct lustre_mount_data {
 #define LMD_FLG_ABORT_RECOV  0x0008  /* Abort recovery */
 #define LMD_FLG_NOSVC        0x0010  /* Only start MGS/MGC for servers, 
                                         no other services */
+#define LMD_FLG_NOMGS        0x0020  /* Only start target for servers, reusing
+                                        existing MGS services */
 
 #define lmd_is_client(x) ((x)->lmd_flags & LMD_FLG_CLIENT) 
 
diff --git a/lustre/obdclass/obd_mount.c b/lustre/obdclass/obd_mount.c
index 8e42a9a9ad75ff11c42ae587d8393cb8d58493f3..663015d62c25c5cbcdce48ddb6e0f3ce983b7ec8 100644
--- a/lustre/obdclass/obd_mount.c
+++ b/lustre/obdclass/obd_mount.c
@@ -744,8 +744,8 @@ static int lustre_stop_mgc(struct super_block *sb)
         obd = lsi->lsi_mgc;
         if (!obd)
                 RETURN(-ENOENT);
-
         lsi->lsi_mgc = NULL;
+
         mutex_down(&mgc_start_lock);
         if (!atomic_dec_and_test(&obd->u.cli.cl_mgc_refcount)) {
                 /* This is not fatal, every client that stops
@@ -1354,7 +1354,8 @@ static void server_put_super(struct super_block *sb)
         CDEBUG(D_MOUNT, "server put_super %s\n", tmpname);
 
         /* Stop the target */
-        if (IS_MDT(lsi->lsi_ldd) || IS_OST(lsi->lsi_ldd)) {
+        if (!(lsi->lsi_lmd->lmd_flags & LMD_FLG_NOSVC) && 
+            (IS_MDT(lsi->lsi_ldd) || IS_OST(lsi->lsi_ldd))) {
                 struct lustre_profile *lprof = NULL;
 
                 /* tell the mgc to drop the config log */
@@ -1391,7 +1392,9 @@ static void server_put_super(struct super_block *sb)
                 /* stop the mgc before the mgs so the connection gets cleaned
                    up */
                 lustre_stop_mgc(sb);
-                server_stop_mgs(sb);
+                /* if MDS start with --nomgs, don't stop MGS then */
+                if (!(lsi->lsi_lmd->lmd_flags & LMD_FLG_NOMGS))
+                        server_stop_mgs(sb);
         }
 
         /* Clean the mgc and sb */
@@ -1579,7 +1582,7 @@ static int server_fill_super(struct super_block *sb)
         }
 
         /* start MGS before MGC */
-        if (IS_MGS(lsi->lsi_ldd)) {
+        if (IS_MGS(lsi->lsi_ldd) && !(lsi->lsi_lmd->lmd_flags & LMD_FLG_NOMGS)) {
                 rc = server_start_mgs(sb);
                 if (rc)
                         GOTO(out_mnt, rc);
@@ -1816,6 +1819,9 @@ static int lmd_parse(char *options, struct lustre_mount_data *lmd)
                 } else if (strncmp(s1, "nosvc", 5) == 0) {
                         lmd->lmd_flags |= LMD_FLG_NOSVC;
                         clear++;
+                } else if (strncmp(s1, "nomgs", 5) == 0) {
+                        lmd->lmd_flags |= LMD_FLG_NOMGS;
+                        clear++;
                 /* ost exclusion list */
                 } else if (strncmp(s1, "exclude=", 8) == 0) {
                         rc = lmd_make_exclusion(lmd, s1 + 7);
diff --git a/lustre/tests/conf-sanity.sh b/lustre/tests/conf-sanity.sh
index 4499f2c35fc9d96d0ab428e6a3859d4964f7cb0f..e3b7f9750a62a8cb414385893b7e4c0c822d8c2c 100644
--- a/lustre/tests/conf-sanity.sh
+++ b/lustre/tests/conf-sanity.sh
@@ -1579,5 +1579,26 @@ test_40() { # bug 15759
 }
 run_test 40 "race during service thread startup"
 
+test_41() { #bug 14134
+        local rc
+        start mds $MDSDEV $MDS_MOUNT_OPTS -o nosvc
+        start ost `ostdevname 1` $OST_MOUNT_OPTS
+        start mds $MDSDEV $MDS_MOUNT_OPTS -o nomgs
+        mkdir -p $MOUNT
+        mount_client $MOUNT || return 1
+        sleep 5
+
+        echo "blah blah" > $MOUNT/$tfile
+        cat $MOUNT/$tfile
+
+        umount_client $MOUNT
+        stop ost -f || return 201
+        stop mds -f || return 202
+        stop mds -f || return 203
+        unload_modules || return 204
+        return $rc
+}
+run_test 41 "mount mds with --nosvc and --nomgs"
+
 equals_msg `basename $0`: test complete
 [ -f "$TESTSUITELOG" ] && cat $TESTSUITELOG || true
diff --git a/lustre/utils/mount_lustre.c b/lustre/utils/mount_lustre.c
index 004890ccad88869893cdf23d4f833982b7b7243d..906a10abe207b33e1c6197c5174b65b1652ba1fa 100644
--- a/lustre/utils/mount_lustre.c
+++ b/lustre/utils/mount_lustre.c
@@ -69,6 +69,7 @@ void usage(FILE *out)
                 "\t<mntopt>: one or more comma separated of:\n"
                 "\t\t(no)flock,(no)user_xattr,(no)acl\n"
                 "\t\tnosvc: only start MGC/MGS obds\n"
+                "\t\tnomgs: only start target obds, using existing MGS\n"
                 "\t\texclude=<ostname>[:<ostname>] : colon-separated list of "
                 "inactive OSTs (e.g. lustre-OST0001)\n"
                 );