From 14765d2816bafa2a08879ece0e33bf8c97f84948 Mon Sep 17 00:00:00 2001 From: brian Date: Wed, 9 Jul 2008 21:43:16 +0000 Subject: [PATCH] b=15625 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 | 8 ++ lustre/autoconf/lustre-version.ac | 14 +++ lustre/doc/mount.lustre.8 | 12 ++ lustre/include/lustre_ver.h.in | 4 + lustre/utils/Makefile.am | 4 +- lustre/utils/mkfs_lustre.c | 57 ++-------- lustre/utils/mount_lustre.c | 6 +- lustre/utils/mount_utils.c | 230 ++++++++++++++++++++++++++++++++++++++ 8 files changed, 282 insertions(+), 53 deletions(-) create mode 100644 lustre/utils/mount_utils.c diff --git a/lustre/ChangeLog b/lustre/ChangeLog index 1cc6c48..e65ed2e 100644 --- a/lustre/ChangeLog +++ b/lustre/ChangeLog @@ -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 diff --git a/lustre/autoconf/lustre-version.ac b/lustre/autoconf/lustre-version.ac index b4a2135..3d2a7b2 100644 --- a/lustre/autoconf/lustre-version.ac +++ b/lustre/autoconf/lustre-version.ac @@ -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]) diff --git a/lustre/doc/mount.lustre.8 b/lustre/doc/mount.lustre.8 index 4980db3..8254d88 100644 --- a/lustre/doc/mount.lustre.8 +++ b/lustre/doc/mount.lustre.8 @@ -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" . diff --git a/lustre/include/lustre_ver.h.in b/lustre/include/lustre_ver.h.in index 583447e..1553f68 100644 --- a/lustre/include/lustre_ver.h.in +++ b/lustre/include/lustre_ver.h.in @@ -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) diff --git a/lustre/utils/Makefile.am b/lustre/utils/Makefile.am index 23b8df4..4066a9a 100644 --- a/lustre/utils/Makefile.am +++ b/lustre/utils/Makefile.am @@ -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 diff --git a/lustre/utils/mkfs_lustre.c b/lustre/utils/mkfs_lustre.c index 3bfe70d..25de036 100644 --- a/lustre/utils/mkfs_lustre.c +++ b/lustre/utils/mkfs_lustre.c @@ -50,6 +50,7 @@ #include #include #include +#include #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); diff --git a/lustre/utils/mount_lustre.c b/lustre/utils/mount_lustre.c index 916e6ef..455f8bc 100644 --- a/lustre/utils/mount_lustre.c +++ b/lustre/utils/mount_lustre.c @@ -33,12 +33,12 @@ #include #include #include -#include #include "obdctl.h" #include #include #include #include +#include #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 index 0000000..17d00d7 --- /dev/null +++ b/lustre/utils/mount_utils.c @@ -0,0 +1,230 @@ +#include +#include +#include +#include +#include +#include +#include +#include + +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)); + } + } +} -- 1.8.3.1