procfs: Support multiple reads of e.g. /proc/*/maps
Refs: #1021 Change-Id: If36e1a0f3f41f0215868daf578e96775d96a59a3
This commit is contained in:
committed by
Masamichi Takagi
parent
e531ee626e
commit
895a8c4099
@@ -67,6 +67,7 @@
|
|||||||
#define SCD_MSG_PROCFS_DELETE 0x11
|
#define SCD_MSG_PROCFS_DELETE 0x11
|
||||||
#define SCD_MSG_PROCFS_REQUEST 0x12
|
#define SCD_MSG_PROCFS_REQUEST 0x12
|
||||||
#define SCD_MSG_PROCFS_ANSWER 0x13
|
#define SCD_MSG_PROCFS_ANSWER 0x13
|
||||||
|
#define SCD_MSG_PROCFS_RELEASE 0x15
|
||||||
|
|
||||||
#define SCD_MSG_DEBUG_LOG 0x20
|
#define SCD_MSG_DEBUG_LOG 0x20
|
||||||
|
|
||||||
|
|||||||
@@ -922,6 +922,303 @@ static const struct file_operations mckernel_forward = {
|
|||||||
.write = mckernel_procfs_write,
|
.write = mckernel_procfs_write,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
#define PA_NULL (-1L)
|
||||||
|
|
||||||
|
struct mckernel_procfs_buffer_info {
|
||||||
|
unsigned long top_pa;
|
||||||
|
unsigned long cur_pa;
|
||||||
|
ihk_os_t os;
|
||||||
|
int pid;
|
||||||
|
char path[0];
|
||||||
|
};
|
||||||
|
|
||||||
|
struct mckernel_procfs_buffer {
|
||||||
|
unsigned long next_pa;
|
||||||
|
unsigned long pos;
|
||||||
|
unsigned long size;
|
||||||
|
char buf[0];
|
||||||
|
};
|
||||||
|
|
||||||
|
static int mckernel_procfs_buff_open(struct inode *inode, struct file *file)
|
||||||
|
{
|
||||||
|
struct mckernel_procfs_buffer_info *info;
|
||||||
|
int pid;
|
||||||
|
int ret;
|
||||||
|
char *path;
|
||||||
|
char *path_buf;
|
||||||
|
char *p;
|
||||||
|
ihk_os_t os;
|
||||||
|
#if LINUX_VERSION_CODE < KERNEL_VERSION(3, 10, 0)
|
||||||
|
struct proc_dir_entry *dp = PDE(inode);
|
||||||
|
struct procfs_list_entry *e = dp->data;
|
||||||
|
#else
|
||||||
|
struct procfs_list_entry *e = PDE_DATA(inode);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
os = osnum_to_os(e->osnum);
|
||||||
|
if (!os) {
|
||||||
|
return -EINVAL;
|
||||||
|
}
|
||||||
|
path_buf = kmalloc(PROCFS_NAME_MAX, GFP_KERNEL);
|
||||||
|
if (!path_buf) {
|
||||||
|
return -ENOMEM;
|
||||||
|
}
|
||||||
|
path = getpath(e, path_buf, PROCFS_NAME_MAX);
|
||||||
|
p = strchr(path, '/') + 1;
|
||||||
|
ret = sscanf(p, "%d/", &pid);
|
||||||
|
if (ret != 1) {
|
||||||
|
pid = -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
info = kmalloc(sizeof(struct mckernel_procfs_buffer_info) +
|
||||||
|
strlen(path) + 1, GFP_KERNEL);
|
||||||
|
if (!info) {
|
||||||
|
kfree(path_buf);
|
||||||
|
return -ENOMEM;
|
||||||
|
}
|
||||||
|
info->top_pa = PA_NULL;
|
||||||
|
info->cur_pa = PA_NULL;
|
||||||
|
info->os = os;
|
||||||
|
info->pid = pid;
|
||||||
|
strcpy(info->path, path);
|
||||||
|
file->private_data = info;
|
||||||
|
|
||||||
|
kfree(path_buf);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int mckernel_procfs_buff_release(struct inode *inode, struct file *file)
|
||||||
|
{
|
||||||
|
struct mckernel_procfs_buffer_info *info = file->private_data;
|
||||||
|
int rc = 0;
|
||||||
|
|
||||||
|
if (!info) {
|
||||||
|
return -EIO;
|
||||||
|
}
|
||||||
|
|
||||||
|
file->private_data = NULL;
|
||||||
|
if (info->top_pa != PA_NULL) {
|
||||||
|
int ret;
|
||||||
|
struct procfs_read *r = NULL;
|
||||||
|
struct ikc_scd_packet isp;
|
||||||
|
int do_free;
|
||||||
|
|
||||||
|
r = kmalloc(sizeof(struct procfs_read), GFP_KERNEL);
|
||||||
|
if (r == NULL) {
|
||||||
|
rc = -ENOMEM;
|
||||||
|
goto out;
|
||||||
|
}
|
||||||
|
memset(r, '\0', sizeof(struct procfs_read));
|
||||||
|
r->pbuf = info->top_pa;
|
||||||
|
r->ret = -EIO; /* default */
|
||||||
|
r->fname[0] = '\0';
|
||||||
|
isp.msg = SCD_MSG_PROCFS_RELEASE;
|
||||||
|
isp.ref = 0;
|
||||||
|
isp.arg = virt_to_phys(r);
|
||||||
|
isp.pid = 0;
|
||||||
|
|
||||||
|
rc = -EIO;
|
||||||
|
ret = mcctrl_ikc_send_wait(info->os, 0,
|
||||||
|
&isp, 5 * HZ, NULL, &do_free, 1, r);
|
||||||
|
|
||||||
|
if (!do_free && ret >= 0) {
|
||||||
|
ret = -EIO;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (ret < 0) {
|
||||||
|
rc = ret;
|
||||||
|
if (ret == -ETIME) {
|
||||||
|
pr_info("%s: error: timeout (1 sec)\n",
|
||||||
|
__func__);
|
||||||
|
}
|
||||||
|
else if (ret == -ERESTARTSYS) {
|
||||||
|
rc = -ERESTART;
|
||||||
|
}
|
||||||
|
if (!do_free)
|
||||||
|
r = NULL;
|
||||||
|
goto out;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (r->ret < 0) {
|
||||||
|
rc = r->ret;
|
||||||
|
goto out;
|
||||||
|
}
|
||||||
|
rc = 0;
|
||||||
|
out:
|
||||||
|
if (r)
|
||||||
|
kfree((void *)r);
|
||||||
|
}
|
||||||
|
kfree(info);
|
||||||
|
return rc;
|
||||||
|
}
|
||||||
|
|
||||||
|
static ssize_t mckernel_procfs_buff_read(struct file *file, char __user *ubuf,
|
||||||
|
size_t nbytes, loff_t *ppos)
|
||||||
|
{
|
||||||
|
struct mckernel_procfs_buffer_info *info = file->private_data;
|
||||||
|
unsigned long phys;
|
||||||
|
struct mckernel_procfs_buffer *buf;
|
||||||
|
int pos = *ppos;
|
||||||
|
ssize_t l = 0;
|
||||||
|
int done = 0;
|
||||||
|
ihk_os_t os;
|
||||||
|
|
||||||
|
if (nbytes <= 0 || *ppos < 0) {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!info) {
|
||||||
|
return -EIO;
|
||||||
|
}
|
||||||
|
|
||||||
|
os = info->os;
|
||||||
|
if (info->top_pa == PA_NULL) {
|
||||||
|
int ret;
|
||||||
|
int pid = info->pid;
|
||||||
|
struct procfs_read *r = NULL;
|
||||||
|
struct ikc_scd_packet isp;
|
||||||
|
struct mcctrl_usrdata *udp = NULL;
|
||||||
|
struct mcctrl_per_proc_data *ppd = NULL;
|
||||||
|
int do_free;
|
||||||
|
|
||||||
|
udp = ihk_host_os_get_usrdata(os);
|
||||||
|
if (!udp) {
|
||||||
|
pr_err("%s: no MCCTRL data found for OS\n",
|
||||||
|
__func__);
|
||||||
|
return -EINVAL;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (pid > 0) {
|
||||||
|
ppd = mcctrl_get_per_proc_data(udp, pid);
|
||||||
|
|
||||||
|
if (unlikely(!ppd)) {
|
||||||
|
pr_err("%s: no per-process structure for PID %d",
|
||||||
|
__func__, pid);
|
||||||
|
return -EINVAL;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
r = kmalloc(sizeof(struct procfs_read), GFP_KERNEL);
|
||||||
|
if (r == NULL) {
|
||||||
|
l = -ENOMEM;
|
||||||
|
done = 1;
|
||||||
|
goto out;
|
||||||
|
}
|
||||||
|
memset(r, '\0', sizeof(struct procfs_read));
|
||||||
|
r->pbuf = PA_NULL;
|
||||||
|
r->ret = -EIO; /* default */
|
||||||
|
strncpy((char *)r->fname, info->path, PROCFS_NAME_MAX);
|
||||||
|
isp.msg = SCD_MSG_PROCFS_REQUEST;
|
||||||
|
isp.ref = 0;
|
||||||
|
isp.arg = virt_to_phys(r);
|
||||||
|
isp.pid = pid;
|
||||||
|
|
||||||
|
l = -EIO;
|
||||||
|
done = 1;
|
||||||
|
ret = mcctrl_ikc_send_wait(os,
|
||||||
|
(pid > 0) ? ppd->ikc_target_cpu : 0,
|
||||||
|
&isp, 5 * HZ, NULL, &do_free, 1, r);
|
||||||
|
|
||||||
|
if (!do_free && ret >= 0) {
|
||||||
|
ret = -EIO;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (ret < 0) {
|
||||||
|
l = ret;
|
||||||
|
if (ret == -ETIME) {
|
||||||
|
pr_info("%s: error: timeout (1 sec)\n",
|
||||||
|
__func__);
|
||||||
|
}
|
||||||
|
else if (ret == -ERESTARTSYS) {
|
||||||
|
l = -ERESTART;
|
||||||
|
}
|
||||||
|
if (!do_free)
|
||||||
|
r = NULL;
|
||||||
|
goto out;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (r->ret < 0) {
|
||||||
|
l = r->ret;
|
||||||
|
goto out;
|
||||||
|
}
|
||||||
|
|
||||||
|
done = 0;
|
||||||
|
l = 0;
|
||||||
|
info->top_pa = info->cur_pa = r->pbuf;
|
||||||
|
|
||||||
|
out:
|
||||||
|
if (ppd)
|
||||||
|
mcctrl_put_per_proc_data(ppd);
|
||||||
|
if (r)
|
||||||
|
kfree((void *)r);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (info->cur_pa == PA_NULL) {
|
||||||
|
info->cur_pa = info->top_pa;
|
||||||
|
}
|
||||||
|
|
||||||
|
while (!done && info->cur_pa != PA_NULL) {
|
||||||
|
long bpos;
|
||||||
|
long bsize;
|
||||||
|
|
||||||
|
phys = ihk_device_map_memory(ihk_os_to_dev(os), info->cur_pa,
|
||||||
|
PAGE_SIZE);
|
||||||
|
#ifdef CONFIG_MIC
|
||||||
|
buf = ioremap_wc(phys, PAGE_SIZE);
|
||||||
|
#else
|
||||||
|
buf = ihk_device_map_virtual(ihk_os_to_dev(os), phys,
|
||||||
|
PAGE_SIZE, NULL, 0);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
if (pos < buf->pos) {
|
||||||
|
info->cur_pa = info->top_pa;
|
||||||
|
goto rep;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (pos >= buf->pos + buf->size) {
|
||||||
|
info->cur_pa = buf->next_pa;
|
||||||
|
goto rep;
|
||||||
|
}
|
||||||
|
|
||||||
|
bpos = pos - buf->pos;
|
||||||
|
bsize = (buf->pos + buf->size) - pos;
|
||||||
|
if (bsize > (nbytes - l)) {
|
||||||
|
bsize = nbytes - l;
|
||||||
|
}
|
||||||
|
if (copy_to_user(ubuf, buf->buf + bpos, bsize)) {
|
||||||
|
done = 1;
|
||||||
|
pos = *ppos;
|
||||||
|
l = -EFAULT;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
ubuf += bsize;
|
||||||
|
pos += bsize;
|
||||||
|
l += bsize;
|
||||||
|
if (l == nbytes) {
|
||||||
|
done = 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
rep:
|
||||||
|
#ifdef CONFIG_MIC
|
||||||
|
iounmap(buf);
|
||||||
|
#else
|
||||||
|
ihk_device_unmap_virtual(ihk_os_to_dev(os), buf, PAGE_SIZE);
|
||||||
|
#endif
|
||||||
|
ihk_device_unmap_memory(ihk_os_to_dev(os), phys, PAGE_SIZE);
|
||||||
|
};
|
||||||
|
|
||||||
|
*ppos = pos;
|
||||||
|
return l;
|
||||||
|
}
|
||||||
|
|
||||||
|
static const struct file_operations mckernel_buff_io = {
|
||||||
|
.llseek = mckernel_procfs_lseek,
|
||||||
|
.read = mckernel_procfs_buff_read,
|
||||||
|
.write = NULL,
|
||||||
|
.open = mckernel_procfs_buff_open,
|
||||||
|
.release = mckernel_procfs_buff_release,
|
||||||
|
};
|
||||||
|
|
||||||
static const struct procfs_entry tid_entry_stuff[] = {
|
static const struct procfs_entry tid_entry_stuff[] = {
|
||||||
// PROC_REG("auxv", S_IRUSR, NULL),
|
// PROC_REG("auxv", S_IRUSR, NULL),
|
||||||
// PROC_REG("clear_refs", S_IWUSR, NULL),
|
// PROC_REG("clear_refs", S_IWUSR, NULL),
|
||||||
@@ -931,10 +1228,10 @@ static const struct procfs_entry tid_entry_stuff[] = {
|
|||||||
// PROC_LNK("exe", mckernel_readlink),
|
// PROC_LNK("exe", mckernel_readlink),
|
||||||
// PROC_REG("limits", S_IRUSR|S_IWUSR, NULL),
|
// PROC_REG("limits", S_IRUSR|S_IWUSR, NULL),
|
||||||
// PROC_REG("maps", S_IRUGO, NULL),
|
// PROC_REG("maps", S_IRUGO, NULL),
|
||||||
PROC_REG("mem", S_IRUSR|S_IWUSR, NULL),
|
PROC_REG("mem", 0600, NULL),
|
||||||
// PROC_REG("pagemap", S_IRUGO, NULL),
|
// PROC_REG("pagemap", S_IRUGO, NULL),
|
||||||
// PROC_REG("smaps", S_IRUGO, NULL),
|
// PROC_REG("smaps", S_IRUGO, NULL),
|
||||||
PROC_REG("stat", S_IRUGO, NULL),
|
PROC_REG("stat", 0444, &mckernel_buff_io),
|
||||||
// PROC_REG("statm", S_IRUGO, NULL),
|
// PROC_REG("statm", S_IRUGO, NULL),
|
||||||
// PROC_REG("status", S_IRUGO, NULL),
|
// PROC_REG("status", S_IRUGO, NULL),
|
||||||
// PROC_REG("syscall", S_IRUGO, NULL),
|
// PROC_REG("syscall", S_IRUGO, NULL),
|
||||||
@@ -943,26 +1240,26 @@ static const struct procfs_entry tid_entry_stuff[] = {
|
|||||||
};
|
};
|
||||||
|
|
||||||
static const struct procfs_entry pid_entry_stuff[] = {
|
static const struct procfs_entry pid_entry_stuff[] = {
|
||||||
PROC_REG("auxv", S_IRUSR, NULL),
|
PROC_REG("auxv", 0400, &mckernel_buff_io),
|
||||||
/* Support the case where McKernel process retrieves its job-id under the Fujitsu TCS suite. */
|
/* Support the case where McKernel process retrieves its job-id under the Fujitsu TCS suite. */
|
||||||
// PROC_REG("cgroup", S_IXUSR, NULL),
|
// PROC_REG("cgroup", S_IXUSR, NULL),
|
||||||
// PROC_REG("clear_refs", S_IWUSR, NULL),
|
// PROC_REG("clear_refs", S_IWUSR, NULL),
|
||||||
PROC_REG("cmdline", S_IRUGO, NULL),
|
PROC_REG("cmdline", 0444, &mckernel_buff_io),
|
||||||
// PROC_REG("comm", S_IRUGO|S_IWUSR, NULL),
|
// PROC_REG("comm", S_IRUGO|S_IWUSR, NULL),
|
||||||
// PROC_REG("coredump_filter", S_IRUGO|S_IWUSR, NULL),
|
// PROC_REG("coredump_filter", S_IRUGO|S_IWUSR, NULL),
|
||||||
PROC_REG("cpuset", S_IXUSR, NULL),
|
// PROC_REG("cpuset", S_IRUGO, NULL),
|
||||||
// PROC_REG("environ", S_IRUSR, NULL),
|
// PROC_REG("environ", S_IRUSR, NULL),
|
||||||
// PROC_LNK("exe", mckernel_readlink),
|
// PROC_LNK("exe", mckernel_readlink),
|
||||||
// PROC_REG("limits", S_IRUSR|S_IWUSR, NULL),
|
// PROC_REG("limits", S_IRUSR|S_IWUSR, NULL),
|
||||||
PROC_REG("maps", S_IRUGO, NULL),
|
PROC_REG("maps", 0444, &mckernel_buff_io),
|
||||||
PROC_REG("mem", S_IRUSR|S_IWUSR, NULL),
|
PROC_REG("mem", 0600, NULL),
|
||||||
PROC_REG("pagemap", S_IRUGO, NULL),
|
PROC_REG("pagemap", 0444, NULL),
|
||||||
PROC_REG("smaps", S_IRUGO, NULL),
|
// PROC_REG("smaps", S_IRUGO, NULL),
|
||||||
// PROC_REG("stat", S_IRUGO, NULL),
|
// PROC_REG("stat", 0444, &mckernel_buff_io),
|
||||||
// PROC_REG("statm", S_IRUGO, NULL),
|
// PROC_REG("statm", S_IRUGO, NULL),
|
||||||
PROC_REG("status", S_IRUGO, NULL),
|
PROC_REG("status", 0444, &mckernel_buff_io),
|
||||||
// PROC_REG("syscall", S_IRUGO, NULL),
|
// PROC_REG("syscall", S_IRUGO, NULL),
|
||||||
PROC_DIR("task", S_IRUGO|S_IXUGO),
|
PROC_DIR("task", 0555),
|
||||||
// PROC_REG("wchan", S_IRUGO, NULL),
|
// PROC_REG("wchan", S_IRUGO, NULL),
|
||||||
PROC_TERM
|
PROC_TERM
|
||||||
};
|
};
|
||||||
@@ -970,14 +1267,14 @@ static const struct procfs_entry pid_entry_stuff[] = {
|
|||||||
static const struct procfs_entry base_entry_stuff[] = {
|
static const struct procfs_entry base_entry_stuff[] = {
|
||||||
// PROC_REG("cmdline", S_IRUGO, NULL),
|
// PROC_REG("cmdline", S_IRUGO, NULL),
|
||||||
#ifdef POSTK_DEBUG_ARCH_DEP_42 /* /proc/cpuinfo support added. */
|
#ifdef POSTK_DEBUG_ARCH_DEP_42 /* /proc/cpuinfo support added. */
|
||||||
PROC_REG("cpuinfo", S_IRUGO, NULL),
|
PROC_REG("cpuinfo", 0444, &mckernel_buff_io),
|
||||||
#else /* POSTK_DEBUG_ARCH_DEP_42 */
|
#else /* POSTK_DEBUG_ARCH_DEP_42 */
|
||||||
// PROC_REG("cpuinfo", S_IRUGO, NULL),
|
// PROC_REG("cpuinfo", S_IRUGO, NULL),
|
||||||
#endif /* POSTK_DEBUG_ARCH_DEP_42 */
|
#endif /* POSTK_DEBUG_ARCH_DEP_42 */
|
||||||
// PROC_REG("meminfo", S_IRUGO, NULL),
|
// PROC_REG("meminfo", S_IRUGO, NULL),
|
||||||
// PROC_REG("pagetypeinfo",S_IRUGO, NULL),
|
// PROC_REG("pagetypeinfo",S_IRUGO, NULL),
|
||||||
// PROC_REG("softirq", S_IRUGO, NULL),
|
// PROC_REG("softirq", S_IRUGO, NULL),
|
||||||
PROC_REG("stat", S_IRUGO, NULL),
|
PROC_REG("stat", 0444, &mckernel_buff_io),
|
||||||
// PROC_REG("uptime", S_IRUGO, NULL),
|
// PROC_REG("uptime", S_IRUGO, NULL),
|
||||||
// PROC_REG("version", S_IRUGO, NULL),
|
// PROC_REG("version", S_IRUGO, NULL),
|
||||||
// PROC_REG("vmallocinfo",S_IRUSR, NULL),
|
// PROC_REG("vmallocinfo",S_IRUSR, NULL),
|
||||||
|
|||||||
@@ -667,6 +667,7 @@ static int syscall_packet_handler(struct ihk_ikc_channel_desc *c,
|
|||||||
break;
|
break;
|
||||||
|
|
||||||
case SCD_MSG_PROCFS_REQUEST:
|
case SCD_MSG_PROCFS_REQUEST:
|
||||||
|
case SCD_MSG_PROCFS_RELEASE:
|
||||||
pckt.msg = SCD_MSG_PROCFS_ANSWER;
|
pckt.msg = SCD_MSG_PROCFS_ANSWER;
|
||||||
pckt.ref = packet->ref;
|
pckt.ref = packet->ref;
|
||||||
pckt.arg = packet->arg;
|
pckt.arg = packet->arg;
|
||||||
|
|||||||
@@ -49,6 +49,7 @@
|
|||||||
#define SCD_MSG_PROCFS_DELETE 0x11
|
#define SCD_MSG_PROCFS_DELETE 0x11
|
||||||
#define SCD_MSG_PROCFS_REQUEST 0x12
|
#define SCD_MSG_PROCFS_REQUEST 0x12
|
||||||
#define SCD_MSG_PROCFS_ANSWER 0x13
|
#define SCD_MSG_PROCFS_ANSWER 0x13
|
||||||
|
#define SCD_MSG_PROCFS_RELEASE 0x15
|
||||||
|
|
||||||
#define SCD_MSG_DEBUG_LOG 0x20
|
#define SCD_MSG_DEBUG_LOG 0x20
|
||||||
|
|
||||||
|
|||||||
435
kernel/procfs.c
435
kernel/procfs.c
@@ -40,6 +40,78 @@ extern int sprintf(char * buf, const char *fmt, ...);
|
|||||||
extern int sscanf(const char * buf, const char * fmt, ...);
|
extern int sscanf(const char * buf, const char * fmt, ...);
|
||||||
extern int scnprintf(char * buf, size_t size, const char *fmt, ...);
|
extern int scnprintf(char * buf, size_t size, const char *fmt, ...);
|
||||||
|
|
||||||
|
struct mckernel_procfs_buffer {
|
||||||
|
unsigned long next_pa;
|
||||||
|
unsigned long pos;
|
||||||
|
unsigned long size;
|
||||||
|
char buf[0];
|
||||||
|
};
|
||||||
|
|
||||||
|
#define PA_NULL (-1L)
|
||||||
|
|
||||||
|
static struct mckernel_procfs_buffer *buf_alloc(unsigned long *phys, long pos)
|
||||||
|
{
|
||||||
|
struct mckernel_procfs_buffer *buf;
|
||||||
|
|
||||||
|
buf = ihk_mc_alloc_pages(1, IHK_MC_AP_NOWAIT);
|
||||||
|
if (!buf)
|
||||||
|
return NULL;
|
||||||
|
buf->next_pa = PA_NULL;
|
||||||
|
buf->pos = pos;
|
||||||
|
buf->size = 0;
|
||||||
|
if (phys)
|
||||||
|
*phys = virt_to_phys(buf);
|
||||||
|
return buf;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void buf_free(unsigned long phys)
|
||||||
|
{
|
||||||
|
struct mckernel_procfs_buffer *pbuf;
|
||||||
|
unsigned long next;
|
||||||
|
|
||||||
|
while (phys != PA_NULL) {
|
||||||
|
pbuf = phys_to_virt(phys);
|
||||||
|
next = pbuf->next_pa;
|
||||||
|
ihk_mc_free_pages(pbuf, 1);
|
||||||
|
phys = next;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static int buf_add(struct mckernel_procfs_buffer **top,
|
||||||
|
struct mckernel_procfs_buffer **cur, void *buf, int l)
|
||||||
|
{
|
||||||
|
int pos = 0;
|
||||||
|
int r;
|
||||||
|
int bufmax = PAGE_SIZE - sizeof(struct mckernel_procfs_buffer);
|
||||||
|
char *chr = buf;
|
||||||
|
|
||||||
|
if (!*top) {
|
||||||
|
*top = *cur = buf_alloc(NULL, 0);
|
||||||
|
if (!*top)
|
||||||
|
return -ENOMEM;
|
||||||
|
}
|
||||||
|
while (l) {
|
||||||
|
r = bufmax - (*cur)->size;
|
||||||
|
if (!r) {
|
||||||
|
*cur = buf_alloc(&(*cur)->next_pa, (*cur)->pos +
|
||||||
|
bufmax);
|
||||||
|
if (!*cur) {
|
||||||
|
buf_free(virt_to_phys(*top));
|
||||||
|
return -ENOMEM;
|
||||||
|
}
|
||||||
|
r = bufmax;
|
||||||
|
}
|
||||||
|
if (r > l) {
|
||||||
|
r = l;
|
||||||
|
}
|
||||||
|
memcpy((*cur)->buf + (*cur)->size, chr + pos, r);
|
||||||
|
l -= r;
|
||||||
|
pos += r;
|
||||||
|
(*cur)->size += r;
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
procfs_thread_ctl(struct thread *thread, int msg)
|
procfs_thread_ctl(struct thread *thread, int msg)
|
||||||
{
|
{
|
||||||
@@ -85,13 +157,17 @@ int process_procfs_request(struct ikc_scd_packet *rpacket)
|
|||||||
struct procfs_read *r;
|
struct procfs_read *r;
|
||||||
int osnum = ihk_mc_get_osnum();
|
int osnum = ihk_mc_get_osnum();
|
||||||
int rosnum, ret, pid, tid, ans = -EIO, eof = 0;
|
int rosnum, ret, pid, tid, ans = -EIO, eof = 0;
|
||||||
char *buf, *p;
|
char *buf, *p = NULL;
|
||||||
|
char *vbuf = NULL;
|
||||||
|
char *tmp = NULL;
|
||||||
struct mcs_rwlock_node_irqsave lock;
|
struct mcs_rwlock_node_irqsave lock;
|
||||||
unsigned long offset;
|
unsigned long offset;
|
||||||
int count;
|
int count;
|
||||||
int npages;
|
int npages;
|
||||||
int readwrite = 0;
|
int readwrite = 0;
|
||||||
int err = -EIO;
|
int err = -EIO;
|
||||||
|
struct mckernel_procfs_buffer *buf_top = NULL;
|
||||||
|
struct mckernel_procfs_buffer *buf_cur = NULL;
|
||||||
|
|
||||||
dprintf("process_procfs_request: invoked.\n");
|
dprintf("process_procfs_request: invoked.\n");
|
||||||
|
|
||||||
@@ -100,27 +176,55 @@ int process_procfs_request(struct ikc_scd_packet *rpacket)
|
|||||||
dprintf("parg: %x\n", parg);
|
dprintf("parg: %x\n", parg);
|
||||||
r = ihk_mc_map_virtual(parg, 1, PTATTR_WRITABLE | PTATTR_ACTIVE);
|
r = ihk_mc_map_virtual(parg, 1, PTATTR_WRITABLE | PTATTR_ACTIVE);
|
||||||
if (r == NULL) {
|
if (r == NULL) {
|
||||||
|
ihk_mc_unmap_memory(NULL, parg, sizeof(struct procfs_read));
|
||||||
kprintf("ERROR: process_procfs_request: got a null procfs_read structure.\n");
|
kprintf("ERROR: process_procfs_request: got a null procfs_read structure.\n");
|
||||||
goto dataunavail;
|
goto err;
|
||||||
}
|
}
|
||||||
dprintf("r: %p\n", r);
|
dprintf("r: %p\n", r);
|
||||||
|
|
||||||
dprintf("remote pbuf: %x\n", r->pbuf);
|
if (rpacket->msg == SCD_MSG_PROCFS_RELEASE) {
|
||||||
pbuf = ihk_mc_map_memory(NULL, r->pbuf, r->count);
|
struct mckernel_procfs_buffer *pbuf;
|
||||||
dprintf("pbuf: %x\n", pbuf);
|
unsigned long phys;
|
||||||
count = r->count + ((uintptr_t)pbuf & (PAGE_SIZE - 1));
|
unsigned long next;
|
||||||
npages = (count + (PAGE_SIZE - 1)) / PAGE_SIZE;
|
|
||||||
buf = ihk_mc_map_virtual(pbuf, npages, PTATTR_WRITABLE | PTATTR_ACTIVE);
|
for (phys = r->pbuf; phys != PA_NULL; phys = next) {
|
||||||
dprintf("buf: %p\n", buf);
|
pbuf = phys_to_virt(phys);
|
||||||
if (buf == NULL) {
|
next = pbuf->next_pa;
|
||||||
kprintf("ERROR: process_procfs_request: got a null buffer.\n");
|
ihk_mc_free_pages(pbuf, 1);
|
||||||
goto bufunavail;
|
}
|
||||||
|
r->ret = 0;
|
||||||
|
err = 0;
|
||||||
|
goto err;
|
||||||
}
|
}
|
||||||
|
|
||||||
readwrite = r->readwrite;
|
if (r->pbuf == PA_NULL) {
|
||||||
count = r->count;
|
tmp = ihk_mc_alloc_pages(1, IHK_MC_AP_NOWAIT);
|
||||||
|
if (!tmp)
|
||||||
|
goto err;
|
||||||
|
buf = tmp;
|
||||||
|
count = PAGE_SIZE;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
dprintf("remote pbuf: %x\n", r->pbuf);
|
||||||
|
pbuf = ihk_mc_map_memory(NULL, r->pbuf, r->count);
|
||||||
|
dprintf("pbuf: %x\n", pbuf);
|
||||||
|
count = r->count + ((uintptr_t)pbuf & (PAGE_SIZE - 1));
|
||||||
|
npages = (count + (PAGE_SIZE - 1)) / PAGE_SIZE;
|
||||||
|
vbuf = ihk_mc_map_virtual(pbuf, npages,
|
||||||
|
PTATTR_WRITABLE|PTATTR_ACTIVE);
|
||||||
|
dprintf("buf: %p\n", vbuf);
|
||||||
|
if (vbuf == NULL) {
|
||||||
|
ihk_mc_unmap_memory(NULL, pbuf, r->count);
|
||||||
|
kprintf("ERROR: %s: got a null buffer.\n", __func__);
|
||||||
|
goto err;
|
||||||
|
}
|
||||||
|
buf = vbuf;
|
||||||
|
readwrite = r->readwrite;
|
||||||
|
count = r->count;
|
||||||
|
dprintf("fname: %s, offset: %lx, count:%d.\n", r->fname,
|
||||||
|
r->offset, r->count);
|
||||||
|
}
|
||||||
offset = r->offset;
|
offset = r->offset;
|
||||||
dprintf("fname: %s, offset: %lx, count:%d.\n", r->fname, r->offset, r->count);
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* check for "mcos%d/"
|
* check for "mcos%d/"
|
||||||
@@ -200,35 +304,24 @@ int process_procfs_request(struct ikc_scd_packet *rpacket)
|
|||||||
}
|
}
|
||||||
else if (!strcmp(p, "stat")) { /* "/proc/stat" */
|
else if (!strcmp(p, "stat")) { /* "/proc/stat" */
|
||||||
extern int num_processors; /* kernel/ap.c */
|
extern int num_processors; /* kernel/ap.c */
|
||||||
char *p;
|
|
||||||
size_t remain;
|
|
||||||
int cpu;
|
int cpu;
|
||||||
|
|
||||||
if (offset > 0) {
|
|
||||||
ans = 0;
|
|
||||||
eof = 1;
|
|
||||||
goto end;
|
|
||||||
}
|
|
||||||
p = buf;
|
|
||||||
remain = count;
|
|
||||||
for (cpu = 0; cpu < num_processors; ++cpu) {
|
for (cpu = 0; cpu < num_processors; ++cpu) {
|
||||||
size_t n;
|
snprintf(buf, count, "cpu%d\n", cpu);
|
||||||
|
if (buf_add(&buf_top, &buf_cur, buf, strlen(buf)) < 0)
|
||||||
n = snprintf(p, remain, "cpu%d\n", cpu);
|
goto err;
|
||||||
if (n >= remain) {
|
|
||||||
ans = -ENOSPC;
|
|
||||||
eof = 1;
|
|
||||||
goto end;
|
|
||||||
}
|
|
||||||
p += n;
|
|
||||||
}
|
}
|
||||||
ans = p - buf;
|
ans = 0;
|
||||||
eof = 1;
|
|
||||||
goto end;
|
goto end;
|
||||||
}
|
}
|
||||||
#ifdef POSTK_DEBUG_ARCH_DEP_42 /* /proc/cpuinfo support added. */
|
#ifdef POSTK_DEBUG_ARCH_DEP_42 /* /proc/cpuinfo support added. */
|
||||||
else if (!strcmp(p, "cpuinfo")) { /* "/proc/cpuinfo" */
|
else if (!strcmp(p, "cpuinfo")) { /* "/proc/cpuinfo" */
|
||||||
ans = ihk_mc_show_cpuinfo(buf, count, offset, &eof);
|
ans = ihk_mc_show_cpuinfo(buf, count, 0, &eof);
|
||||||
|
if (ans < 0)
|
||||||
|
goto err;
|
||||||
|
if (buf_add(&buf_top, &buf_cur, buf, strlen(buf)) < 0)
|
||||||
|
goto err;
|
||||||
|
ans = 0;
|
||||||
goto end;
|
goto end;
|
||||||
}
|
}
|
||||||
#endif /* POSTK_DEBUG_ARCH_DEP_42 */
|
#endif /* POSTK_DEBUG_ARCH_DEP_42 */
|
||||||
@@ -313,110 +406,51 @@ int process_procfs_request(struct ikc_scd_packet *rpacket)
|
|||||||
*/
|
*/
|
||||||
if (strcmp(p, "maps") == 0) {
|
if (strcmp(p, "maps") == 0) {
|
||||||
struct vm_range *range;
|
struct vm_range *range;
|
||||||
#ifdef POSTK_DEBUG_TEMP_FIX_47 /* /proc/<pid>/maps 1024 byte over read fix. */
|
|
||||||
int left = PAGE_SIZE * 2;
|
|
||||||
#else /* POSTK_DEBUG_TEMP_FIX_47 */
|
|
||||||
int left = r->count - 1; /* extra 1 for terminating NULL */
|
|
||||||
#endif /* POSTK_DEBUG_TEMP_FIX_47 */
|
|
||||||
int written = 0;
|
|
||||||
char *_buf = buf;
|
|
||||||
#ifdef POSTK_DEBUG_TEMP_FIX_47 /* /proc/<pid>/maps 1024 byte over read fix. */
|
|
||||||
int len = 0;
|
|
||||||
char *tmp = NULL;
|
|
||||||
|
|
||||||
_buf = tmp = kmalloc(left, IHK_MC_AP_CRITICAL);
|
|
||||||
if (!tmp) {
|
|
||||||
kprintf("%s: error allocating /proc/self/maps buffer\n",
|
|
||||||
__FUNCTION__);
|
|
||||||
ans = 0;
|
|
||||||
goto end;
|
|
||||||
}
|
|
||||||
#endif /* POSTK_DEBUG_TEMP_FIX_47 */
|
|
||||||
|
|
||||||
#ifndef POSTK_DEBUG_TEMP_FIX_47 /* /proc/<pid>/maps 1024 byte over read fix. */
|
|
||||||
/* Starting from the middle of a proc file is not supported for maps */
|
|
||||||
if (offset > 0) {
|
|
||||||
ans = 0;
|
|
||||||
eof = 1;
|
|
||||||
goto end;
|
|
||||||
}
|
|
||||||
#endif /* POSTK_DEBUG_TEMP_FIX_47 */
|
|
||||||
|
|
||||||
ihk_mc_spinlock_lock_noirq(&vm->memory_range_lock);
|
ihk_mc_spinlock_lock_noirq(&vm->memory_range_lock);
|
||||||
|
|
||||||
range = lookup_process_memory_range(vm, 0, -1);
|
range = lookup_process_memory_range(vm, 0, -1);
|
||||||
while (range) {
|
while (range) {
|
||||||
int written_now;
|
|
||||||
|
|
||||||
/* format is (from man proc):
|
/* format is (from man proc):
|
||||||
* address perms offset dev inode pathname
|
* address perms offset dev inode pathname
|
||||||
* 08048000-08056000 r-xp 00000000 03:0c 64593 /usr/sbin/gpm
|
* 08048000-08056000 r-xp 00000000 03:0c 64593 /usr/sbin/gpm
|
||||||
*/
|
*/
|
||||||
written_now = snprintf(_buf, left,
|
snprintf(buf, count,
|
||||||
"%012lx-%012lx %s%s%s%s %lx %lx:%lx %d\t\t\t%s\n",
|
"%012lx-%012lx %s%s%s%s %lx %lx:%lx %d\t\t\t%s\n",
|
||||||
range->start, range->end,
|
range->start, range->end,
|
||||||
range->flag & VR_PROT_READ ? "r" : "-",
|
range->flag & VR_PROT_READ ? "r" : "-",
|
||||||
range->flag & VR_PROT_WRITE ? "w" : "-",
|
range->flag & VR_PROT_WRITE ? "w" : "-",
|
||||||
range->flag & VR_PROT_EXEC ? "x" : "-",
|
range->flag & VR_PROT_EXEC ? "x" : "-",
|
||||||
range->flag & VR_PRIVATE ? "p" : "s",
|
range->flag & VR_PRIVATE ? "p" : "s",
|
||||||
/* TODO: fill in file details! */
|
/* TODO: fill in file details! */
|
||||||
0UL,
|
0UL,
|
||||||
0UL,
|
0UL,
|
||||||
0UL,
|
0UL,
|
||||||
0,
|
0,
|
||||||
range->memobj && range->memobj->path ? range->memobj->path :
|
range->memobj && range->memobj->path ?
|
||||||
range->start ==
|
range->memobj->path :
|
||||||
(unsigned long)vm->vdso_addr ? "[vdso]" :
|
range->start == (unsigned long)vm->vdso_addr ?
|
||||||
range->start ==
|
"[vdso]" :
|
||||||
(unsigned long)vm->vvar_addr ? "[vsyscall]" :
|
range->start == (unsigned long)vm->vvar_addr ?
|
||||||
range->flag & VR_STACK ? "[stack]" :
|
"[vsyscall]" :
|
||||||
range->start >= vm->region.brk_start &&
|
range->flag & VR_STACK ?
|
||||||
range->end <= vm->region.brk_end_allocated ?
|
"[stack]" :
|
||||||
"[heap]" :
|
range->start >= vm->region.brk_start &&
|
||||||
|
range->end <= vm->region.brk_end_allocated ?
|
||||||
|
"[heap]" :
|
||||||
""
|
""
|
||||||
);
|
);
|
||||||
|
|
||||||
left -= written_now;
|
if (buf_add(&buf_top, &buf_cur, buf, strlen(buf)) < 0) {
|
||||||
_buf += written_now;
|
ihk_mc_spinlock_unlock_noirq(&vm->memory_range_lock);
|
||||||
written += written_now;
|
goto err;
|
||||||
|
|
||||||
#ifdef POSTK_DEBUG_TEMP_FIX_47 /* /proc/<pid>/maps 1024 byte over read fix. */
|
|
||||||
if (left == 0) {
|
|
||||||
kprintf("%s(): WARNING: buffer too small to fill proc/maps\n",
|
|
||||||
__FUNCTION__);
|
|
||||||
break;
|
|
||||||
}
|
}
|
||||||
#else /* POSTK_DEBUG_TEMP_FIX_47 */
|
|
||||||
if (left == 1) {
|
|
||||||
kprintf("%s(): WARNING: buffer too small to fill proc/maps\n",
|
|
||||||
__FUNCTION__);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
#endif /* POSTK_DEBUG_TEMP_FIX_47 */
|
|
||||||
range = next_process_memory_range(vm, range);
|
range = next_process_memory_range(vm, range);
|
||||||
}
|
}
|
||||||
|
|
||||||
ihk_mc_spinlock_unlock_noirq(&vm->memory_range_lock);
|
ihk_mc_spinlock_unlock_noirq(&vm->memory_range_lock);
|
||||||
|
|
||||||
#ifdef POSTK_DEBUG_TEMP_FIX_47 /* /proc/<pid>/maps 1024 byte over read fix. */
|
ans = 0;
|
||||||
len = strlen(tmp);
|
|
||||||
if (r->offset < len) {
|
|
||||||
if (r->offset + r->count < len) {
|
|
||||||
ans = r->count;
|
|
||||||
} else {
|
|
||||||
eof = 1;
|
|
||||||
ans = len;
|
|
||||||
}
|
|
||||||
strncpy(buf, tmp + r->offset, ans);
|
|
||||||
} else if (r->offset == len) {
|
|
||||||
ans = 0;
|
|
||||||
eof = 1;
|
|
||||||
}
|
|
||||||
kfree(tmp);
|
|
||||||
#else /* POSTK_DEBUG_TEMP_FIX_47 */
|
|
||||||
ans = written;
|
|
||||||
eof = 1;
|
|
||||||
#endif /* POSTK_DEBUG_TEMP_FIX_47 */
|
|
||||||
goto end;
|
goto end;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -465,28 +499,16 @@ int process_procfs_request(struct ikc_scd_packet *rpacket)
|
|||||||
extern int num_processors; /* kernel/ap.c */
|
extern int num_processors; /* kernel/ap.c */
|
||||||
struct vm_range *range;
|
struct vm_range *range;
|
||||||
unsigned long lockedsize = 0;
|
unsigned long lockedsize = 0;
|
||||||
char *tmp;
|
|
||||||
char *bitmasks;
|
char *bitmasks;
|
||||||
int bitmasks_offset = 0;
|
int bitmasks_offset = 0;
|
||||||
char *cpu_bitmask, *cpu_list, *numa_bitmask, *numa_list;
|
char *cpu_bitmask, *cpu_list, *numa_bitmask, *numa_list;
|
||||||
int len;
|
|
||||||
char *state;
|
char *state;
|
||||||
|
|
||||||
tmp = kmalloc(8192, IHK_MC_AP_CRITICAL);
|
|
||||||
if (!tmp) {
|
|
||||||
kprintf("%s: error allocating /proc/self/status buffer\n",
|
|
||||||
__FUNCTION__);
|
|
||||||
ans = 0;
|
|
||||||
goto end;
|
|
||||||
}
|
|
||||||
|
|
||||||
bitmasks = kmalloc(BITMASKS_BUF_SIZE, IHK_MC_AP_CRITICAL);
|
bitmasks = kmalloc(BITMASKS_BUF_SIZE, IHK_MC_AP_CRITICAL);
|
||||||
if (!tmp) {
|
if (!bitmasks) {
|
||||||
kprintf("%s: error allocating /proc/self/status bitmaks buffer\n",
|
kprintf("%s: error allocating /proc/self/status bitmaks buffer\n",
|
||||||
__FUNCTION__);
|
__FUNCTION__);
|
||||||
kfree(tmp);
|
goto err;
|
||||||
ans = 0;
|
|
||||||
goto end;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
ihk_mc_spinlock_lock_noirq(&proc->vm->memory_range_lock);
|
ihk_mc_spinlock_lock_noirq(&proc->vm->memory_range_lock);
|
||||||
@@ -529,37 +551,43 @@ int process_procfs_request(struct ikc_scd_packet *rpacket)
|
|||||||
state = "T (tracing stop)";
|
state = "T (tracing stop)";
|
||||||
else if (proc->status == PS_EXITED)
|
else if (proc->status == PS_EXITED)
|
||||||
state = "Z (zombie)";
|
state = "Z (zombie)";
|
||||||
sprintf(tmp,
|
sprintf(buf,
|
||||||
"Pid:\t%d\n"
|
"Pid:\t%d\n"
|
||||||
"Uid:\t%d\t%d\t%d\t%d\n"
|
"Uid:\t%d\t%d\t%d\t%d\n"
|
||||||
"Gid:\t%d\t%d\t%d\t%d\n"
|
"Gid:\t%d\t%d\t%d\t%d\n"
|
||||||
"State:\t%s\n"
|
"State:\t%s\n"
|
||||||
"VmLck:\t%9lu kB\n"
|
"VmLck:\t%9lu kB\n",
|
||||||
"Cpus_allowed:\t%s\n"
|
proc->pid,
|
||||||
"Cpus_allowed_list:\t%s\n"
|
proc->ruid, proc->euid, proc->suid, proc->fsuid,
|
||||||
"Mems_allowed:\t%s\n"
|
proc->rgid, proc->egid, proc->sgid, proc->fsgid,
|
||||||
"Mems_allowed_list:\t%s\n",
|
|
||||||
proc->pid,
|
|
||||||
proc->ruid, proc->euid, proc->suid, proc->fsuid,
|
|
||||||
proc->rgid, proc->egid, proc->sgid, proc->fsgid,
|
|
||||||
state,
|
state,
|
||||||
(lockedsize + 1023) >> 10,
|
(lockedsize + 1023) >> 10);
|
||||||
cpu_bitmask, cpu_list, numa_bitmask, numa_list);
|
if (buf_add(&buf_top, &buf_cur, buf, strlen(buf)) < 0) {
|
||||||
len = strlen(tmp);
|
goto err;
|
||||||
if (r->offset < len) {
|
}
|
||||||
if (r->offset + r->count < len) {
|
|
||||||
ans = r->count;
|
sprintf(buf, "Cpus_allowed:\t%s\n", cpu_bitmask);
|
||||||
} else {
|
if (buf_add(&buf_top, &buf_cur, buf, strlen(buf)) < 0) {
|
||||||
eof = 1;
|
kfree(bitmasks);
|
||||||
ans = len;
|
goto err;
|
||||||
}
|
}
|
||||||
strncpy(buf, tmp + r->offset, ans);
|
sprintf(buf, "Cpus_allowed_list:\t%s\n", cpu_list);
|
||||||
} else if (r->offset == len) {
|
if (buf_add(&buf_top, &buf_cur, buf, strlen(buf)) < 0) {
|
||||||
ans = 0;
|
kfree(bitmasks);
|
||||||
eof = 1;
|
goto err;
|
||||||
|
}
|
||||||
|
sprintf(buf, "Mems_allowed:\t%s\n", numa_bitmask);
|
||||||
|
if (buf_add(&buf_top, &buf_cur, buf, strlen(buf)) < 0) {
|
||||||
|
kfree(bitmasks);
|
||||||
|
goto err;
|
||||||
|
}
|
||||||
|
sprintf(buf, "Mems_allowed_list:\t%s\n", numa_list);
|
||||||
|
if (buf_add(&buf_top, &buf_cur, buf, strlen(buf)) < 0) {
|
||||||
|
kfree(bitmasks);
|
||||||
|
goto err;
|
||||||
}
|
}
|
||||||
kfree(tmp);
|
|
||||||
kfree(bitmasks);
|
kfree(bitmasks);
|
||||||
|
ans = 0;
|
||||||
goto end;
|
goto end;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -568,20 +596,10 @@ int process_procfs_request(struct ikc_scd_packet *rpacket)
|
|||||||
*/
|
*/
|
||||||
if (strcmp(p, "auxv") == 0) {
|
if (strcmp(p, "auxv") == 0) {
|
||||||
unsigned int limit = AUXV_LEN * sizeof(unsigned long);
|
unsigned int limit = AUXV_LEN * sizeof(unsigned long);
|
||||||
unsigned int len = r->count;
|
|
||||||
if (r->offset < limit) {
|
if (buf_add(&buf_top, &buf_cur, proc->saved_auxv, limit) < 0)
|
||||||
if (limit < r->offset + r->count) {
|
goto err;
|
||||||
len = limit - r->offset;
|
ans = 0;
|
||||||
}
|
|
||||||
memcpy((void *)buf, ((char *) proc->saved_auxv) + r->offset, len);
|
|
||||||
ans = len;
|
|
||||||
if (r->offset + len == limit) {
|
|
||||||
eof = 1;
|
|
||||||
}
|
|
||||||
} else if (r->offset == limit) {
|
|
||||||
ans = 0;
|
|
||||||
eof = 1;
|
|
||||||
}
|
|
||||||
goto end;
|
goto end;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -590,27 +608,17 @@ int process_procfs_request(struct ikc_scd_packet *rpacket)
|
|||||||
*/
|
*/
|
||||||
if (strcmp(p, "cmdline") == 0) {
|
if (strcmp(p, "cmdline") == 0) {
|
||||||
unsigned int limit = proc->saved_cmdline_len;
|
unsigned int limit = proc->saved_cmdline_len;
|
||||||
unsigned int len = r->count;
|
|
||||||
|
|
||||||
if(!proc->saved_cmdline){
|
if(!proc->saved_cmdline){
|
||||||
|
if (buf_add(&buf_top, &buf_cur, "", 0) < 0)
|
||||||
|
goto err;
|
||||||
ans = 0;
|
ans = 0;
|
||||||
eof = 1;
|
|
||||||
goto end;
|
goto end;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (r->offset < limit) {
|
if (buf_add(&buf_top, &buf_cur, proc->saved_cmdline, limit) < 0)
|
||||||
if (limit < r->offset + r->count) {
|
goto err;
|
||||||
len = limit - r->offset;
|
ans = 0;
|
||||||
}
|
|
||||||
memcpy((void *)buf, ((char *) proc->saved_cmdline) + r->offset, len);
|
|
||||||
ans = len;
|
|
||||||
if (r->offset + len == limit) {
|
|
||||||
eof = 1;
|
|
||||||
}
|
|
||||||
} else if (r->offset == limit) {
|
|
||||||
ans = 0;
|
|
||||||
eof = 1;
|
|
||||||
}
|
|
||||||
goto end;
|
goto end;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -622,8 +630,6 @@ int process_procfs_request(struct ikc_scd_packet *rpacket)
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
if (!strcmp(p, "stat")) {
|
if (!strcmp(p, "stat")) {
|
||||||
char tmp[1024];
|
|
||||||
int len;
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* pid (comm) state ppid
|
* pid (comm) state ppid
|
||||||
@@ -638,7 +644,7 @@ int process_procfs_request(struct ikc_scd_packet *rpacket)
|
|||||||
* cnswap exit_signal processor rt_priority
|
* cnswap exit_signal processor rt_priority
|
||||||
* policy delayacct_blkio_ticks guest_time cguest_time
|
* policy delayacct_blkio_ticks guest_time cguest_time
|
||||||
*/
|
*/
|
||||||
ans = sprintf(tmp,
|
ans = sprintf(buf,
|
||||||
"%d (%s) %c %d " // pid...
|
"%d (%s) %c %d " // pid...
|
||||||
"%d %d %d %d " // pgrp...
|
"%d %d %d %d " // pgrp...
|
||||||
"%u %lu %lu %lu " // flags...
|
"%u %lu %lu %lu " // flags...
|
||||||
@@ -662,21 +668,10 @@ int process_procfs_request(struct ikc_scd_packet *rpacket)
|
|||||||
0L, 0, thread->cpu_id, 0, // cnswap...
|
0L, 0, thread->cpu_id, 0, // cnswap...
|
||||||
0, 0LL, 0L, 0L // policy...
|
0, 0LL, 0L, 0L // policy...
|
||||||
);
|
);
|
||||||
dprintf("tmp=%s\n", tmp);
|
|
||||||
|
|
||||||
len = strlen(tmp);
|
if (buf_add(&buf_top, &buf_cur, buf, strlen(buf)) < 0)
|
||||||
if (r->offset < len) {
|
goto err;
|
||||||
if (r->offset + r->count < len) {
|
ans = 0;
|
||||||
ans = r->count;
|
|
||||||
} else {
|
|
||||||
eof = 1;
|
|
||||||
ans = len;
|
|
||||||
}
|
|
||||||
strncpy(buf, tmp + r->offset, ans);
|
|
||||||
} else if (r->offset == len) {
|
|
||||||
ans = 0;
|
|
||||||
eof = 1;
|
|
||||||
}
|
|
||||||
goto end;
|
goto end;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -686,16 +681,24 @@ int process_procfs_request(struct ikc_scd_packet *rpacket)
|
|||||||
kprintf("unsupported procfs entry: %d/%s\n", pid, p);
|
kprintf("unsupported procfs entry: %d/%s\n", pid, p);
|
||||||
|
|
||||||
end:
|
end:
|
||||||
ihk_mc_unmap_virtual(buf, npages);
|
|
||||||
dprintf("ret: %d, eof: %d\n", ans, eof);
|
dprintf("ret: %d, eof: %d\n", ans, eof);
|
||||||
r->ret = ans;
|
r->ret = ans;
|
||||||
r->eof = eof;
|
r->eof = eof;
|
||||||
err = 0;
|
err = 0;
|
||||||
bufunavail:
|
if (r->pbuf == PA_NULL && buf_top)
|
||||||
ihk_mc_unmap_memory(NULL, pbuf, r->count);
|
r->pbuf = virt_to_phys(buf_top);
|
||||||
ihk_mc_unmap_virtual(r, 1);
|
err:
|
||||||
dataunavail:
|
if (vbuf) {
|
||||||
ihk_mc_unmap_memory(NULL, parg, sizeof(struct procfs_read));
|
ihk_mc_unmap_virtual(vbuf, npages);
|
||||||
|
ihk_mc_unmap_memory(NULL, pbuf, r->count);
|
||||||
|
}
|
||||||
|
if (r) {
|
||||||
|
ihk_mc_unmap_virtual(r, 1);
|
||||||
|
ihk_mc_unmap_memory(NULL, parg, sizeof(struct procfs_read));
|
||||||
|
}
|
||||||
|
if (tmp) {
|
||||||
|
ihk_mc_free_pages(tmp, 1);
|
||||||
|
}
|
||||||
|
|
||||||
if(proc)
|
if(proc)
|
||||||
release_process(proc);
|
release_process(proc);
|
||||||
|
|||||||
286
test/issues/1021/C1021.c
Normal file
286
test/issues/1021/C1021.c
Normal file
@@ -0,0 +1,286 @@
|
|||||||
|
#include <stdlib.h>
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <stdarg.h>
|
||||||
|
#include <string.h>
|
||||||
|
#include <unistd.h>
|
||||||
|
#include <sys/types.h>
|
||||||
|
#include <sys/mman.h>
|
||||||
|
#include <fcntl.h>
|
||||||
|
#include <errno.h>
|
||||||
|
#include <ctype.h>
|
||||||
|
|
||||||
|
int id;
|
||||||
|
int okcnt;
|
||||||
|
int ngcnt;
|
||||||
|
void *area;
|
||||||
|
|
||||||
|
void
|
||||||
|
ok(char *file, char *fmt, ...)
|
||||||
|
{
|
||||||
|
va_list ap;
|
||||||
|
|
||||||
|
printf("*** C1021T%02d %s ", id, file);
|
||||||
|
va_start(ap, fmt);
|
||||||
|
vprintf(fmt, ap);
|
||||||
|
va_end(ap);
|
||||||
|
printf("\n");
|
||||||
|
okcnt++;
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
ng(char *file, char *fmt, ...)
|
||||||
|
{
|
||||||
|
va_list ap;
|
||||||
|
|
||||||
|
printf("*** C1021T%02d %s ", id, file);
|
||||||
|
va_start(ap, fmt);
|
||||||
|
vprintf(fmt, ap);
|
||||||
|
va_end(ap);
|
||||||
|
printf("\n");
|
||||||
|
ngcnt++;
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
hex(char *bp, int len)
|
||||||
|
{
|
||||||
|
unsigned char *buf;
|
||||||
|
long l;
|
||||||
|
long p;
|
||||||
|
long zl = 0;
|
||||||
|
long zf = 1;
|
||||||
|
long zp = 0;
|
||||||
|
|
||||||
|
for (p = 0; p < len; p += 16) {
|
||||||
|
int i;
|
||||||
|
|
||||||
|
buf = (unsigned char *)bp + p;
|
||||||
|
l = 16;
|
||||||
|
if (p + 16 > len) {
|
||||||
|
l = len - p;
|
||||||
|
}
|
||||||
|
if (!zf) {
|
||||||
|
int zz = 0;
|
||||||
|
|
||||||
|
for (i = 0; i < l; i++) {
|
||||||
|
if (buf[i])
|
||||||
|
zz = 1;
|
||||||
|
}
|
||||||
|
if (l < 16 || !zz) {
|
||||||
|
zl += 16;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
if (zl == 16) {
|
||||||
|
printf("%016lx 00000000 00000000 00000000 "
|
||||||
|
"00000000 *................*\n", zp);
|
||||||
|
}
|
||||||
|
else if (zl) {
|
||||||
|
printf(" %08lx - %08lx ZERO\n", zp, p);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
zf = 0;
|
||||||
|
printf("%08lx ", p);
|
||||||
|
for (i = 0; i < 16; i++) {
|
||||||
|
if (i % 4 == 0)
|
||||||
|
printf(" ");
|
||||||
|
printf(i < l ? "%02x" : " ", buf[i]);
|
||||||
|
if (i < l && buf[i])
|
||||||
|
zf = 1;
|
||||||
|
}
|
||||||
|
printf(" *");
|
||||||
|
for (i = 0; i < 16; i++)
|
||||||
|
printf(i < l ? "%c" : " ",
|
||||||
|
isprint(buf[i]) ? buf[i] : '.');
|
||||||
|
printf("*\n");
|
||||||
|
zl = 0;
|
||||||
|
zp = p + 16;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
sub(char *file, int mapsflag)
|
||||||
|
{
|
||||||
|
int fd;
|
||||||
|
int fd2;
|
||||||
|
char buf1[65536];
|
||||||
|
char buf2[65536];
|
||||||
|
char buf3[65536];
|
||||||
|
int n;
|
||||||
|
int rc;
|
||||||
|
int pos;
|
||||||
|
|
||||||
|
id++;
|
||||||
|
fd = open(file, O_RDONLY);
|
||||||
|
if (fd == -1) {
|
||||||
|
ng(file, "open %s", strerror(errno));
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
ok(file, "open OK");
|
||||||
|
}
|
||||||
|
|
||||||
|
id++;
|
||||||
|
fd2 = dup(fd);
|
||||||
|
if (fd2 == -1) {
|
||||||
|
ng(file, "dup %s", strerror(errno));
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
ok(file, "dup OK");
|
||||||
|
}
|
||||||
|
|
||||||
|
id++;
|
||||||
|
for (n = 0; (rc = read(fd, buf1 + n, 1)) == 1; n++);
|
||||||
|
if (rc == -1) {
|
||||||
|
ng(file, "read(1) %s", strerror(errno));
|
||||||
|
}
|
||||||
|
else if (mapsflag && n < 4096) {
|
||||||
|
ng(file, "read(1) short n=%d", n);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
ok(file, "read(1) OK n=%d", n);
|
||||||
|
}
|
||||||
|
|
||||||
|
id++;
|
||||||
|
rc = lseek(fd, 0L, SEEK_SET);
|
||||||
|
if (rc == -1) {
|
||||||
|
ng(file, "lseek %s", strerror(errno));
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
ok(file, "lseek OK");
|
||||||
|
}
|
||||||
|
|
||||||
|
if (mapsflag)
|
||||||
|
munmap(area, 4096);
|
||||||
|
|
||||||
|
id++;
|
||||||
|
pos = 0;
|
||||||
|
while ((rc = read(fd, buf2 + pos, 1024)) > 0) {
|
||||||
|
pos += rc;
|
||||||
|
}
|
||||||
|
if (rc == -1) {
|
||||||
|
ng(file, "read(1) %s\n", strerror(errno));
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
if (pos != n) {
|
||||||
|
ng(file, "read(1024) invalid size %d != %d", pos, n);
|
||||||
|
}
|
||||||
|
else if (memcmp(buf1, buf2, n) != 0) {
|
||||||
|
ng(file, "read(1024) invalid data");
|
||||||
|
hex(buf1, n);
|
||||||
|
hex(buf2, n);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
ok(file, "read(1024) OK");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
id++;
|
||||||
|
rc = close(fd);
|
||||||
|
if (rc == -1) {
|
||||||
|
ng(file, "close %s", strerror(errno));
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
ok(file, "close OK");
|
||||||
|
}
|
||||||
|
|
||||||
|
id++;
|
||||||
|
rc = read(fd2, buf3, n);
|
||||||
|
if (rc == -1) {
|
||||||
|
ng(file, "read(dup) EOF %s", strerror(errno));
|
||||||
|
}
|
||||||
|
else if (rc == 0) {
|
||||||
|
ok(file, "read(dup) EOF OK");
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
ng(file, "read(dup) invalid position");
|
||||||
|
}
|
||||||
|
|
||||||
|
id++;
|
||||||
|
rc = lseek(fd2, 0L, SEEK_SET);
|
||||||
|
if (rc == -1) {
|
||||||
|
ng(file, "lseek(dup) %s", strerror(errno));
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
ok(file, "lseek(dup) OK");
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
id++;
|
||||||
|
rc = read(fd2, buf3, n);
|
||||||
|
if (rc == -1) {
|
||||||
|
ng(file, "read(dup) %s", strerror(errno));
|
||||||
|
}
|
||||||
|
else if (rc != n) {
|
||||||
|
ng(file, "read(dup) too short");
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
rc = read(fd2, buf3 + rc, n);
|
||||||
|
if (rc == -1) {
|
||||||
|
ng(file, "read(dup) %s", strerror(errno));
|
||||||
|
}
|
||||||
|
else if (rc != 0) {
|
||||||
|
ng(file, "read(dup) too long");
|
||||||
|
}
|
||||||
|
else if (memcmp(buf1, buf3, n) != 0) {
|
||||||
|
ng(file, "read(dup) invalid data");
|
||||||
|
hex(buf1, n);
|
||||||
|
hex(buf3, n);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
ok(file, "read(dup) OK");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
id++;
|
||||||
|
rc = close(fd2);
|
||||||
|
if (rc == -1) {
|
||||||
|
ng(file, "close(dup) %s", strerror(errno));
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
ok(file, "close(dup) OK");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
int
|
||||||
|
main(int argc, char **argv)
|
||||||
|
{
|
||||||
|
int i;
|
||||||
|
int pid = getpid();
|
||||||
|
char file[1024];
|
||||||
|
|
||||||
|
for (i = 0; i < 512; i++) {
|
||||||
|
char *c;
|
||||||
|
|
||||||
|
if (i % 2) {
|
||||||
|
c = mmap(NULL, 4096, PROT_READ|PROT_WRITE,
|
||||||
|
MAP_PRIVATE|MAP_ANONYMOUS, -1, 0);
|
||||||
|
area = c;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
c = mmap(NULL, 4096, PROT_READ|PROT_WRITE,
|
||||||
|
MAP_SHARED|MAP_ANONYMOUS, -1, 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (c == (void *)-1) {
|
||||||
|
printf("mmap error %d\n", errno);
|
||||||
|
exit(1);
|
||||||
|
}
|
||||||
|
*c = 1;
|
||||||
|
}
|
||||||
|
sub("/proc/stat", 0);
|
||||||
|
sprintf(file, "/proc/%d/auxv", pid);
|
||||||
|
sub(file, 0);
|
||||||
|
sprintf(file, "/proc/%d/cmdline", pid);
|
||||||
|
sub(file, 0);
|
||||||
|
sprintf(file, "/proc/%d/maps", pid);
|
||||||
|
sub(file, 1);
|
||||||
|
sprintf(file, "/proc/%d/status", pid);
|
||||||
|
sub(file, 0);
|
||||||
|
sprintf(file, "/proc/%d/task/%d/stat", pid, pid);
|
||||||
|
sub(file, 0);
|
||||||
|
|
||||||
|
if (ngcnt) {
|
||||||
|
printf("TEST FAILED OK=%d NG=%d\n", okcnt, ngcnt);
|
||||||
|
exit(1);
|
||||||
|
}
|
||||||
|
printf("TEST SUCCESS OK=%d\n", okcnt);
|
||||||
|
exit(0);
|
||||||
|
}
|
||||||
81
test/issues/1021/C1021.sh
Executable file
81
test/issues/1021/C1021.sh
Executable file
@@ -0,0 +1,81 @@
|
|||||||
|
#!/bin/sh
|
||||||
|
BIN=
|
||||||
|
SBIN=
|
||||||
|
LTP=
|
||||||
|
OSTEST=
|
||||||
|
BOOTPARAM="-c 1-7,17-23,9-15,25-31 -m 10G@0,10G@1"
|
||||||
|
|
||||||
|
if ! sudo ls /sys/kernel/debug | grep kmemleak > /dev/null 2>&1; then
|
||||||
|
echo kmemleak: not found >&2
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
if [ -f ../../../config.h ]; then
|
||||||
|
str=`grep "^#define BINDIR " ../../../config.h | head -1 | sed 's/^#define BINDIR /BINDIR=/'`
|
||||||
|
eval $str
|
||||||
|
fi
|
||||||
|
if [ "x$BINDIR" = x ];then
|
||||||
|
BINDIR="$BIN"
|
||||||
|
fi
|
||||||
|
|
||||||
|
if [ -f ../../../Makefile ]; then
|
||||||
|
str=`grep ^SBINDIR ../../../Makefile | head -1 | sed 's/ //g'`
|
||||||
|
eval $str
|
||||||
|
fi
|
||||||
|
if [ "x$SBINDIR" = x ];then
|
||||||
|
SBINDIR="$SBIN"
|
||||||
|
fi
|
||||||
|
|
||||||
|
if [ -f $HOME/ltp/testcases/bin/fork01 ]; then
|
||||||
|
LTPDIR=$HOME/ltp
|
||||||
|
fi
|
||||||
|
if [ "x$LTPDIR" = x ]; then
|
||||||
|
LTPDIR="$LTP"
|
||||||
|
fi
|
||||||
|
if [ "x$LTPDIR" != x ]; then
|
||||||
|
LTPDIR="$LTPDIR/testcases"
|
||||||
|
fi
|
||||||
|
|
||||||
|
if [ -f $HOME/ostest/bin/test_mck ]; then
|
||||||
|
OSTESTDIR=$HOME/ostest/
|
||||||
|
fi
|
||||||
|
if [ "x$OSTESTDIR" = x ]; then
|
||||||
|
OSTESTDIR="$OSTEST"
|
||||||
|
fi
|
||||||
|
if [ ! -x "$OSTESTDIR"/bin/test_mck ]; then
|
||||||
|
echo no ostest found $OSTEST >&2
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
TESTMCK="$OSTESTDIR/bin/test_mck"
|
||||||
|
|
||||||
|
if [ ! -x $SBINDIR/mcstop+release.sh ]; then
|
||||||
|
echo mcstop+release: not found >&2
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
echo -n "mcstop+release.sh ... "
|
||||||
|
sudo $SBINDIR/mcstop+release.sh
|
||||||
|
echo "done"
|
||||||
|
|
||||||
|
if [ ! -x $SBINDIR/mcreboot.sh ]; then
|
||||||
|
echo mcreboot: not found >&2
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
echo -n "mcreboot.sh $BOOTPARAM ... "
|
||||||
|
sudo $SBINDIR/mcreboot.sh $BOOTPARAM
|
||||||
|
echo "done"
|
||||||
|
|
||||||
|
if [ ! -x $BINDIR/mcexec ]; then
|
||||||
|
echo no mcexec found >&2
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
################################################################################
|
||||||
|
sudo sh -c 'echo clear > /sys/kernel/debug/kmemleak'
|
||||||
|
$BINDIR/mcexec ./C1021
|
||||||
|
sudo $SBINDIR/mcstop+release.sh
|
||||||
|
sudo sh -c 'echo scan > /sys/kernel/debug/kmemleak'
|
||||||
|
if sudo cat /sys/kernel/debug/kmemleak | tee C1021T71.kmemleak | grep 'mcctrl'; then
|
||||||
|
echo '*** C1021T61 NG (kmemleak)'
|
||||||
|
else
|
||||||
|
echo '*** C1021T61 OK (kmemleak)'
|
||||||
|
fi
|
||||||
71
test/issues/1021/C1021.txt
Normal file
71
test/issues/1021/C1021.txt
Normal file
@@ -0,0 +1,71 @@
|
|||||||
|
Script started on Wed Aug 29 15:21:45 2018
|
||||||
|
bash-4.2$ make test
|
||||||
|
sh ./C1021.sh
|
||||||
|
mcstop+release.sh ... done
|
||||||
|
mcreboot.sh -c 1-7,17-23,9-15,25-31 -m 10G@0,10G@1 ... done
|
||||||
|
*** C1021T01 /proc/stat open OK
|
||||||
|
*** C1021T02 /proc/stat dup OK
|
||||||
|
*** C1021T03 /proc/stat read(1) OK n=158
|
||||||
|
*** C1021T04 /proc/stat lseek OK
|
||||||
|
*** C1021T05 /proc/stat read(1024) OK
|
||||||
|
*** C1021T06 /proc/stat close OK
|
||||||
|
*** C1021T07 /proc/stat read(dup) EOF OK
|
||||||
|
*** C1021T08 /proc/stat lseek(dup) OK
|
||||||
|
*** C1021T09 /proc/stat read(dup) OK
|
||||||
|
*** C1021T10 /proc/stat close(dup) OK
|
||||||
|
*** C1021T11 /proc/12455/auxv open OK
|
||||||
|
*** C1021T12 /proc/12455/auxv dup OK
|
||||||
|
*** C1021T13 /proc/12455/auxv read(1) OK n=144
|
||||||
|
*** C1021T14 /proc/12455/auxv lseek OK
|
||||||
|
*** C1021T15 /proc/12455/auxv read(1024) OK
|
||||||
|
*** C1021T16 /proc/12455/auxv close OK
|
||||||
|
*** C1021T17 /proc/12455/auxv read(dup) EOF OK
|
||||||
|
*** C1021T18 /proc/12455/auxv lseek(dup) OK
|
||||||
|
*** C1021T19 /proc/12455/auxv read(dup) OK
|
||||||
|
*** C1021T20 /proc/12455/auxv close(dup) OK
|
||||||
|
*** C1021T21 /proc/12455/cmdline open OK
|
||||||
|
*** C1021T22 /proc/12455/cmdline dup OK
|
||||||
|
*** C1021T23 /proc/12455/cmdline read(1) OK n=8
|
||||||
|
*** C1021T24 /proc/12455/cmdline lseek OK
|
||||||
|
*** C1021T25 /proc/12455/cmdline read(1024) OK
|
||||||
|
*** C1021T26 /proc/12455/cmdline close OK
|
||||||
|
*** C1021T27 /proc/12455/cmdline read(dup) EOF OK
|
||||||
|
*** C1021T28 /proc/12455/cmdline lseek(dup) OK
|
||||||
|
*** C1021T29 /proc/12455/cmdline read(dup) OK
|
||||||
|
*** C1021T30 /proc/12455/cmdline close(dup) OK
|
||||||
|
*** C1021T31 /proc/12455/maps open OK
|
||||||
|
*** C1021T32 /proc/12455/maps dup OK
|
||||||
|
*** C1021T33 /proc/12455/maps read(1) OK n=25401
|
||||||
|
*** C1021T34 /proc/12455/maps lseek OK
|
||||||
|
*** C1021T35 /proc/12455/maps read(1024) OK
|
||||||
|
*** C1021T36 /proc/12455/maps close OK
|
||||||
|
*** C1021T37 /proc/12455/maps read(dup) EOF OK
|
||||||
|
*** C1021T38 /proc/12455/maps lseek(dup) OK
|
||||||
|
*** C1021T39 /proc/12455/maps read(dup) OK
|
||||||
|
*** C1021T40 /proc/12455/maps close(dup) OK
|
||||||
|
*** C1021T41 /proc/12455/status open OK
|
||||||
|
*** C1021T42 /proc/12455/status dup OK
|
||||||
|
*** C1021T43 /proc/12455/status read(1) OK n=255
|
||||||
|
*** C1021T44 /proc/12455/status lseek OK
|
||||||
|
*** C1021T45 /proc/12455/status read(1024) OK
|
||||||
|
*** C1021T46 /proc/12455/status close OK
|
||||||
|
*** C1021T47 /proc/12455/status read(dup) EOF OK
|
||||||
|
*** C1021T48 /proc/12455/status lseek(dup) OK
|
||||||
|
*** C1021T49 /proc/12455/status read(dup) OK
|
||||||
|
*** C1021T50 /proc/12455/status close(dup) OK
|
||||||
|
*** C1021T51 /proc/12455/task/12455/stat open OK
|
||||||
|
*** C1021T52 /proc/12455/task/12455/stat dup OK
|
||||||
|
*** C1021T53 /proc/12455/task/12455/stat read(1) OK n=92
|
||||||
|
*** C1021T54 /proc/12455/task/12455/stat lseek OK
|
||||||
|
*** C1021T55 /proc/12455/task/12455/stat read(1024) OK
|
||||||
|
*** C1021T56 /proc/12455/task/12455/stat close OK
|
||||||
|
*** C1021T57 /proc/12455/task/12455/stat read(dup) EOF OK
|
||||||
|
*** C1021T58 /proc/12455/task/12455/stat lseek(dup) OK
|
||||||
|
*** C1021T59 /proc/12455/task/12455/stat read(dup) OK
|
||||||
|
*** C1021T60 /proc/12455/task/12455/stat close(dup) OK
|
||||||
|
TEST SUCCESS OK=60
|
||||||
|
*** C1021T61 OK (kmemleak)
|
||||||
|
bash-4.2$ exit
|
||||||
|
exit
|
||||||
|
|
||||||
|
Script done on Wed Aug 29 15:22:55 2018
|
||||||
13
test/issues/1021/Makefile
Normal file
13
test/issues/1021/Makefile
Normal file
@@ -0,0 +1,13 @@
|
|||||||
|
CC=gcc
|
||||||
|
TARGET=C1021
|
||||||
|
|
||||||
|
all:: $(TARGET)
|
||||||
|
|
||||||
|
C1021: C1021.c
|
||||||
|
$(CC) -o C1021 C1021.c -Wall -g
|
||||||
|
|
||||||
|
test:: $(TARGET)
|
||||||
|
sh ./C1021.sh
|
||||||
|
|
||||||
|
clean::
|
||||||
|
rm -f *.o $(TARGET)
|
||||||
58
test/issues/1021/README
Normal file
58
test/issues/1021/README
Normal file
@@ -0,0 +1,58 @@
|
|||||||
|
【Issue#1021 動作確認】
|
||||||
|
□ テスト内容
|
||||||
|
1. procfs ファイルに対するファイルオペレーションのテスト
|
||||||
|
Issue#1021 の対応において、procfs の以下のファイル処理を変更している。
|
||||||
|
/proc/stat
|
||||||
|
/proc/pid/auxv
|
||||||
|
/proc/pid/cmdline
|
||||||
|
/proc/pid/maps
|
||||||
|
/proc/pid/status
|
||||||
|
/proc/pid/task/tid/stat
|
||||||
|
|
||||||
|
これらのファイルに対するファイルオペレーションとして、以下をテストする。
|
||||||
|
1) ファイルをopen(2)できること。
|
||||||
|
2) ファイルディスクリプタをdup(2)できること。
|
||||||
|
3) 1バイト単位にファイル終端までread(2)できること。
|
||||||
|
4) lseek(2) できること。(※2)
|
||||||
|
5) lseek(2) 後に、1024バイト単位に read(2) できること。最初の read(2)と内容が
|
||||||
|
一致していること。
|
||||||
|
6) close(2) できること。
|
||||||
|
7) dup(2) したファイルディスクリプタが EOF になっていること (5 の read(2) の
|
||||||
|
影響)。
|
||||||
|
8) dup(2) したファイルディスクリプタを lseek(2) できること。
|
||||||
|
9) dup(2) したファイルディスクリプタを read(2) し、ファイル全体を 1 回の read(2)
|
||||||
|
で読み込むことができること。また、最初の read(2) と内容が一致していること。
|
||||||
|
10) dup(2) したファイルを close(2) できること。
|
||||||
|
|
||||||
|
テストケースは以下の通りである。
|
||||||
|
C1021T01-C1021T10 /proc/stat に対する上記 1) - 10) のテスト
|
||||||
|
C1021T11-C1021T20 /proc/pid/auxv に対する上記 1) - 10) のテスト
|
||||||
|
C1021T21-C1021T30 /proc/pid/cmdline に対する上記 1) - 10) のテスト
|
||||||
|
C1021T31-C1021T40 /proc/pid/maps に対する上記 1) - 10) のテスト (※1, ※2)
|
||||||
|
C1021T41-C1021T50 /proc/pid/status に対する上記 1) - 10) のテスト
|
||||||
|
C1021T51-C1021T60 /proc/pid/rask/tid/stat に対する上記 1) - 10) のテスト
|
||||||
|
|
||||||
|
※1 /proc/pid/maps はユーザプログラムのメモリの使い方により非常に大きなファイル
|
||||||
|
になることがあるので、予め mmap を複数回行って4kB以上の read が発生するよう
|
||||||
|
にしておく。(McKernel 内のバッファが複数ページになる場合のテストを兼ねる)。
|
||||||
|
|
||||||
|
※2 /proc/pid/maps の読み込み中に情報が変化しても後続の read(2) に影響しない
|
||||||
|
ことを確認するため、/proc/pid/maps の lseek(2) 後に munmap(2) を行い、
|
||||||
|
McKernel の内部情報を変化させる。(後続の read(2) では、munmap 前の情報を
|
||||||
|
読み込む仕様)。
|
||||||
|
|
||||||
|
2. メモリリークが発生していないことの確認
|
||||||
|
C1021T61 kmemleak を用いて mcctrl の procfs 処理がメモリリークを起こして
|
||||||
|
いないことを確認する。
|
||||||
|
|
||||||
|
□ 実行手順
|
||||||
|
$ make test
|
||||||
|
|
||||||
|
実行できない場合は、C1021.shの以下の行を適切に書き換えた後に実行。
|
||||||
|
BIN= mcexec が存在するパス
|
||||||
|
SBIN= mcreboot.sh が存在するパス
|
||||||
|
LTP= LTP が存在するパス
|
||||||
|
|
||||||
|
□ 実行結果
|
||||||
|
C1021.txt 参照。
|
||||||
|
全ての項目が OK となっていることを確認。
|
||||||
Reference in New Issue
Block a user