iprutils: Implements live dump functionality
Implements live dump functionality for CLI. Signed-off-by: Kleber Sacilotto de Souza <klebers@linux.vnet.ibm.com
This commit is contained in:
parent
6ed2d3ccc9
commit
54909c2a36
4 changed files with 175 additions and 1 deletions
18
iprconfig.c
18
iprconfig.c
|
|
@ -15622,6 +15622,23 @@ static int set_ioa_caching(char **args, int num_args)
|
|||
return rc;
|
||||
}
|
||||
|
||||
/**
|
||||
* get_live_dump -
|
||||
* @args: argument vector
|
||||
* @num_args: number of arguments
|
||||
*
|
||||
* Returns:
|
||||
* 0 if success / non-zero on failure
|
||||
**/
|
||||
static int get_live_dump (char **args, int num_args)
|
||||
{
|
||||
struct ipr_dev *dev = find_gen_dev(args[0]);
|
||||
|
||||
if (dev)
|
||||
return ipr_get_live_dump(dev->ioa);
|
||||
return -ENXIO;
|
||||
}
|
||||
|
||||
static const struct {
|
||||
char *cmd;
|
||||
int min_args;
|
||||
|
|
@ -15721,6 +15738,7 @@ static const struct {
|
|||
{ "set-bus-speed", 3, 0, 3, set_bus_speed, "sg5 0 320" },
|
||||
{ "set-bus-width", 3, 0, 3, set_bus_width, "sg5 0 16" },
|
||||
{ "raid-migrate", 3, 1, 0, raid_migrate_cmd, "-r 10 [-s 256] sda sg6 sg7" },
|
||||
{ "get-live-dump", 1, 0, 1, get_live_dump, "sg5" },
|
||||
};
|
||||
|
||||
/**
|
||||
|
|
|
|||
|
|
@ -20,7 +20,6 @@
|
|||
#include <sys/mman.h>
|
||||
|
||||
#define IPRDUMP_SIZE (8 * 1024 * 1024)
|
||||
#define IPRDUMP_DIR "/var/log/"
|
||||
#define MAX_DUMP_FILES 4
|
||||
#define TOOL_NAME "iprdump"
|
||||
#define DUMP_PREFIX TOOL_NAME"."
|
||||
|
|
|
|||
153
iprlib.c
153
iprlib.c
|
|
@ -3869,6 +3869,159 @@ int ipr_query_res_redundancy_info(struct ipr_dev *dev,
|
|||
return rc;
|
||||
}
|
||||
|
||||
/**
|
||||
* get_livedump_fname -
|
||||
* @ioa: ipr_ioa struct
|
||||
* @fname: string to return the filename
|
||||
* @max: max size of fname
|
||||
*
|
||||
* Returns:
|
||||
* negative on failure / otherwise length of the file name
|
||||
*
|
||||
**/
|
||||
static int get_livedump_fname(struct ipr_ioa *ioa, char *fname, int max)
|
||||
{
|
||||
time_t cur_time, rc;
|
||||
struct tm *cur_tm;
|
||||
char time_str[100];
|
||||
int len;
|
||||
|
||||
fname[0] = '\0';
|
||||
rc = time(&cur_time);
|
||||
if (rc == ((time_t)-1))
|
||||
return -EIO;
|
||||
|
||||
cur_tm = localtime(&cur_time);
|
||||
if (!cur_tm)
|
||||
return -EIO;
|
||||
strftime(time_str, sizeof(time_str), "%Y%m%d.%H%M", cur_tm);
|
||||
|
||||
len = snprintf(fname, max, "ipr-%04X-%s-dump-%s", ioa->ccin,
|
||||
ioa->pci_address, time_str);
|
||||
|
||||
return len;
|
||||
}
|
||||
|
||||
#define IPR_MAX_LIVE_DUMP_SIZE (16 * 1024 * 1024)
|
||||
|
||||
/**
|
||||
* get_scsi_max_xfer_len -
|
||||
* @fd: IOA sg file descriptor
|
||||
*
|
||||
* Returns:
|
||||
* 0 on failure / otherwise max scatter-gather transfer length
|
||||
*
|
||||
**/
|
||||
static int get_scsi_max_xfer_len(int fd)
|
||||
{
|
||||
int rc, max_tablesize, max_scsi_len;
|
||||
struct sysfs_module *sysfs_module;
|
||||
struct sysfs_attribute *sysfs_attr;
|
||||
|
||||
sysfs_module = sysfs_open_module("sg");
|
||||
if (!sysfs_module) {
|
||||
syslog_dbg("Failed to open sg module. %m\n");
|
||||
return 0;
|
||||
}
|
||||
|
||||
sysfs_attr = sysfs_get_module_parm(sysfs_module, "scatter_elem_sz");
|
||||
if (!sysfs_attr) {
|
||||
syslog_dbg("Failed to open scatter_elem_sz parameter from sg module. %m\n");
|
||||
return 0;
|
||||
}
|
||||
|
||||
rc = ioctl(fd, SG_GET_SG_TABLESIZE, &max_tablesize);
|
||||
if (rc) {
|
||||
syslog_dbg("Unable to get device scatter-gather table size. %m\n");
|
||||
return 0;
|
||||
}
|
||||
|
||||
max_scsi_len = max_tablesize * atoi(sysfs_attr->value);
|
||||
|
||||
if (max_scsi_len < IPR_MAX_LIVE_DUMP_SIZE)
|
||||
return max_scsi_len;
|
||||
else
|
||||
return IPR_MAX_LIVE_DUMP_SIZE;
|
||||
}
|
||||
|
||||
/**
|
||||
* ipr_get_live_dump -
|
||||
* @dev: ipr dev struct
|
||||
* @info: ipr_res_redundancy_info struct
|
||||
*
|
||||
* Returns:
|
||||
* 0 if success / non-zero on failure
|
||||
*
|
||||
**/
|
||||
int ipr_get_live_dump(struct ipr_ioa *ioa)
|
||||
{
|
||||
char *name = ioa->ioa.gen_name;
|
||||
struct sense_data_t sense_data;
|
||||
u8 cdb[IPR_CCB_CDB_LEN], *buf;
|
||||
char dump_file[100], dump_path[100];
|
||||
int rc, fd, fd_dump, buff_len;
|
||||
|
||||
if (strlen(name) == 0)
|
||||
return -ENOENT;
|
||||
|
||||
fd = open(name, O_RDWR);
|
||||
if (fd <= 1) {
|
||||
if (!strcmp(tool_name, "iprconfig") || ipr_debug)
|
||||
syslog(LOG_ERR, "Could not open %s. %m\n", name);
|
||||
return errno;
|
||||
}
|
||||
|
||||
buff_len = get_scsi_max_xfer_len(fd);
|
||||
if (buff_len == 0) {
|
||||
rc = -EPERM;
|
||||
goto out;
|
||||
}
|
||||
|
||||
memset(cdb, 0, IPR_CCB_CDB_LEN);
|
||||
cdb[0] = IPR_IOA_SERVICE_ACTION;
|
||||
cdb[1] = IPR_LIVE_DUMP;
|
||||
cdb[10] = buff_len >> 24;
|
||||
cdb[11] = (buff_len >> 16) & 0xff;
|
||||
cdb[12] = (buff_len >> 8) & 0xff;
|
||||
cdb[13] = buff_len & 0xff;
|
||||
|
||||
buf = (u8*) malloc(buff_len);
|
||||
|
||||
rc = sg_ioctl(fd, cdb, buf, buff_len, SG_DXFER_FROM_DEV,
|
||||
&sense_data, IPR_INTERNAL_DEV_TIMEOUT);
|
||||
|
||||
if (rc) {
|
||||
ioa_cmd_err(ioa, &sense_data, "Live Dump", rc);
|
||||
goto out_free;
|
||||
}
|
||||
|
||||
rc = get_livedump_fname(ioa, dump_file, sizeof(dump_file));
|
||||
if (rc < 0) {
|
||||
syslog_dbg("Failed to create a live dump file name.\n");
|
||||
goto out_free;
|
||||
}
|
||||
|
||||
snprintf(dump_path, sizeof(dump_path), "%s%s", IPRDUMP_DIR, dump_file);
|
||||
fd_dump = creat(dump_path, S_IRUSR);
|
||||
if (fd_dump < 0) {
|
||||
syslog(LOG_ERR, "Could not open %s. %m\n", dump_path);
|
||||
rc = fd_dump;
|
||||
goto out_free;
|
||||
}
|
||||
|
||||
rc = write(fd_dump, buf, buff_len);
|
||||
if (rc != buff_len)
|
||||
syslog(LOG_ERR, "Could not write dump on file %s. %m\n", dump_path);
|
||||
|
||||
close(fd_dump);
|
||||
|
||||
out_free:
|
||||
free(buf);
|
||||
out:
|
||||
close(fd);
|
||||
return rc;
|
||||
}
|
||||
|
||||
/**
|
||||
* ipr_set_array_asym_access -
|
||||
* @dev: ipr_dev struct
|
||||
|
|
|
|||
4
iprlib.h
4
iprlib.h
|
|
@ -64,6 +64,8 @@
|
|||
#define FIRMWARE_HOTPLUG_CONFIG_FILE "/etc/hotplug/firmware.agent"
|
||||
#define FIRMWARE_HOTPLUG_DEFAULT_DIR LINUX_UCODE_BASE_DIR
|
||||
|
||||
#define IPRDUMP_DIR "/var/log/"
|
||||
|
||||
#define IPR_JBOD_BLOCK_SIZE 512
|
||||
#define IPR_DEFAULT_AF_BLOCK_SIZE 522
|
||||
#define IOCTL_BUFFER_SIZE 512
|
||||
|
|
@ -150,6 +152,7 @@
|
|||
#define IPR_QUERY_RES_REDUNDANCY_INFO 0x13
|
||||
#define IPR_CHANGE_CACHE_PARAMETERS 0x14
|
||||
#define IPR_QUERY_CACHE_PARAMETERS 0x16
|
||||
#define IPR_LIVE_DUMP 0x31
|
||||
#define IPR_EVALUATE_DEVICE 0xE4
|
||||
#define SKIP_READ 0xE8
|
||||
#define SKIP_WRITE 0xEA
|
||||
|
|
@ -2332,6 +2335,7 @@ int ipr_get_blk_size(struct ipr_dev *);
|
|||
u32 get_ioa_ucode_version(char *);
|
||||
int ipr_improper_device_type(struct ipr_dev *);
|
||||
int ipr_get_fw_version(struct ipr_dev *, u8 release_level[4]);
|
||||
int ipr_get_live_dump(struct ipr_ioa *);
|
||||
|
||||
static inline u32 ipr_get_dev_res_handle(struct ipr_ioa *ioa, struct ipr_dev_record *dev_rcd)
|
||||
{
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue