trouble sending very large rpc replies
James Peach
jpeach at sgi.com
Tue Jan 3 02:16:57 GMT 2006
On Tue, Jan 03, 2006 at 01:14:51PM +1100, Jeremy Allison wrote:
> On Sat, Dec 24, 2005 at 02:02:36PM +1100, James Peach wrote:
> > Hi guys,
> >
> > I'm still slowly plugging away at integrating PCP support for
> > performance metrics. When the necessary management folk get back from
> > holidays in a couple of weeks, I'll be able to post some patches and
> > test programs.
> >
> > In the meantime, I've hit what appears to be a snag in the RPC layer.
> > When the client fetches the counter names and help text registry
> > entries, these get quite large due to the number of counters we have.
> > The help text is ~100KiB on Linux and ~500KiB on IRIX.
> >
> > I'm currently testing on Linux and it seems that send_trans_reply thinks
> > this is too large a chunk of data to send and I get the following
> > failure:
> >
> > [2005/12/24 13:26:42, 5] smbd/ipc.c:send_trans_reply(89)
> > send_trans_reply: buffer 1024 too large
> > [2005/12/24 13:26:42, 3] smbd/error.c:error_packet(146)
> > error packet at smbd/ipc.c(97) cmd=37 (SMBtrans) STATUS_BUFFER_OVERFLOW
> >
> > Is this behaviour to be expected? Is there something I can do to work
> > around it?
> >
> > The test program in question does a RegQueryValueEx starting with a
> > 16KiB buffer. It grows the buffer by 16KiB each time is gets a
> > ERROR_MORE_DATA return value.
>
> Can you send me the test program please. I'll ensure this gets fixed.
see attached
--
James Peach | jpeach at sgi.com | SGI Australian Software Group
I don't speak for SGI.
-------------- next part --------------
/*
* Dump performance counter data.
*
* Copyright (C) 2005 Silicon Graphics, Inc. All rights reserved.
* James Peach <jpeach at sgi.com>
*
* This program 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.
*
* This program 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 this program; if not, write to the Free Software
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*/
#include "stdafx.h"
const char PROGNAME[] = "perfdump";
#define FORMAT_ERROR(err) format_error(__FILE__, __LINE__, err)
#define XFORMAT_ERROR(err) xformat_error(__FILE__, __LINE__, err)
void format_error(const char * file, int line, DWORD errcode)
{
LPVOID lpMsgBuf;
::FormatMessage(
FORMAT_MESSAGE_ALLOCATE_BUFFER |
FORMAT_MESSAGE_FROM_SYSTEM,
NULL,
errcode,
MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT),
(LPTSTR) &lpMsgBuf,
0, NULL );
std::cerr << PROGNAME << ": " << file << "(" << line << "): error " << errcode
<< ": " << ((char *)lpMsgBuf ? (char *)lpMsgBuf : "<unknown>")
<< std::flush;
LocalFree(lpMsgBuf);
}
void xformat_error(const char * file, int line, DWORD errcode)
{
format_error(file, line, errcode);
ExitProcess(errcode);
}
void dump_buffer(const char * prefix, const char * fname, void * buf, size_t bufsz)
{
char namebuf[1024];
FILE * fp;
sprintf(namebuf, "%s-%s", prefix, fname);
if (fp = fopen(namebuf, "wb"))
{
std::cout << "dumping " << bufsz << " bytes in " << namebuf << std::endl;
fwrite(buf, bufsz, 1, fp);
fclose(fp);
}
else
{
std::cerr << "failed to create " << namebuf << std::endl;
}
}
bool open_reg_key(const char * server, HKEY root, const char * subkey, HKEY * rkey)
{
LONG result = ERROR_SUCCESS;
if (server)
{
HKEY tmp;
result = RegConnectRegistry(server, root, &tmp);
if (result != ERROR_SUCCESS)
{
XFORMAT_ERROR(result);
return(false);
}
root = tmp;
}
/* Return the root key if no subkey wanted. */
*rkey = root;
if (subkey)
{
HKEY skey;
result = RegOpenKeyEx(root, subkey, 0, KEY_READ, &skey);
if (server)
RegCloseKey(*rkey);
*rkey = skey;
}
if (result != ERROR_SUCCESS)
XFORMAT_ERROR(result);
return(result == ERROR_SUCCESS);
}
bool query_reg_key(HKEY key, const char * value, void ** buf, DWORD * bufsz)
{
LONG result;
*bufsz = 0;
do
{
*bufsz += 16384;
*buf = realloc(*buf, *bufsz);
result = RegQueryValueEx(key, value, NULL, NULL,
(LPBYTE)*buf, bufsz);
} while (result == ERROR_MORE_DATA);
if (result != ERROR_SUCCESS)
XFORMAT_ERROR(result);
return (result == ERROR_SUCCESS);
}
void dump_perflib_names(const char * server, const char * fname)
{
void * buf = NULL;
DWORD bufsz = 0;
HKEY key;
std::cout << "fetching metric names" << std::endl;
open_reg_key(server, HKEY_LOCAL_MACHINE, "SOFTWARE\\Microsoft\\Windows NT\\CurrentVersion\\Perflib\\009", &key);
query_reg_key(key, "Counters", &buf, &bufsz);
dump_buffer(server ? server+2 : "local", fname, buf, bufsz);
}
void dump_perflib_help(const char * server, const char * fname)
{
void * buf = NULL;
DWORD bufsz = 0;
HKEY key;
std::cout << "fetching metric help" << std::endl;
open_reg_key(server, HKEY_LOCAL_MACHINE, "SOFTWARE\\Microsoft\\Windows NT\\CurrentVersion\\Perflib\\009", &key);
query_reg_key(key, "Help", &buf, &bufsz);
dump_buffer(server ? server+2 : "local", fname, buf, bufsz);
}
void dump_perflib_data(const char * server, const char * fname)
{
void * buf = NULL;
DWORD bufsz = 0;
HKEY key;
std::cout << "fetching metric data" << std::endl;
open_reg_key(server, HKEY_PERFORMANCE_DATA, NULL, &key);
query_reg_key(key, "Global", &buf, &bufsz);
dump_buffer(server ? server+2 : "local", fname, buf, bufsz);
}
int main(int argc, char ** argv)
{
// usage: perfdump [\\server]
dump_perflib_names(argc > 1 ? argv[1] : NULL, "names.dat");
dump_perflib_help(argc > 1 ? argv[1] : NULL, "help.dat");
dump_perflib_data(argc > 1 ? argv[1] : NULL, "data.dat");
return 0;
}
More information about the samba-technical
mailing list