Whamcloud - gitweb
b=15625
authorbrian <brian>
Wed, 9 Jul 2008 21:43:16 +0000 (21:43 +0000)
committerbrian <brian>
Wed, 9 Jul 2008 21:43:16 +0000 (21:43 +0000)
i=adilger
i=nathan

Service Tags.

If the service tags package is installed on a Lustre node when a Lustre
target is mounted, a service tag will be generated which can then optionally
be collected by a Registration Client for addition to the Sun asset
inventory system being offered at inventory.sun.com.

lustre/ChangeLog
lustre/autoconf/lustre-version.ac
lustre/doc/mount.lustre.8
lustre/include/lustre_ver.h.in
lustre/utils/Makefile.am
lustre/utils/mkfs_lustre.c
lustre/utils/mount_lustre.c
lustre/utils/mount_utils.c [new file with mode: 0644]

index 1cc6c48..e65ed2e 100644 (file)
@@ -13,6 +13,14 @@ tbd  Sun Microsystems, Inc.
         removed cwd "./" (refer to Bugzilla 14399).
 
 Severity   : normal
+Bugzilla   : 15625
+Description: *optional* service tags registration
+Details    : if the "service tags" package is installed on a Lustre node
+             When the filesystem is mounted, a local-node service tag will
+            be created.  See http://inventory.sun.com/ for more information
+            on a free, web based IT asset management system.
+
+Severity   : normal
 Bugzilla   : 15825
 Description: Kernel BUG tries to release flock
 Details    : Lustre does not destroy flock lock before last reference goes
index b4a2135..3d2a7b2 100644 (file)
@@ -3,6 +3,12 @@ m4_define([LUSTRE_MINOR],[9])
 m4_define([LUSTRE_PATCH],[50])
 m4_define([LUSTRE_FIX],[0])
 
+dnl # don't forget to update the service tags info
+m4_define([CLIENT_URN],["LUSTRE-165-CLT"])
+m4_define([MDS_URN],["LUSTRE-165-MDS"])
+m4_define([MGS_URN],["LUSTRE-165-MGS"])
+m4_define([OSS_URN],["LUSTRE-165-OSS"])
+
 dnl # liblustre delta is 0.0.1.32 , next version with fixes is ok, but
 dnl # after following release candidate/beta would spill this warning already.
 m4_define([LUSTRE_VER_ALLOWED_OFFSET],["OBD_OCD_VERSION(0,0,1,32)"])
@@ -24,6 +30,10 @@ m4_define([LUSTRE_VERSION],m4_if(LUSTRE_FIX,[0],LUSTRE_MAJOR.LUSTRE_MINOR.LUSTRE
 [AC_LUSTRE_VER_ALLOWED_OFFSET]=LUSTRE_VER_ALLOWED_OFFSET
 [AC_LUSTRE_LIB_VER_OFFSET_WARN]=LUSTRE_LIB_VER_OFFSET_WARN
 [AC_LUSTRE_CLI_VER_OFFSET_WARN]=LUSTRE_CLI_VER_OFFSET_WARN
+[AC_LUSTRE_CLIENT_URN]=CLIENT_URN
+[AC_LUSTRE_MGS_URN]=MGS_URN
+[AC_LUSTRE_MDS_URN]=MDS_URN
+[AC_LUSTRE_OSS_URN]=OSS_URN
 
 AC_SUBST([AC_LUSTRE_MAJOR])
 AC_SUBST([AC_LUSTRE_MINOR])
@@ -33,3 +43,7 @@ AC_SUBST([AC_LUSTRE_VERSION_STRING])
 AC_SUBST([AC_LUSTRE_VER_ALLOWED_OFFSET])
 AC_SUBST([AC_LUSTRE_LIB_VER_OFFSET_WARN])
 AC_SUBST([AC_LUSTRE_CLI_VER_OFFSET_WARN])
+AC_SUBST([AC_LUSTRE_CLIENT_URN])
+AC_SUBST([AC_LUSTRE_MDS_URN])
+AC_SUBST([AC_LUSTRE_MGS_URN])
+AC_SUBST([AC_LUSTRE_OSS_URN])
index 4980db3..8254d88 100644 (file)
@@ -117,6 +117,18 @@ Start the Lustre metadata target service from /dev/sda1 on mountpoint /mnt/test/
 .B mount -t lustre -L testfs-MDT0000 -o abort_recov /mnt/test/mdt
 Start the testfs-MDT0000 service (by using the disk label), but abort the
 recovery process.
+.SH NOTES
+If the Service Tags tool (from the sun-servicetag package) can be found in
+/opt/sun/servicetag/bin/stclient an inventory service tag will be created
+reflecting the Lustre service being provided.  If this tool cannot be found
+.B mount.lustre
+will silently ignore it and no service tag is created.  The
+.BR stclient (1)
+tool only creates the local service tag.  No information is sent to the asset
+management system until you run the Registration Client to collect the tags
+and then upload them to the inventory system using your inventory system account.
+See https://inventory.sun.com/ for more details on a web-based, free, IT asset
+management system.
 .SH BUGS
 Not very many mount options can be changed with
 .BR "-o remount" .
index 583447e..1553f68 100644 (file)
@@ -9,6 +9,10 @@
 #define LUSTRE_PATCH @AC_LUSTRE_PATCH@
 #define LUSTRE_FIX @AC_LUSTRE_FIX@
 #define LUSTRE_VERSION_STRING "@AC_LUSTRE_VERSION_STRING@"
+#define CLIENT_URN "@AC_LUSTRE_CLIENT_URN@"
+#define MDS_URN "@AC_LUSTRE_MDS_URN@"
+#define MGS_URN "@AC_LUSTRE_MGS_URN@"
+#define OSS_URN "@AC_LUSTRE_OSS_URN@"
 
 #define LUSTRE_VERSION_CODE OBD_OCD_VERSION(LUSTRE_MAJOR,LUSTRE_MINOR,LUSTRE_PATCH,LUSTRE_FIX)
 
index 23b8df4..4066a9a 100644 (file)
@@ -80,11 +80,11 @@ llog_reader_DEPENDENCIES := $(LIBPTLCTL)
 
 lr_reader_SOURCES = lr_reader.c
 
-mount_lustre_SOURCES = mount_lustre.c 
+mount_lustre_SOURCES = mount_lustre.c mount_utils.c
 mount_lustre_LDADD := $(LIBPTLCTL)
 mount_lustre_DEPENDENCIES := $(LIBPTLCTL)
 
-mkfs_lustre_SOURCES = mkfs_lustre.c
+mkfs_lustre_SOURCES = mkfs_lustre.c mount_utils.c
 mkfs_lustre_CPPFLAGS = -UTUNEFS $(AM_CPPFLAGS)
 mkfs_lustre_LDADD := libiam.a $(LIBPTLCTL)
 mkfs_lustre_DEPENDENCIES := $(LIBPTLCTL) libiam.a
index 3bfe70d..25de036 100644 (file)
@@ -50,6 +50,7 @@
 #include <lustre_param.h>
 #include <lnet/lnetctl.h>
 #include <lustre_ver.h>
+#include <mount_utils.h>
 
 #ifndef PATH_MAX
 #define PATH_MAX 4096
@@ -73,8 +74,8 @@ struct mkfs_opts {
         int   mo_mgs_failnodes;
 };
 
-static char *progname;
-static int verbose = 1;
+char *progname;
+int verbose = 1;
 static int print_only = 0;
 static int failover = 0;
 
@@ -125,12 +126,6 @@ void usage(FILE *out)
 #define vprint if (verbose > 0) printf
 #define verrprint if (verbose >= 0) printf
 
-static void fatal(void)
-{
-        verbose = 0;
-        fprintf(stderr, "\n%s FATAL: ", progname);
-}
-
 /*================ utility functions =====================*/
 
 char *strscat(char *dst, char *src, int buflen) {
@@ -185,47 +180,6 @@ int get_os_version()
         return version;
 }
 
-int run_command(char *cmd, int cmdsz)
-{
-        char log[] = "/tmp/mkfs_logXXXXXX";
-        int fd = -1, rc;
-
-        if ((cmdsz - strlen(cmd)) < 6) {
-                fatal();
-                fprintf(stderr, "Command buffer overflow: %.*s...\n",
-                        cmdsz, cmd);
-                return ENOMEM;
-        }
-
-        if (verbose > 1) {
-                printf("cmd: %s\n", cmd);
-        } else {
-                if ((fd = mkstemp(log)) >= 0) {
-                        close(fd);
-                        strcat(cmd, " >");
-                        strcat(cmd, log);
-                }
-        }
-        strcat(cmd, " 2>&1");
-
-        /* Can't use popen because we need the rv of the command */
-        rc = system(cmd);
-        if (rc && (fd >= 0)) {
-                char buf[128];
-                FILE *fp;
-                fp = fopen(log, "r");
-                if (fp) {
-                        while (fgets(buf, sizeof(buf), fp) != NULL) {
-                                printf("   %s", buf);
-                        }
-                        fclose(fp);
-                }
-        }
-        if (fd >= 0)
-                remove(log);
-        return rc;
-}
-
 static int check_mtab_entry(char *spec)
 {
         FILE *fp;
@@ -449,6 +403,7 @@ static int file_in_dev(char *file_name, char *dev_name)
                 if (strstr(debugfs_cmd, "unsupported feature")) {
                           disp_old_e2fsprogs_msg("an unknown", 0);
                 }
+                pclose(fp);
                 return -1;
         }
         pclose(fp);
@@ -912,6 +867,10 @@ int read_local_files(struct mkfs_opts *mop)
 
         dev = mop->mo_device;
 
+        /* TODO: it's worth observing the get_mountdata() function that is
+                 in mount_utils.c for getting the mountdata out of the
+                 filesystem */
+
         /* Construct debugfs command line. */
         snprintf(cmd, cmdsz, "debugfs -c -R 'dump /%s %s/mountdata' %s",
                  MOUNT_DATA_FILE, tmpdir, dev);
index 916e6ef..455f8bc 100644 (file)
 #include <sys/mount.h>
 #include <mntent.h>
 #include <getopt.h>
-#include <sys/utsname.h>
 #include "obdctl.h"
 #include <lustre_ver.h>
 #include <glob.h>
 #include <ctype.h>
 #include <limits.h>
+#include <mount_utils.h>
 
 #define MAX_HW_SECTORS_KB_PATH  "queue/max_hw_sectors_kb"
 #define MAX_SECTORS_KB_PATH     "queue/max_sectors_kb"
@@ -47,7 +47,7 @@ int          verbose = 0;
 int          nomtab = 0;
 int          fake = 0;
 int          force = 0;
-static char *progname = NULL;
+char         *progname = NULL;
 
 void usage(FILE *out)
 {
@@ -555,6 +555,8 @@ int main(int argc, char *const argv[])
                                 " (may cause reduced IO performance)\n",
                                 argv[0], source);
 
+        register_service_tags(usource, source, target);
+
         if (!fake)
                 /* flags and target get to lustre_get_sb, but not
                    lustre_fill_super.  Lustre ignores the flags, but mount
diff --git a/lustre/utils/mount_utils.c b/lustre/utils/mount_utils.c
new file mode 100644 (file)
index 0000000..17d00d7
--- /dev/null
@@ -0,0 +1,230 @@
+#include <stdio.h>
+#include <errno.h>
+#include <string.h>
+#include <config.h>
+#include <lustre_disk.h>
+#include <lustre_ver.h>
+#include <sys/stat.h>
+#include <sys/utsname.h>
+
+extern char *progname;
+extern int verbose;
+
+#define vprint if (verbose > 0) printf
+#define verrprint if (verbose >= 0) printf
+
+void fatal(void)
+{
+        verbose = 0;
+        fprintf(stderr, "\n%s FATAL: ", progname);
+}
+
+int run_command(char *cmd, int cmdsz)
+{
+        char log[] = "/tmp/run_command_logXXXXXX";
+        int fd = -1, rc;
+
+        if ((cmdsz - strlen(cmd)) < 6) {
+                fatal();
+                fprintf(stderr, "Command buffer overflow: %.*s...\n",
+                        cmdsz, cmd);
+                return ENOMEM;
+        }
+
+        if (verbose > 1) {
+                printf("cmd: %s\n", cmd);
+        } else {
+                if ((fd = mkstemp(log)) >= 0) {
+                        close(fd);
+                        strcat(cmd, " >");
+                        strcat(cmd, log);
+                }
+        }
+        strcat(cmd, " 2>&1");
+
+        /* Can't use popen because we need the rv of the command */
+        rc = system(cmd);
+        if (rc && (fd >= 0)) {
+                char buf[128];
+                FILE *fp;
+                fp = fopen(log, "r");
+                if (fp) {
+                        while (fgets(buf, sizeof(buf), fp) != NULL) {
+                                printf("   %s", buf);
+                        }
+                        fclose(fp);
+                }
+        }
+        if (fd >= 0)
+                remove(log);
+        return rc;
+}
+
+int get_mountdata(char *dev, struct lustre_disk_data *mo_ldd)
+{
+
+        char tmpdir[] = "/tmp/lustre_tmp.XXXXXX";
+        char cmd[256];
+        char filepnm[128];
+        FILE *filep;
+        int ret = 0;
+        int ret2 = 0;
+        int cmdsz = sizeof(cmd);
+
+        /* Make a temporary directory to hold Lustre data files. */
+        if (!mkdtemp(tmpdir)) {
+                verrprint(stderr, "%s: Can't create temporary "
+                        "directory %s: %s\n",
+                        progname, tmpdir, strerror(errno));
+                return errno;
+        }
+
+        snprintf(cmd, cmdsz, "/sbin/debugfs -c -R 'dump /%s %s/mountdata' %s",
+                 MOUNT_DATA_FILE, tmpdir, dev);
+
+        ret = run_command(cmd, cmdsz);
+        if (ret) {
+                verrprint("%s: Unable to dump %s dir (%d)\n",
+                          progname, MOUNT_CONFIGS_DIR, ret);
+                goto out_rmdir;
+        }
+
+        sprintf(filepnm, "%s/mountdata", tmpdir);
+        filep = fopen(filepnm, "r");
+        if (filep) {
+                vprint("Reading %s\n", MOUNT_DATA_FILE);
+                fread(mo_ldd, sizeof(*mo_ldd), 1, filep);
+       } else {
+                verrprint("%s: Unable to read %d.%d config %s.\n",
+                          progname, LUSTRE_MAJOR, LUSTRE_MINOR, filepnm);
+                goto out_close;
+       }       
+
+out_close:
+        fclose(filep);
+
+out_rmdir:
+        snprintf(cmd, cmdsz, "rm -rf %s", tmpdir);
+        ret2 = run_command(cmd, cmdsz);
+        if (ret2) {
+                verrprint("Failed to remove temp dir %s (%d)\n", tmpdir, ret2);
+               /* failure return from run_command() is more important
+                 * than the failure to remove a dir */
+               if (!ret)
+                       ret = ret2;
+       }
+
+        return ret;
+}
+
+#define PARENT_URN "urn:uuid:2bb5bdbf-6c4b-11dc-9b8e-080020a9ed93"
+#define PARENT_PRODUCT "Lustre"
+
+static int stclient(char *type, char *arch)
+{
+
+        char product[64];
+        char *urn = NULL;
+        char cmd[1024];
+        FILE *fp;
+        int i;
+
+        if (strcmp(type, "Client") == 0)
+                urn = CLIENT_URN;
+        else if (strcmp(type, "MDS") == 0)
+                urn = MDS_URN;
+        else if (strcmp(type, "MGS") == 0)
+                urn = MGS_URN;
+        else if (strcmp(type, "OSS") == 0)
+                urn = OSS_URN;
+
+        snprintf(product, 64, "Lustre %s %d.%d.%d", type, LUSTRE_MAJOR,
+                 LUSTRE_MINOR, LUSTRE_PATCH); 
+
+        /* need to see if the entry exists first */
+        snprintf(cmd, 1024,
+                 "/opt/sun/servicetag/bin/stclient -f -t '%s' ", urn);
+        fp = popen(cmd, "r");
+        if (!fp) {
+                if (verbose)
+                        fprintf(stderr, "%s: trying to run stclient -f: %s\n",
+                                progname, strerror(errno));
+                return 0;
+        }
+
+        i = fread(cmd, 1, sizeof(cmd), fp);
+        if (i) {
+                cmd[i] = 0;
+                if (strcmp(cmd, "Record not found\n") != 0) {
+                        /* exists, just return */
+                        pclose(fp);
+                        return 0;
+                }
+        }
+        pclose(fp);
+
+        snprintf(cmd, 1024, "/opt/sun/servicetag/bin/stclient -a -p '%s' "
+               "-e %d.%d.%d -t '%s' -S mount -F '%s' -P '%s' -m SUN "
+               "-A %s -z global", product, LUSTRE_MAJOR, LUSTRE_MINOR,
+               LUSTRE_PATCH, urn, PARENT_URN, PARENT_PRODUCT, arch);
+
+        return(run_command(cmd, sizeof(cmd)));
+}
+
+void register_service_tags(char *usource, char *source, char *target)
+{
+        struct lustre_disk_data mo_ldd;
+        struct utsname utsname_buf;
+        struct stat stat_buf;
+        char stclient_loc[] = "/opt/sun/servicetag/bin/stclient";
+        int rc;
+
+        rc = stat(stclient_loc, &stat_buf);
+
+        if (rc == 0) {
+                /* call the service tags stclient to show that we use Lustre on
+                   this system */
+
+                rc = uname(&utsname_buf);
+                if (rc) {
+                        if (verbose)
+                                fprintf(stderr,
+                                        "%s: trying to get uname failed: %s, "
+                                        "inventory tags will not be created\n",
+                                        progname, strerror(errno));
+                } else {
+
+                        /* client or server? */
+                        if (strchr(usource, ':')) {
+                                stclient("Client", utsname_buf.machine);
+                        } else {
+                                /* first figure what type of device it is */
+                                rc = get_mountdata(source, &mo_ldd);
+                                if (rc) {
+                                        if (verbose)
+                                                fprintf(stderr,
+                                                        "%s: trying to read mountdata from %s "
+                                                        "failed: %s, inventory tags will not "
+                                                        "be created\n",
+                                                        progname, target, strerror(errno));
+                                } else {
+
+                                        if (IS_MDT(&mo_ldd))
+                                                stclient("MDS", utsname_buf.machine);
+
+                                        if (IS_MGS(&mo_ldd))
+                                                stclient("MGS", utsname_buf.machine);
+
+                                        if (IS_OST(&mo_ldd))
+                                                stclient("OSS", utsname_buf.machine);
+                                }
+                        }
+                }
+        } else {
+                if (errno != ENOENT && verbose) {
+                        fprintf(stderr,
+                                "%s: trying to stat stclient failed: %s\n",
+                                progname, strerror(errno));
+                }
+        }
+}