summaryrefslogtreecommitdiff
path: root/source3/smbd/process.c
diff options
context:
space:
mode:
authortodd stecher <todd.stecher@gmail.com>2009-02-08 23:10:34 -0800
committerTim Prouty <tprouty@samba.org>2009-02-09 13:23:44 -0800
commit54c51a66e3e31c70a641d7efac2d4b08c3007278 (patch)
tree01ea8154819950eec666579dfeaad7724cf3fdb1 /source3/smbd/process.c
parent98a4327b19e83ffad4e0be7e8895fdbd9e48d49f (diff)
downloadsamba-54c51a66e3e31c70a641d7efac2d4b08c3007278.tar.gz
samba-54c51a66e3e31c70a641d7efac2d4b08c3007278.tar.bz2
samba-54c51a66e3e31c70a641d7efac2d4b08c3007278.zip
S3: New module interface for SMB message statistics gathering
This changelist allows for the addition of custom performance monitoring modules through smb.conf. Entrypoints in the main message processing code have been added to capture the command, subop, ioctl, identity and message size statistics.
Diffstat (limited to 'source3/smbd/process.c')
-rw-r--r--source3/smbd/process.c61
1 files changed, 45 insertions, 16 deletions
diff --git a/source3/smbd/process.c b/source3/smbd/process.c
index 8539e04bd5..1262d01840 100644
--- a/source3/smbd/process.c
+++ b/source3/smbd/process.c
@@ -32,9 +32,10 @@ static void construct_reply_common(struct smb_request *req, const char *inbuf,
Send an smb to a fd.
****************************************************************************/
-bool srv_send_smb(int fd, char *buffer, bool do_encrypt)
+bool srv_send_smb(int fd, char *buffer, bool do_encrypt,
+ struct smb_perfcount_data *pcd)
{
- size_t len;
+ size_t len = 0;
size_t nwritten=0;
ssize_t ret;
char *buf_out = buffer;
@@ -48,7 +49,7 @@ bool srv_send_smb(int fd, char *buffer, bool do_encrypt)
DEBUG(0, ("send_smb: SMB encryption failed "
"on outgoing packet! Error %s\n",
nt_errstr(status) ));
- return false;
+ goto out;
}
}
@@ -60,12 +61,15 @@ bool srv_send_smb(int fd, char *buffer, bool do_encrypt)
DEBUG(0,("Error writing %d bytes to client. %d. (%s)\n",
(int)len,(int)ret, strerror(errno) ));
srv_free_enc_buffer(buf_out);
- return false;
+ goto out;
}
nwritten += ret;
}
+ SMB_PERFCOUNT_SET_MSGLEN_OUT(pcd, len);
srv_free_enc_buffer(buf_out);
+out:
+ SMB_PERFCOUNT_END(pcd);
return true;
}
@@ -373,6 +377,7 @@ void init_smb_request(struct smb_request *req,
req->conn = conn_find(req->tid);
req->chain_fsp = NULL;
req->chain_outbuf = NULL;
+ smb_init_perfcount_data(&req->pcd);
/* Ensure we have at least wct words and 2 bytes of bcc. */
if (smb_size + req->wct*2 > req_size) {
@@ -390,12 +395,13 @@ void init_smb_request(struct smb_request *req,
(unsigned int)req_size));
exit_server_cleanly("Invalid SMB request");
}
+
req->outbuf = NULL;
}
static void process_smb(struct smbd_server_connection *conn,
uint8_t *inbuf, size_t nread, size_t unread_bytes,
- bool encrypted);
+ bool encrypted, struct smb_perfcount_data *deferred_pcd);
static void smbd_deferred_open_timer(struct event_context *ev,
struct timed_event *te,
@@ -421,7 +427,7 @@ static void smbd_deferred_open_timer(struct event_context *ev,
process_smb(smbd_server_conn, inbuf,
msg->buf.length, 0,
- msg->encrypted);
+ msg->encrypted, &msg->pcd);
}
/****************************************************************************
@@ -453,6 +459,7 @@ static bool push_queued_message(struct smb_request *req,
msg->request_time = request_time;
msg->encrypted = req->encrypted;
+ SMB_PERFCOUNT_DEFER_OP(&req->pcd, &msg->pcd);
if (private_data) {
msg->private_data = data_blob_talloc(msg, private_data,
@@ -1354,7 +1361,9 @@ static connection_struct *switch_message(uint8 type, struct smb_request *req, in
Construct a reply to the incoming packet.
****************************************************************************/
-static void construct_reply(char *inbuf, int size, size_t unread_bytes, bool encrypted)
+static void construct_reply(char *inbuf, int size, size_t unread_bytes,
+ bool encrypted,
+ struct smb_perfcount_data *deferred_pcd)
{
connection_struct *conn;
struct smb_request *req;
@@ -1362,9 +1371,19 @@ static void construct_reply(char *inbuf, int size, size_t unread_bytes, bool enc
if (!(req = talloc(talloc_tos(), struct smb_request))) {
smb_panic("could not allocate smb_request");
}
+
init_smb_request(req, (uint8 *)inbuf, unread_bytes, encrypted);
req->inbuf = (uint8_t *)talloc_move(req, &inbuf);
+ /* we popped this message off the queue - keep original perf data */
+ if (deferred_pcd)
+ req->pcd = *deferred_pcd;
+ else {
+ SMB_PERFCOUNT_START(&req->pcd);
+ SMB_PERFCOUNT_SET_OP(&req->pcd, req->cmd);
+ SMB_PERFCOUNT_SET_MSGLEN_IN(&req->pcd, size);
+ }
+
conn = switch_message(req->cmd, req, size);
if (req->unread_bytes) {
@@ -1386,7 +1405,8 @@ static void construct_reply(char *inbuf, int size, size_t unread_bytes, bool enc
if (!srv_send_smb(smbd_server_fd(),
(char *)req->outbuf,
- IS_CONN_ENCRYPTED(conn)||req->encrypted)) {
+ IS_CONN_ENCRYPTED(conn)||req->encrypted,
+ &req->pcd)) {
exit_server_cleanly("construct_reply: srv_send_smb failed.");
}
@@ -1398,10 +1418,9 @@ static void construct_reply(char *inbuf, int size, size_t unread_bytes, bool enc
/****************************************************************************
Process an smb from the client
****************************************************************************/
-
static void process_smb(struct smbd_server_connection *conn,
uint8_t *inbuf, size_t nread, size_t unread_bytes,
- bool encrypted)
+ bool encrypted, struct smb_perfcount_data *deferred_pcd)
{
int msg_type = CVAL(inbuf,0);
@@ -1423,8 +1442,7 @@ static void process_smb(struct smbd_server_connection *conn,
show_msg((char *)inbuf);
- construct_reply((char *)inbuf,nread,unread_bytes,encrypted);
-
+ construct_reply((char *)inbuf,nread,unread_bytes,encrypted,deferred_pcd);
trans_num++;
done:
@@ -1617,16 +1635,24 @@ void chain_reply(struct smb_request *req)
*/
smb_setlen((char *)(req->chain_outbuf),
talloc_get_size(req->chain_outbuf) - 4);
+
if (!srv_send_smb(smbd_server_fd(), (char *)req->chain_outbuf,
IS_CONN_ENCRYPTED(req->conn)
- ||req->encrypted)) {
+ ||req->encrypted,
+ &req->pcd)) {
exit_server_cleanly("chain_reply: srv_send_smb "
"failed.");
}
TALLOC_FREE(req);
+
return;
}
+ /* add a new perfcounter for this element of chain */
+ SMB_PERFCOUNT_ADD(&req->pcd);
+ SMB_PERFCOUNT_SET_OP(&req->pcd, chain_cmd);
+ SMB_PERFCOUNT_SET_MSGLEN_IN(&req->pcd, smblen);
+
/*
* Check if the client tries to fool us. The request so far uses the
* space to the end of the byte buffer in the request just
@@ -1735,7 +1761,8 @@ void chain_reply(struct smb_request *req)
show_msg((char *)(req->chain_outbuf));
if (!srv_send_smb(smbd_server_fd(), (char *)req->chain_outbuf,
- IS_CONN_ENCRYPTED(req->conn)||req->encrypted)) {
+ IS_CONN_ENCRYPTED(req->conn)||req->encrypted,
+ &req->pcd)) {
exit_server_cleanly("construct_reply: srv_send_smb failed.");
}
TALLOC_FREE(req);
@@ -1823,7 +1850,7 @@ static void smbd_server_connection_read_handler(struct smbd_server_connection *c
}
process:
- process_smb(conn, inbuf, inbuf_len, unread_bytes, encrypted);
+ process_smb(conn, inbuf, inbuf_len, unread_bytes, encrypted, NULL);
}
static void smbd_server_connection_handler(struct event_context *ev,
@@ -1988,7 +2015,7 @@ void smbd_process(void)
unsigned char buf[5] = {0x83, 0, 0, 1, 0x81};
DEBUG( 1, ("Connection denied from %s\n",
client_addr(get_client_fd(),addr,sizeof(addr)) ) );
- (void)srv_send_smb(smbd_server_fd(),(char *)buf,false);
+ (void)srv_send_smb(smbd_server_fd(),(char *)buf,false, NULL);
exit_server_cleanly("connection denied");
}
@@ -1996,6 +2023,8 @@ void smbd_process(void)
init_modules();
+ smb_perfcount_init();
+
if (!init_account_policy()) {
exit_server("Could not open account policy tdb.\n");
}