diff --git a/configure.ac b/configure.ac index 7dad1268541c449c9c527656db25c75ac0761712..e37b75434ff9cf55f5a777f588ebf2b4b48e31fe 100644 --- a/configure.ac +++ b/configure.ac @@ -73,9 +73,9 @@ dnl aliases for plugins. dnl case "$host" in *-*-aix*) AC_DEFINE(USE_ALIAS, 0, - [Define slurm_ prefix function aliases for plugins]) ;; + [Define slurm_ prefix function aliases for plugins]) ;; *darwin*) AC_DEFINE(USE_ALIAS, 0, - [Define slurm_ prefix function aliases for plugins]) ;; + [Define slurm_ prefix function aliases for plugins]) ;; *) AC_DEFINE(USE_ALIAS, 1, [Define slurm_ prefix function aliases for plugins]) ;; esac @@ -119,12 +119,12 @@ AC_SEARCH_LIBS([kstat_open], [kstat]) dnl Checks for header files. dnl AC_CHECK_HEADERS(mcheck.h values.h socket.h sys/socket.h \ - stdbool.h sys/ipc.h sys/shm.h sys/sem.h errno.h \ - stdlib.h dirent.h pthread.h sys/prctl.h \ - sysint.h inttypes.h termcap.h netdb.h sys/socket.h \ - sys/systemcfg.h ncurses.h curses.h sys/dr.h sys/vfs.h \ - pam/pam_appl.h security/pam_appl.h sys/sysctl.h \ - pty.h utmp.h \ + stdbool.h sys/ipc.h sys/shm.h sys/sem.h errno.h \ + stdlib.h dirent.h pthread.h sys/prctl.h \ + sysint.h inttypes.h termcap.h netdb.h sys/socket.h \ + sys/systemcfg.h ncurses.h curses.h sys/dr.h sys/vfs.h \ + pam/pam_appl.h security/pam_appl.h sys/sysctl.h \ + pty.h utmp.h \ sys/syslog.h linux/sched.h \ kstat.h paths.h limits.h sys/statfs.h sys/ptrace.h \ sys/termios.h float.h @@ -507,6 +507,9 @@ AC_CONFIG_FILES([Makefile src/plugins/acct_gather_infiniband/Makefile src/plugins/acct_gather_infiniband/ofed/Makefile src/plugins/acct_gather_infiniband/none/Makefile + src/plugins/acct_gather_filesystem/Makefile + src/plugins/acct_gather_filesystem/lustre/Makefile + src/plugins/acct_gather_filesystem/none/Makefile src/plugins/acct_gather_profile/Makefile src/plugins/acct_gather_profile/hdf5/Makefile src/plugins/acct_gather_profile/hdf5/sh5util/Makefile diff --git a/slurm/slurm.h.in b/slurm/slurm.h.in index 1046cd8778784e0d20f9bd86dbb5ed2c4099d1c3..db6a6a6c42a6b4130b14644104c6bf4a0f0e936b 100644 --- a/slurm/slurm.h.in +++ b/slurm/slurm.h.in @@ -1891,6 +1891,7 @@ typedef struct reservation_name_msg { #define DEBUG_FLAG_THREADID 0x00100000 /* Print out the thread id */ #define DEBUG_FLAG_PROFILE 0x00200000 /* AcctGatherProfile plugin */ #define DEBUG_FLAG_INFINIBAND 0x00400000 /* AcctGatherInfiniband plugin */ +#define DEBUG_FLAG_FILESYSTEM 0x00800000 /* AcctGatherFilesystem plugin */ #define GROUP_FORCE 0x8000 /* if set, update group membership * info even if no updates to @@ -1935,6 +1936,7 @@ typedef struct slurm_ctl_conf { char *acct_gather_energy_type; /* energy accounting type */ char *acct_gather_profile_type; /* profile accounting type */ char *acct_gather_infiniband_type; /* infiniband accounting type */ + char *acct_gather_filesystem_type; /* filesystem accounting type */ uint16_t acct_gather_node_freq; /* secs between node acct request */ char *authtype; /* authentication type */ char *backup_addr; /* comm path of slurmctld secondary server */ diff --git a/src/api/config_info.c b/src/api/config_info.c index f07e303ad437b25764d3e580ca438537ab5f12df..a64ab4c151115d333c62536fe3992a68d3366562 100644 --- a/src/api/config_info.c +++ b/src/api/config_info.c @@ -207,6 +207,11 @@ extern void *slurm_ctl_conf_2_key_pairs (slurm_ctl_conf_t* slurm_ctl_conf_ptr) key_pair->value = xstrdup(slurm_ctl_conf_ptr->acct_gather_infiniband_type); list_append(ret_list, key_pair); + key_pair = xmalloc(sizeof(config_key_pair_t)); + key_pair->name = xstrdup("AcctGatherFilesystemType"); + key_pair->value = xstrdup(slurm_ctl_conf_ptr->acct_gather_filesystem_type); + list_append(ret_list, key_pair); + snprintf(tmp_str, sizeof(tmp_str), "%u sec", slurm_ctl_conf_ptr->acct_gather_node_freq); key_pair = xmalloc(sizeof(config_key_pair_t)); diff --git a/src/common/Makefile.am b/src/common/Makefile.am index 9a00a0ba6bc6045a9fbc2e8d063b7290f52d7eff..1ff1fe6d8b1d5b0ae3b760a07ad9096d52de4295 100644 --- a/src/common/Makefile.am +++ b/src/common/Makefile.am @@ -95,6 +95,7 @@ libcommon_la_SOURCES = \ slurm_acct_gather_energy.c slurm_acct_gather_energy.h \ slurm_acct_gather_profile.c slurm_acct_gather_profile.h \ slurm_acct_gather_infiniband.c slurm_acct_gather_infiniband.h \ + slurm_acct_gather_filesystem.c slurm_acct_gather_filesystem.h \ slurm_jobcomp.c slurm_jobcomp.h \ slurm_topology.c slurm_topology.h \ switch.c switch.h \ diff --git a/src/common/read_config.c b/src/common/read_config.c index 45094375478a907c691f0fa78b877fd8701b591e..35d19b41cc0cd82dd54b2a903aa5540ec0f3bd2b 100644 --- a/src/common/read_config.c +++ b/src/common/read_config.c @@ -166,6 +166,7 @@ s_p_options_t slurm_conf_options[] = { {"AcctGatherNodeFreq", S_P_UINT16}, {"AcctGatherProfileType", S_P_STRING}, {"AcctGatherInfinibandType", S_P_STRING}, + {"AcctGatherFilesystemType", S_P_STRING}, {"AuthType", S_P_STRING}, {"BackupAddr", S_P_STRING}, {"BackupController", S_P_STRING}, @@ -2068,6 +2069,7 @@ free_slurm_conf (slurm_ctl_conf_t *ctl_conf_ptr, bool purge_node_hash) xfree (ctl_conf_ptr->acct_gather_energy_type); xfree (ctl_conf_ptr->acct_gather_profile_type); xfree (ctl_conf_ptr->acct_gather_infiniband_type); + xfree (ctl_conf_ptr->acct_gather_filesystem_type); xfree (ctl_conf_ptr->epilog); xfree (ctl_conf_ptr->epilog_slurmctld); xfree (ctl_conf_ptr->ext_sensors_type); @@ -2174,6 +2176,7 @@ init_slurm_conf (slurm_ctl_conf_t *ctl_conf_ptr) xfree (ctl_conf_ptr->acct_gather_energy_type); xfree (ctl_conf_ptr->acct_gather_profile_type); xfree (ctl_conf_ptr->acct_gather_infiniband_type); + xfree (ctl_conf_ptr->acct_gather_filesystem_type); ctl_conf_ptr->ext_sensors_freq = 0; xfree (ctl_conf_ptr->ext_sensors_type); ctl_conf_ptr->dynalloc_port = (uint16_t) NO_VAL; @@ -2677,6 +2680,11 @@ _validate_and_set_defaults(slurm_ctl_conf_t *conf, s_p_hashtbl_t *hashtbl) conf->acct_gather_infiniband_type = xstrdup(DEFAULT_ACCT_GATHER_INFINIBAND_TYPE); + if (!s_p_get_string(&conf->acct_gather_filesystem_type, + "AcctGatherFilesystemType", hashtbl)) + conf->acct_gather_filesystem_type = + xstrdup(DEFAULT_ACCT_GATHER_FILESYSTEM_TYPE); + if (!s_p_get_uint16(&conf->acct_gather_node_freq, "AcctGatherNodeFreq", hashtbl)) conf->acct_gather_node_freq = 0; @@ -3775,10 +3783,15 @@ extern char * debug_flags2str(uint32_t debug_flags) xstrcat(rc, "Gres"); } if (debug_flags & DEBUG_FLAG_INFINIBAND) { - if (rc) - xstrcat(rc, ","); - xstrcat(rc, "Infiniband"); - } + if (rc) + xstrcat(rc, ","); + xstrcat(rc, "Infiniband"); + } + if (debug_flags & DEBUG_FLAG_FILESYSTEM) { + if (rc) + xstrcat(rc, ","); + xstrcat(rc, "Filesystem"); + } if (debug_flags & DEBUG_FLAG_NO_CONF_HASH) { if (rc) xstrcat(rc, ","); @@ -3876,7 +3889,9 @@ extern uint32_t debug_str2flags(char *debug_flags) else if (strcasecmp(tok, "Gres") == 0) rc |= DEBUG_FLAG_GRES; else if (strcasecmp(tok, "Infiniband") == 0) - rc |= DEBUG_FLAG_INFINIBAND; + rc |= DEBUG_FLAG_INFINIBAND; + else if (strcasecmp(tok, "Filesystem") == 0) + rc |= DEBUG_FLAG_FILESYSTEM; else if (strcasecmp(tok, "NO_CONF_HASH") == 0) rc |= DEBUG_FLAG_NO_CONF_HASH; else if (strcasecmp(tok, "NoRealTime") == 0) diff --git a/src/common/read_config.h b/src/common/read_config.h index 8aea7e8807a983cb9c0b713aaef8be3e3216b29b..7bfef568a6ff71fbc7c1a07f36690dd989ae0fdb 100644 --- a/src/common/read_config.h +++ b/src/common/read_config.h @@ -82,6 +82,7 @@ extern char *default_plugstack; #define DEFAULT_ACCT_GATHER_ENERGY_TYPE "acct_gather_energy/none" #define DEFAULT_ACCT_GATHER_PROFILE_TYPE "acct_gather_profile/none" #define DEFAULT_ACCT_GATHER_INFINIBAND_TYPE "acct_gather_infiniband/none" +#define DEFAULT_ACCT_GATHER_FILESYSTEM_TYPE "acct_gather_filesystem/none" #define ACCOUNTING_STORAGE_TYPE_NONE "accounting_storage/none" #define DEFAULT_DISABLE_ROOT_JOBS 0 #define DEFAULT_ENFORCE_PART_LIMITS 0 diff --git a/src/common/slurm_acct_gather.c b/src/common/slurm_acct_gather.c index b3e54c8ae1bed9df95f221348c2120c78076afbe..01fb76bd3e052ac64333665e4b63bdad48f503fe 100644 --- a/src/common/slurm_acct_gather.c +++ b/src/common/slurm_acct_gather.c @@ -59,6 +59,7 @@ extern int acct_gather_conf_init(void) acct_gather_energy_g_conf_options(&full_options, &full_options_cnt); acct_gather_profile_g_conf_options(&full_options, &full_options_cnt); acct_gather_infiniband_g_conf_options(&full_options, &full_options_cnt); + acct_gather_filesystem_g_conf_options(&full_options, &full_options_cnt); /* ADD MORE HERE */ /* for the NULL at the end */ @@ -92,6 +93,7 @@ extern int acct_gather_conf_init(void) acct_gather_energy_g_conf_set(tbl); acct_gather_profile_g_conf_set(tbl); acct_gather_infiniband_g_conf_set(tbl); + acct_gather_filesystem_g_conf_set(tbl); /* ADD MORE HERE */ /******************************************/ diff --git a/src/common/slurm_acct_gather.h b/src/common/slurm_acct_gather.h index 6d6e0c2914ce23474855a061d3b8d229e2ce5c64..54e40165e761c1f86851972a9b2392180b8e37ae 100644 --- a/src/common/slurm_acct_gather.h +++ b/src/common/slurm_acct_gather.h @@ -55,6 +55,7 @@ #include "slurm_acct_gather_energy.h" #include "slurm_acct_gather_profile.h" #include "slurm_acct_gather_infiniband.h" +#include "slurm_acct_gather_filesystem.h" extern int acct_gather_conf_init(void); extern int acct_gather_conf_destroy(void); diff --git a/src/common/slurm_protocol_api.c b/src/common/slurm_protocol_api.c index 2cb76d5ad351da252d36a620849ed2c72b3d0372..58de63217679e3b6d5d022d5fa8237635e721329 100644 --- a/src/common/slurm_protocol_api.c +++ b/src/common/slurm_protocol_api.c @@ -1448,6 +1448,25 @@ char *slurm_get_acct_gather_infiniband_type(void) return acct_gather_infiniband_type; } +/* slurm_get_filesystem_accounting_type + * get FilesystemAccountingType from slurmctld_conf object + * RET char * - filesystem_accounting type, MUST be xfreed by caller + */ +char *slurm_get_acct_gather_filesystem_type(void) +{ + char *acct_gather_filesystem_type = NULL; + slurm_ctl_conf_t *conf; + + if (slurmdbd_conf) { + } else { + conf = slurm_conf_lock(); + acct_gather_filesystem_type = + xstrdup(conf->acct_gather_filesystem_type); + slurm_conf_unlock(); + } + return acct_gather_filesystem_type; +} + extern uint16_t slurm_get_acct_gather_node_freq(void) { diff --git a/src/common/slurm_protocol_api.h b/src/common/slurm_protocol_api.h index cf570c87d2854c30a9e80de14391dbdc19fa4443..e48d5744b7e23f7b532c363ec0a7f004358e649a 100644 --- a/src/common/slurm_protocol_api.h +++ b/src/common/slurm_protocol_api.h @@ -569,6 +569,13 @@ char *slurm_get_acct_gather_profile_type(void); */ char *slurm_get_acct_gather_infiniband_type(void); +/* slurm_get_acct_filesystem_profile_type + * get FilesystemAccountingType from slurmctld_conf object + * RET char * - acct_gather_filesystem_type, MUST be xfreed by caller + */ +char *slurm_get_acct_gather_filesystem_type(void); + + /* slurm_get_acct_gather_node_freq * returns the accounting poll frequency for requesting info from a * node from the slurmctld_conf object diff --git a/src/plugins/Makefile.am b/src/plugins/Makefile.am index e2aa5db8000a473395a2a28232a3b061b75a86f7..3e73f3452b0a7cbbce6d90a388a712ded9e9aa04 100644 --- a/src/plugins/Makefile.am +++ b/src/plugins/Makefile.am @@ -3,6 +3,7 @@ SUBDIRS = \ acct_gather_energy \ acct_gather_profile \ acct_gather_infiniband \ + acct_gather_filesystem \ auth \ checkpoint \ crypto \ diff --git a/src/plugins/acct_gather_filesystem/Makefile.am b/src/plugins/acct_gather_filesystem/Makefile.am new file mode 100644 index 0000000000000000000000000000000000000000..5b95ab898dfab565337baefd4cc83890ff6ae455 --- /dev/null +++ b/src/plugins/acct_gather_filesystem/Makefile.am @@ -0,0 +1,3 @@ +# Makefile for accounting gather filesystem plugins + +SUBDIRS = lustre none diff --git a/src/plugins/acct_gather_filesystem/lustre/Makefile.am b/src/plugins/acct_gather_filesystem/lustre/Makefile.am new file mode 100644 index 0000000000000000000000000000000000000000..22d9fad0c4c60e4cde394618a8a69e38d63299b2 --- /dev/null +++ b/src/plugins/acct_gather_filesystem/lustre/Makefile.am @@ -0,0 +1,27 @@ +# Makefile for acct_gather_filesystem/lustre plugin + +#dprx need to uncomment this when safe to build +#SUBDIRS = include lib + +AUTOMAKE_OPTIONS = foreign + +INCLUDES = -I$(top_srcdir) -I$(top_srcdir)/src/common + +if BUILD_OFED + +PLUGIN_FLAGS = -module -avoid-version --export-dynamic + +pkglib_LTLIBRARIES = acct_gather_filesystem_lustre.la + +# Infiniband accounting lustre plugin. +acct_gather_filesystem_lustre_la_SOURCES = acct_gather_filesystem_lustre.c \ + acct_gather_filesystem_lustre.h + +acct_gather_filesystem_lustre_la_LDFLAGS = $(SO_LDFLAGS) $(PLUGIN_FLAGS) +acct_gather_filesystem_lustre_la_LIBADD = -lm + +else + +EXTRA_acct_gather_filesystem_lustre_la_SOURCES = acct_gather_filesystem_lustre.c \ + acct_gather_filesystem_lustre.h +endif diff --git a/src/plugins/acct_gather_filesystem/lustre/acct_gather_filesystem_lustre.c b/src/plugins/acct_gather_filesystem/lustre/acct_gather_filesystem_lustre.c new file mode 100644 index 0000000000000000000000000000000000000000..873c6a0d44299a3cd283e8690ef6427bed3217d6 --- /dev/null +++ b/src/plugins/acct_gather_filesystem/lustre/acct_gather_filesystem_lustre.c @@ -0,0 +1,362 @@ +/*****************************************************************************\ + * acct_gather_filesystem_lustre.c -slurm filesystem accounting plugin for lustre + ***************************************************************************** + * Copyright (C) 2013 + * Written by Bull- Yiannis Georgiou + * + * This file is part of SLURM, a resource management program. + * For details, see <http://www.schedmd.com/slurmdocs/>. + * Please also read the included file: DISCLAIMER. + * + * SLURM is free software; you can redistribute it and/or modify it under + * the terms of the GNU General Public License as published by the Free + * Software Foundation; either version 2 of the License, or (at your option) + * any later version. + * + * In addition, as a special exception, the copyright holders give permission + * to link the code of portions of this program with the OpenSSL library under + * certain conditions as described in each individual source file, and + * distribute linked combinations including the two. You must obey the GNU + * General Public License in all respects for all of the code used other than + * OpenSSL. If you modify file(s) with this exception, you may extend this + * exception to your version of the file(s), but you are not obligated to do + * so. If you do not wish to do so, delete this exception statement from your + * version. If you delete this exception statement from all source files in + * the program, then also delete it here. + * + * SLURM is distributed in the hope that it will be useful, but WITHOUT ANY + * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS + * FOR A PARTICULAR PURPOSE. See the GNU General Public License for more + * details. + * + * You should have received a copy of the GNU General Public License along + * with SLURM; if not, write to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + * + * This file is patterned after jobcomp_linux.c, written by Morris Jette and + * Copyright (C) 2002 The Regents of the University of California. +\*****************************************************************************/ + + +#include <stdlib.h> +#include <stdio.h> +#include <fcntl.h> +#include <sys/stat.h> +#include <signal.h> +#include <dirent.h> + +#include <unistd.h> +#include <getopt.h> +#include <netinet/in.h> + + +#include "src/common/slurm_xlator.h" +#include "src/common/slurm_acct_gather_filesystem.h" +#include "src/common/slurm_protocol_api.h" +#include "src/common/slurm_protocol_defs.h" +#include "src/slurmd/common/proctrack.h" +#include "src/common/slurm_acct_gather_profile.h" + +#include "src/slurmd/slurmd/slurmd.h" +#include "acct_gather_filesystem_lustre.h" + + +/***************************************************************/ + + + +#define _DEBUG 1 +#define _DEBUG_FILESYSTEM 1 + +/* + * These variables are required by the generic plugin interface. If they + * are not found in the plugin, the plugin loader will ignore it. + * + * plugin_name - a string giving a human-readable description of the + * plugin. There is no maximum length, but the symbol must refer to + * a valid string. + * + * plugin_type - a string suggesting the type of the plugin or its + * applicability to a particular form of data or method of data handling. + * If the low-level plugin API is used, the contents of this string are + * unimportant and may be anything. SLURM uses the higher-level plugin + * interface which requires this string to be of the form + * + * <application>/<method> + * + * where <application> is a description of the intended application of + * the plugin (e.g., "jobacct" for SLURM job completion logging) and <method> + * is a description of how this plugin satisfies that application. SLURM will + * only load job completion logging plugins if the plugin_type string has a + * prefix of "jobacct/". + * + * plugin_version - an unsigned 32-bit integer giving the version number + * of the plugin. If major and minor revisions are desired, the major + * version number may be multiplied by a suitable magnitude constant such + * as 100 or 1000. Various SLURM versions will likely require a certain + * minimum version for their plugins as the job accounting API + * matures. + */ + +const char plugin_name[] = "AcctGatherFilesystem LUSTRE plugin"; +const char plugin_type[] = "acct_gather_filesystem/lustre"; +const uint32_t plugin_version = 100; + + +typedef struct { + time_t last_update_time; + time_t update_time; + uint64_t lustre_nb_writes; + uint64_t lustre_nb_reads; + uint64_t all_lustre_nb_writes; + uint64_t all_lustre_nb_reads; + uint64_t lustre_write_bytes; + uint64_t lustre_read_bytes; + uint64_t all_lustre_write_bytes; + uint64_t all_lustre_read_bytes; +} lustre_sens_t; + +static lustre_sens_t lustre_se = {0,0,0,0,0,0,0,0}; + +static slurm_fs_conf_t lustre_conf; +static uint32_t debug_flags = 0; +static pthread_mutex_t lustre_lock = PTHREAD_MUTEX_INITIALIZER; + +/* Default path to lustre stats */ +const char proc_base_path[] = "/proc/fs/lustre/"; + +/** + * is lustre fs supported + **/ +static int _check_lustre_fs() +{ + static bool set = false; + static int rc = SLURM_SUCCESS; + + if (!set) { + uint32_t profile = 0; + char lustre_directory[BUFSIZ]; + DIR *proc_dir; + + set = true; + acct_gather_profile_g_get(ACCT_GATHER_PROFILE_RUNNING, + &profile); + if ((profile & ACCT_GATHER_PROFILE_LUSTRE)) { + sprintf(lustre_directory, "%s/llite", proc_base_path); + proc_dir = opendir(proc_base_path); + if (!proc_dir) { + debug2("not able to read %s", + lustre_directory); + rc = SLURM_FAILURE; + } + closedir(proc_dir); + } else + rc = SLURM_ERROR; + } + + return rc; +} + +/** + * read counters from all mounted lustre fs + */ +static int _read_lustre_counters(void ) +{ + char lustre_dir[PATH_MAX]; + char path_stats[PATH_MAX]; + DIR *proc_dir; + struct dirent *entry; + FILE *fff; + char buffer[BUFSIZ]; + + + sprintf(lustre_dir, "%s/llite", proc_base_path); + + proc_dir = opendir(lustre_dir); + if (proc_dir == NULL) { + error("Cannot open %s\n", lustre_dir); + return SLURM_FAILURE; + } + + entry = readdir(proc_dir); + + while (entry != NULL) { + snprintf(path_stats, PATH_MAX - 1, "%s/%s/stats", lustre_dir, + entry->d_name); + debug3("Found file %s\n", path_stats); + + fff = fopen(path_stats, "r"); + if (fff) { + while(1) { + if (!fgets(buffer,BUFSIZ,fff)) + break; + + if (strstr(buffer, "write_bytes")) { + sscanf(buffer, + "%*s %"PRIu64" %*s %*s " + "%*d %*d %"PRIu64"", + &lustre_se.lustre_nb_writes, + &lustre_se.lustre_write_bytes); + debug3("Lustre Counter " + "%"PRIu64" " + "write_bytes %"PRIu64" " + "writes\n", + lustre_se.lustre_write_bytes, + lustre_se.lustre_nb_writes); + } + + if (strstr(buffer, "read_bytes")) { + sscanf(buffer, + "%*s %"PRIu64" %*s %*s " + "%*d %*d %"PRIu64"", + &lustre_se.lustre_nb_reads, + &lustre_se.lustre_read_bytes); + debug3("Lustre Counter " + "%"PRIu64" " + "read_bytes %"PRIu64" " + "reads\n", + lustre_se.lustre_read_bytes, + lustre_se.lustre_nb_reads); + } + } + fclose(fff); + } + entry = readdir(proc_dir); + lustre_se.all_lustre_write_bytes += lustre_se.lustre_write_bytes; + lustre_se.all_lustre_read_bytes += lustre_se.lustre_read_bytes; + lustre_se.all_lustre_nb_writes += lustre_se.lustre_nb_writes; + lustre_se.all_lustre_nb_reads += lustre_se.lustre_nb_reads; + } + closedir(proc_dir); + + lustre_se.last_update_time = lustre_se.update_time; + lustre_se.update_time = time(NULL); + + + return SLURM_SUCCESS; +} + + + + +/* + * _thread_update_node_energy calls _read_ipmi_values and updates all values + * for node consumption + */ +static int _update_node_filesystem(void) +{ + acct_filesystem_data_t *fls; + int rc = SLURM_SUCCESS; + + slurm_mutex_lock(&lustre_lock); + rc = _read_lustre_counters(); + + fls = xmalloc(sizeof(acct_filesystem_data_t)); + + fls->reads = lustre_se.all_lustre_nb_reads; + fls->writes = lustre_se.all_lustre_nb_writes; + fls->read_size = (double) lustre_se.all_lustre_read_bytes / 1048576; + fls->write_size = (double) lustre_se.all_lustre_write_bytes / 1048576; + acct_gather_profile_g_add_sample_data(ACCT_GATHER_PROFILE_LUSTRE, fls); + + debug3("Collection of Lustre counters Finished"); + xfree(fls); + + + if (debug_flags & DEBUG_FLAG_FILESYSTEM) { + info("lustre-thread = %d sec, transmitted %"PRIu64" bytes, " + "received %"PRIu64" bytes", + (int) (lustre_se.update_time - lustre_se.last_update_time), + lustre_se.xmtdataall_lustre_read_bytes, + lustre_se.all_lustre_write_bytes); + } + slurm_mutex_unlock(&lustre_lock); + + return rc; +} + +static bool _run_in_daemon(void) +{ + static bool set = false; + static bool run = false; + + if (!set) { + set = 1; + run = run_in_daemon("slurmstepd"); + } + + return run; +} + + +/* + * init() is called when the plugin is loaded, before any other functions + * are called. Put global initialization here. + */ +extern int init(void) +{ + debug_flags = slurm_get_debug_flags(); + + return SLURM_SUCCESS; +} + +extern int fini(void) +{ + if (!_run_in_daemon()) + return SLURM_SUCCESS; + + if (debug_flags & DEBUG_FLAG_FILESYSTEM) + info("lustre: ended"); + + return SLURM_SUCCESS; +} + +extern int acct_gather_filesystem_p_node_update(void) +{ + uint32_t profile; + int rc = SLURM_SUCCESS; + static bool set = false; + + acct_gather_profile_g_get(ACCT_GATHER_PROFILE_RUNNING, + &profile); + + if (!(profile & ACCT_GATHER_PROFILE_LUSTRE)) + set = true; + + if ((set == true) && (_check_lustre_fs() == SLURM_SUCCESS)) + _update_node_filesystem(); + + return rc; +} + + +extern void acct_gather_filesystem_p_conf_set(s_p_hashtbl_t *tbl) +{ + if (tbl) { + s_p_get_uint32(&lustre_conf.freq, + "FilesystemLUSTREFrequency", tbl); + } + + if (!_run_in_daemon()) + return; + + verbose("%s loaded", plugin_name); +} + +extern void acct_gather_filesystem_p_conf_options(s_p_options_t **full_options, + int *full_options_cnt) +{ + s_p_options_t options[] = { + {"FilesystemLUSTREFrequency", S_P_UINT32}, + {NULL} }; + + transfer_s_p_options(full_options, options, full_options_cnt); + + return; +} + +extern void* acct_gather_filesystem_p_conf_get() +{ + return &lustre_conf; +} + diff --git a/src/plugins/acct_gather_filesystem/none/Makefile.am b/src/plugins/acct_gather_filesystem/none/Makefile.am new file mode 100644 index 0000000000000000000000000000000000000000..18bf771ecf0b1955f3fbb79fc771a307c51300c3 --- /dev/null +++ b/src/plugins/acct_gather_filesystem/none/Makefile.am @@ -0,0 +1,15 @@ +# Makefile for acct_gather_filesystem/none plugin + +AUTOMAKE_OPTIONS = foreign + +PLUGIN_FLAGS = -module -avoid-version --export-dynamic + +INCLUDES = -I$(top_srcdir) -I$(top_srcdir)/src/common + +pkglib_LTLIBRARIES = acct_gather_filesystem_none.la + +# Null job completion logging plugin. +acct_gather_filesystem_none_la_SOURCES = acct_gather_filesystem_none.c + +acct_gather_filesystem_none_la_LDFLAGS = $(SO_LDFLAGS) $(PLUGIN_FLAGS) + diff --git a/src/plugins/acct_gather_filesystem/none/acct_gather_filesystem_none.c b/src/plugins/acct_gather_filesystem/none/acct_gather_filesystem_none.c new file mode 100644 index 0000000000000000000000000000000000000000..745e50334d2d8378cd85fbac26415e89dab0f821 --- /dev/null +++ b/src/plugins/acct_gather_filesystem/none/acct_gather_filesystem_none.c @@ -0,0 +1,121 @@ +/*****************************************************************************\ + * acct_gather_filesystem_none.c - slurm filesystem accounting plugin for none. + ***************************************************************************** + * Copyright (C) 2013 BULL + * Written by Yiannis Georgiou <yiannis.georgiou@bull.net>, + * + * This file is part of SLURM, a resource management program. + * For details, see <http://www.schedmd.com/slurmdocs/>. + * Please also read the included file: DISCLAIMER. + * + * SLURM is free software; you can redistribute it and/or modify it under + * the terms of the GNU General Public License as published by the Free + * Software Foundation; either version 2 of the License, or (at your option) + * any later version. + * + * In addition, as a special exception, the copyright holders give permission + * to link the code of portions of this program with the OpenSSL library under + * certain conditions as described in each individual source file, and + * distribute linked combinations including the two. You must obey the GNU + * General Public License in all respects for all of the code used other than + * OpenSSL. If you modify file(s) with this exception, you may extend this + * exception to your version of the file(s), but you are not obligated to do + * so. If you do not wish to do so, delete this exception statement from your + * version. If you delete this exception statement from all source files in + * the program, then also delete it here. + * + * SLURM is distributed in the hope that it will be useful, but WITHOUT ANY + * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS + * FOR A PARTICULAR PURPOSE. See the GNU General Public License for more + * details. + * + * You should have received a copy of the GNU General Public License along + * with SLURM; if not, write to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + * + * This file is patterned after jobcomp_linux.c, written by Morris Jette and + * Copyright (C) 2002 The Regents of the University of California. +\*****************************************************************************/ + + +/* acct_gather_filesystem_none + * This plugin does not initiate a node-level thread. + * It is the acct_gather_filesystem stub. + */ + +#include "src/common/slurm_xlator.h" +#include "src/common/slurm_jobacct_gather.h" +#include "src/common/slurm_protocol_api.h" +#include "src/common/slurm_protocol_defs.h" +#include "src/slurmd/common/proctrack.h" + +#include <fcntl.h> +#include <signal.h> + +#define _DEBUG 1 +#define _DEBUG_INFINIBAND 1 + +/* + * These variables are required by the generic plugin interface. If they + * are not found in the plugin, the plugin loader will ignore it. + * + * plugin_name - a string giving a human-readable description of the + * plugin. There is no maximum length, but the symbol must refer to + * a valid string. + * + * plugin_type - a string suggesting the type of the plugin or its + * applicability to a particular form of data or method of data handling. + * If the low-level plugin API is used, the contents of this string are + * unimportant and may be anything. SLURM uses the higher-level plugin + * interface which requires this string to be of the form + * + * <application>/<method> + * + * where <application> is a description of the intended application of + * the plugin (e.g., "jobacct" for SLURM job completion logging) and <method> + * is a description of how this plugin satisfies that application. SLURM will + * only load job completion logging plugins if the plugin_type string has a + * prefix of "jobacct/". + * + * plugin_version - an unsigned 32-bit integer giving the version number + * of the plugin. If major and minor revisions are desired, the major + * version number may be multiplied by a suitable magnitude constant such + * as 100 or 1000. Various SLURM versions will likely require a certain + * minimum version for their plugins as the job accounting API + * matures. + */ +const char plugin_name[] = "AcctGatherFilesystem NONE plugin"; +const char plugin_type[] = "acct_gather_filesystem/none"; +const uint32_t plugin_version = 100; + +/* + * init() is called when the plugin is loaded, before any other functions + * are called. Put global initialization here. + */ +extern int init(void) +{ + verbose("%s loaded", plugin_name); + return SLURM_SUCCESS; +} + +extern int fini(void) +{ + return SLURM_SUCCESS; +} + +extern int acct_gather_filesystem_p_node_update(void) +{ + return SLURM_SUCCESS; +} + +extern void acct_gather_filesystem_p_conf_set(s_p_hashtbl_t *tbl) +{ + return; +} + +extern void acct_gather_filesystem_p_conf_options(s_p_options_t **full_options, + int *full_options_cnt) +{ + return; +} + diff --git a/src/plugins/jobacct_gather/linux/jobacct_gather_linux.c b/src/plugins/jobacct_gather/linux/jobacct_gather_linux.c index c6c0b26ab812a3e02d109136c2e751371c053694..d0902c768a7bc8c188e2a790f771bbe301a9feba 100644 --- a/src/plugins/jobacct_gather/linux/jobacct_gather_linux.c +++ b/src/plugins/jobacct_gather/linux/jobacct_gather_linux.c @@ -117,9 +117,6 @@ static int _get_sys_interface_freq_line(uint32_t cpu, char *filename, static uint32_t _update_weighted_freq(struct jobacctinfo *jobacct, char * sbuf); -/* Default path to lustre stats */ -const char proc_base_path[] = "/proc/fs/lustre/"; - /* * _get_offspring_data() -- collect memory usage data for the offspring @@ -481,136 +478,6 @@ extern int fini (void) return SLURM_SUCCESS; } -/** - * is lustre fs supported - **/ -static int _check_lustre_fs() -{ - static bool set = false; - static int rc = SLURM_SUCCESS; - - if (!set) { - uint32_t profile = 0; - char lustre_directory[BUFSIZ]; - DIR *proc_dir; - - set = true; - acct_gather_profile_g_get(ACCT_GATHER_PROFILE_RUNNING, - &profile); - if ((profile & ACCT_GATHER_PROFILE_LUSTRE)) { - sprintf(lustre_directory, "%s/llite", proc_base_path); - proc_dir = opendir(proc_base_path); - if (!proc_dir) { - debug2("not able to read %s", - lustre_directory); - rc = SLURM_FAILURE; - } - closedir(proc_dir); - } else - rc = SLURM_ERROR; - } - - return rc; -} - -/** - * read counters from all mounted lustre fs - */ -static int _read_lustre_counters(void ) -{ - char lustre_dir[PATH_MAX]; - char path_stats[PATH_MAX]; - DIR *proc_dir; - struct dirent *entry; - FILE *fff; - char buffer[BUFSIZ]; - uint64_t lustre_nb_writes = 0; - uint64_t lustre_nb_reads = 0; - uint64_t all_lustre_nb_writes = 0; - uint64_t all_lustre_nb_reads = 0; - uint64_t lustre_write_bytes = 0; - uint64_t lustre_read_bytes = 0; - uint64_t all_lustre_write_bytes = 0; - uint64_t all_lustre_read_bytes = 0; - struct lustre_data *lus; - - - sprintf(lustre_dir, "%s/llite", proc_base_path); - - proc_dir = opendir(lustre_dir); - if (proc_dir == NULL) { - error("Cannot open %s\n", lustre_dir); - return SLURM_FAILURE; - } - - entry = readdir(proc_dir); - - while (entry != NULL) { - snprintf(path_stats, PATH_MAX - 1, "%s/%s/stats", lustre_dir, - entry->d_name); - debug3("Found file %s\n", path_stats); - - fff = fopen(path_stats, "r"); - if (fff) { - while(1) { - if (!fgets(buffer,BUFSIZ,fff)) - break; - - if (strstr(buffer, "write_bytes")) { - sscanf(buffer, - "%*s %"PRIu64" %*s %*s " - "%*d %*d %"PRIu64"", - &lustre_nb_writes, - &lustre_write_bytes); - debug3("Lustre Counter " - "%"PRIu64" " - "write_bytes %"PRIu64" " - "writes\n", - lustre_write_bytes, - lustre_nb_writes); - } - - if (strstr(buffer, "read_bytes")) { - sscanf(buffer, - "%*s %"PRIu64" %*s %*s " - "%*d %*d %"PRIu64"", - &lustre_nb_reads, - &lustre_read_bytes); - debug3("Lustre Counter " - "%"PRIu64" " - "read_bytes %"PRIu64" " - "reads\n", - lustre_read_bytes, - lustre_nb_reads); - } - } - fclose(fff); - } - entry = readdir(proc_dir); - all_lustre_write_bytes += lustre_write_bytes; - all_lustre_read_bytes += lustre_read_bytes; - all_lustre_nb_writes += lustre_nb_writes; - all_lustre_nb_reads += lustre_nb_reads; - } - closedir(proc_dir); - - lus = xmalloc(sizeof(struct lustre_data)); - memset(lus, 0, sizeof(struct lustre_data)); - - lus->reads = all_lustre_nb_reads; - lus->writes = all_lustre_nb_writes; - lus->read_size = (double) all_lustre_read_bytes / 1048576; - lus->write_size = (double) all_lustre_write_bytes / 1048576; - acct_gather_profile_g_add_sample_data(ACCT_GATHER_PROFILE_LUSTRE, lus); - - debug3("Collection of Lustre counters Finished"); - xfree(lus); - - return SLURM_SUCCESS; -} - - - /* * jobacct_gather_p_poll_data() - Build a table of all current processes * @@ -842,9 +709,6 @@ extern void jobacct_gather_p_poll_data( } list_iterator_destroy(itr); - if (_check_lustre_fs() == SLURM_SUCCESS) - _read_lustre_counters(); - jobacct_gather_handle_mem_limit(total_job_mem, total_job_vsize); finished: