• Open Menu Close Menu
  • Apple
  • Shopping Bag
  • Apple
  • Mac
  • iPad
  • iPhone
  • Watch
  • TV
  • Music
  • Support
  • Search apple.com
  • Shopping Bag

Lists

Open Menu Close Menu
  • Terms and Conditions
  • Lists hosted on this site
  • Email the Postmaster
  • Tips for posting to public mailing lists
Filesystem debugging - was: my filesystem vs Finder. "error -50" what does it mean?
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Filesystem debugging - was: my filesystem vs Finder. "error -50" what does it mean?


  • Subject: Filesystem debugging - was: my filesystem vs Finder. "error -50" what does it mean?
  • From: Paul Nelson <email@hidden>
  • Date: Thu, 19 Apr 2012 00:06:52 -0500

One of the best things I ever did for myself was to add logging tricks to my filesystem.  My favorite trick is to log filesystem events on your network adapter.  This has these advantages:

  1. The logged events can be traced using the standard tcpdump or Wireshark
  2. It is very fast and won't slow down your kernel like printf does.  It is also 'atomic' so messages don't get mixed up like printf does.
  3. If your filesystem is a network file system, then you can see your log messages mixed in with your network traffic AND in the proper time relationship
  4. You can write a simple script to turn a tcpdump or Wireshark file into text using strings and grep.
  5. When using Wireshark, you can display your filesystem traffic and/or your log messages by adding or removing || udp to your filter (eg: nfs || udp)
  6. It is easy to see what app is calling your filesystem.  Once you have your log as text, you can grep for just that one app.  Remember that the Finder leverages many other processes besides its own.
  7. You can use Wireshark to look for vnop calls by searching your trace for text
  8. You can leave it in your shipping code if you like.  Even novice Mac users can be instructed on how to collect the trace data.  No special software need be installed since tcpdump comes standard.

Here is what I do:

a) Add some code to your kpi module start function to set up the multicast socket
#define MCAST_LOGGING 1
#if MCAST_LOGGING
// global stuff -
static socket_t mcast_logging_socket = 0;
struct sockaddr_in mcast_logging;
uint32_t com_mycompany_netlog = 0;
#endif
.
.
.

// in your start function, where error is your intended return value
#if MCAST_LOGGING
    if( !error )
    {
        errno_t err = sock_socket(AF_INET, SOCK_DGRAM, 0, NULL, NULL, &mcast_logging_socket);
        if( err == 0 )
        {
            xdebug_printf("sock_socket: %p\n", mcast_logging_socket);
            sock_setpriv(mcast_logging_socket, 1);
            uint32_t sndsize = 65536;
            sock_setsockopt(mcast_logging_socket, SOL_SOCKET, SO_SNDBUF, (void*)&sndsize, (int)sizeof(sndsize));
            memset( &mcast_logging, 0, sizeof(mcast_logging));
            mcast_logging.sin_family = AF_INET;
            // address 239.0.0.239
            mcast_logging.sin_len = sizeof(mcast_logging); // INET_ADDRSTRLEN?
            mcast_logging.sin_addr.s_addr = htonl(0xef0000ef);
            mcast_logging.sin_port = htons(9);
        }
        else printf("cifs_module_start_kpi sock_socket failed: %d\n", err);
    }
#endif

b) Be sure you close the socket when your kext is unloaded.
        sock_close(mcast_logging_socket);
c) Write a logging function that just logs raw data:
__private_extern__
void mykext_log_msgbuf( const char * pmsg, void* buf, size_t buflen)
{
    if( ! com_mycompany_netlog )
        return;
    if( mcast_logging_socket )
    {
        struct iovec aio[3];
        struct msghdr msg;
        char pad[1];
        size_t sent = 0;
        uint32_t ii=0;

        memset(&msg, 0, sizeof(msg));

        pad[0] = 0;
        aio[ii].iov_base = pad;
        aio[ii].iov_len = 1;
        ii++;
        aio[ii].iov_base = (void*)pmsg;
        aio[ii].iov_len = strlen(pmsg)+1;
        ii++;
        if( buf!=NULL && buflen > 0 )
        {
            aio[ii].iov_base=buf;
            aio[ii].iov_len = buflen;
            ii++;
        }
        msg.msg_name = &mcast_logging;
        msg.msg_namelen = sizeof(mcast_logging);
        msg.msg_iov = aio;
        msg.msg_iovlen = ii;
        errno_t err = sock_send(mcast_logging_socket, &msg, 0, &sent);
        if( err )
        {
            xdebug_printf("sock_send failed: %d\n", err); // EINVAL
            sock_close(mcast_logging_socket);
            mcast_logging_socket=0;
        }
    }
}
d) Write a more useful log function that fills out the log message with useful info.  Mine looks like this:
__private_extern__ void mykext_log_operation( pid_t pid, mount_t mp, const char * operation, vnode_t vp, const char * inFmt, ...)
{
    if( ! com_mycompany_netlog )
        return;
    static uint8_t sglogseq = 0;  // log a sequence number in case we suspect log messages getting dropped
    va_list listp;
    char * fpath = NULL;
    if( vp )
    {
fpath = mykext_vnode_path(vp); // your filesystem function to allocate and fill in a textual path to vp
        if( mp == NULL )
            mp = vnode_mount(vp);
    }
    char pmsg[512];
    {
// log a basic header that is the same for all messages
        char pname[MAXCOMLEN+1];
        pname[0] = 'X';
        pname[1] = 0;
        proc_name(pid, pname, sizeof(pname));
        snprintf(pmsg, sizeof(pmsg), "%s[%s,%d(%p) %2.2x]:", operation, pname, pid, current_thread(), sglogseq++);
    }

    if( inFmt )
    {
        char fmsg[512];
        va_start(listp, inFmt);
        vsnprintf(fmsg, sizeof(fmsg), inFmt, listp);
        strlcat(pmsg, fmsg, sizeof(pmsg));
        va_end(listp);
    }
    if( vp )
    {
        char vpinfo[64];
        snprintf(vpinfo, sizeof(vpinfo), "- (%p:%p):", vnode_mount(vp), vp);
        strlcat(pmsg, vpinfo, sizeof(pmsg));
    }
    strlcat(pmsg, fpath ? fpath : "***", sizeof(pmsg));
    mykext_log_msgbuf(pmsg, NULL, 0);
    if( fpath )
        _FREE(fpath, M_CIFSTEMP);
}
e) Add some logging to critical spots like your open function:
static int mykext_vnodeop_open(struct vnop_open_args *ap)
{
    int rval;
    if( SHOULD_LOG(LOG_OPENCLOSE))
        mykext_log_operation(vfs_context_pid(ap->a_context), vnode_mount(ap->a_vp), "mykext_vnodeop_open", ap->a_vp,
                           "enter a_mode=%x", ap->a_mode);
for example.  You might want to use a macro for mykext_log_operation so it is easy to leave out:
#define log_operation mykext_log_operation
#define xlog_operation

f) Add some way to turn the beast on and off.  I use a sysctl:
SYSCTL_UINT(_com_mycompany, OID_AUTO, netlog, CTLFLAG_RW|CTLFLAG_LOCKED, &com_mycompany_netlog, 0, "MYKEXT netlog enabled" );
// register your sysctls!
// after loading your kext
    sysctl_register_oid(& sysctl__com_mycompany_netlog);
// before unloading your kext:
    sysctl_unregister_oid(&sysctl__com_mycompany_netlog);


Set your logging control from the command line:
sudo sysctl -w com_mycompany.netlog=1; # turn on network logging
sudo sysctl -w com_mycompany.netlog=0; # turn off network logging

f) log your messages using tcpdump:
tcpdump -s 0 -i en0 -B 1024000 -w mykext.pcap

ctrl c to stop.  If you name your trace file with .pcap you can open it with Wireshark using the terminal command: open mykext.pcap

g) script to print out your trace file:
#!/bin/sh
strings "$1" | egrep "mykext_||vnodeop_"


I may have made some errors typing this up.  If so they should be easy to fix.
Hope this is useful to someone!
Paul
 _______________________________________________
Do not post admin requests to the list. They will be ignored.
Filesystem-dev mailing list      (email@hidden)
Help/Unsubscribe/Update your Subscription:

This email sent to email@hidden

References: 
 >my filesystem vs Finder. "error -50" what does it mean? (From: Anatol Pomozov <email@hidden>)
 >Re: my filesystem vs Finder. "error -50" what does it mean? (From: Jim Luther <email@hidden>)

  • Prev by Date: Re: my filesystem vs Finder. "error -50" what does it mean?
  • Next by Date: Is there any way to setup a non-HFS volume sharing with AFP?
  • Previous by thread: Re: my filesystem vs Finder. "error -50" what does it mean?
  • Next by thread: Re: my filesystem vs Finder. "error -50" what does it mean?
  • Index(es):
    • Date
    • Thread