/*
* CDDL HEADER START
*
* The contents of this file are subject to the terms of the
* Common Development and Distribution License (the "License").
* You may not use this file except in compliance with the License.
*
* You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
* See the License for the specific language governing permissions
* and limitations under the License.
*
* When distributing Covered Code, include this CDDL HEADER in each
* file and include the License file at usr/src/OPENSOLARIS.LICENSE.
* If applicable, add the following below this CDDL HEADER, with the
* fields enclosed by brackets "[]" replaced with your own identifying
* information: Portions Copyright [yyyy] [name of copyright owner]
*
* CDDL HEADER END
*/
/*
* Copyright 2009 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
#include <mdb/mdb_modapi.h>
#include <sys/ipc_impl.h>
#include <sys/shm_impl.h>
#include <sys/sem_impl.h>
#include <sys/msg_impl.h>
/*
* Bitmap data for page protection flags suitable for use with %b.
*/
{ NULL, 0, 0 }
};
static void
{
if (time)
else
}
/*
* Print header common to all IPC types.
*/
static void
{
"OWNER", "GROUP", "CREAT", "CGRP");
}
/*
* Print data common to all IPC types.
*/
static void
{
int res;
if (res == -1)
else
if (res == -1)
else
}
/*ARGSUSED*/
static int
{
if (!(flags & DCMD_ADDRSPEC))
return (DCMD_USAGE);
if (DCMD_HDRSPEC(flags))
return (DCMD_ERR);
}
return (DCMD_OK);
}
static int
{
int found = 0;
int ii;
sizeof (list_node_t);
walker =
"Failed to read message queue\n");
return (found);
}
if (flag & MSG_SND_SIZE) {
mdb_printf("%15lx\t%6d\t%15lx\t%15d\n",
} else {
mdb_printf("%15lx\t%6d\t%15lx\t%15s\n",
}
found++;
walker =
}
}
}
return (found);
}
static void
{
int total = 0;
mdb_printf("cbytes: 0t%lu qnum: 0t%lu qbytes: 0t%lu"
mdb_printf("lspid: 0t%d lrpid: 0t%d\n",
mdb_printf("snd_cnt: 0t%lld snd_cv: %hd (%p)\n",
mdb_printf("Blocked recievers\n");
"Type", "cv addr", "copyout-wait?");
0, MSG_MAX_QNUM + 1, 0,
mdb_printf("Blocked senders\n");
"Type", "cv addr", "Msg Size");
msg_wait_snd), 0);
}
/*ARGSUSED1*/
static void
{
"SEGSZ", "AMP", "LKCNT", "LPID", "CPID", "NATTCH", "CNATTCH");
mdb_printf("%10#lx %?p %5u %7d %7d %7lu %7lu\n",
mdb_printf("sptinfo: %-?p sptseg: %-?p\n",
}
/*ARGSUSED1*/
static void
{
mdb_printf("base: %-?p nsems: 0t%u\n",
}
typedef struct ipc_ops_vec {
"msq",
"kmsqid",
"msq_svc",
sizeof (kmsqid_t)
};
"shm",
"kshmid",
"shm_svc",
sizeof (kshmid_t)
};
"sem",
"ksemid",
"sem_svc",
sizeof (ksemid_t)
};
/*
* Generic IPC data structure display code
*/
static int
{
void *iddata;
if (!(flags & DCMD_ADDRSPEC)) {
return (DCMD_USAGE);
return (DCMD_ERR);
}
return (DCMD_OK);
}
return (DCMD_ERR);
}
mdb_printf("\n");
}
return (DCMD_OK);
}
/*
* Stubs to call ds_print with the appropriate ops vector
*/
static int
{
}
static int
{
}
static int
{
}
/*
* Generic IPC walker
*/
static int
{
mdb_printf("ignoring provided address\n");
mdb_printf("failed to read '%s'; module not present\n",
iv->iv_service);
return (WALK_DONE);
}
else
return (WALK_ERR);
return (WALK_NEXT);
}
static int
{
wsp->walk_cbdata));
}
/*
*/
static int
{
mdb_warn("id out of range\n");
return (DCMD_ERR);
}
return (DCMD_ERR);
}
return (DCMD_ERR);
}
return (DCMD_ERR);
mdb_warn("failed to read kipc_perm_t at %#p",
return (DCMD_ERR);
}
return (DCMD_ERR);
return (DCMD_OK);
}
typedef struct findkey_data {
static int
{
return (WALK_DONE);
}
return (WALK_NEXT);
}
static int
{
mdb_warn("key out of range\n");
return (DCMD_ERR);
}
return (DCMD_ERR);
}
return (DCMD_ERR);
return (DCMD_OK);
}
static int
{
int result;
return (DCMD_USAGE);
else
return (DCMD_USAGE);
return (result);
}
static int
{
}
static int
{
}
static int
{
int result;
if (!(flags & DCMD_ADDRSPEC))
return (DCMD_USAGE);
return (DCMD_USAGE);
mdb_warn("failed to read '%s'; module not present\n",
iv->iv_service);
return (DCMD_ERR);
}
return (result);
}
/*
* Stubs to call ds_ptr with the appropriate ops vector
*/
static int
{
}
static int
{
}
static int
{
}
/*
* The message queue contents walker
*/
static int
{
return (WALK_ERR);
return (WALK_NEXT);
}
static int
{
wsp->walk_cbdata));
}
/*
* The "::ipcs" command itself. Just walks each IPC type in turn.
*/
/*ARGSUSED*/
static int
{
return (DCMD_USAGE);
mdb_printf("Message queues:\n");
-1) {
mdb_warn("can't walk 'msq'");
return (DCMD_ERR);
}
mdb_printf("\nShared memory:\n");
-1) {
mdb_warn("can't walk 'shm'");
return (DCMD_ERR);
}
mdb_printf("\nSemaphores:\n");
-1) {
mdb_warn("can't walk 'sem'");
return (DCMD_ERR);
}
return (DCMD_OK);
}
static int
{
long type = 0;
return (DCMD_USAGE);
/*
* Handle negative values.
*/
if (*tflag == '-') {
tflag++;
type = -1;
} else {
type = 1;
}
}
if (DCMD_HDRSPEC(flags))
mdb_printf("%<u>%?s %?s %8s %8s %8s%</u>\n",
"ADDR", "TEXT", "SIZE", "TYPE", "REF");
return (DCMD_ERR);
}
/*
* If we are meeting our type contraints, display the message.
* If -l was specified, we will also display the message
* contents.
*/
if ((type == 0) ||
mdb_printf("\n");
if (lflag) {
mdb_printf("\n");
if (mdb_dumpptr(
MDB_DUMP_GROUP(4),
return (DCMD_ERR);
}
}
}
return (DCMD_OK);
}
/*
* MDB module linkage
*/
/* Generic routines */
/* Specific routines */
/* Convenience routines */
{ NULL }
};
{ "ipcsvc", "walk a System V IPC service",
{ "shm", "walk the active shmid_ds structures",
{ "msq", "walk the active msqid_ds structures",
{ "sem", "walk the active semid_ds structures",
{ "msgqueue", "walk messages on a message queue",
{ NULL }
};
const mdb_modinfo_t *
_mdb_init(void)
{
return (&modinfo);
}