On Fri, 6 Jan 2006, Alan Robertson wrote:

> Matthew Soffen wrote:
> > That is correct.  It didn't .   Also, Remember that many of the
> > functions use the HA malloc code which may/may not properly align things
> > in memory.
>
>
> It does indeed align things properly - it gets ALL its space from malloc.

In my particular case, I think we might be seeing an effect from elsewhere
in the heartbeat code.  (That is, that malloc() may well be fine and that
ha_malloc() may similarly be fine.)

Rather, is it possible that the "pool" code ("lib/clplumbing/ocf_ipc.c"?)
is doing naughty things?  For instance, does it do a relatively big
"malloc" (properly aligned) but then hand out (i.e. setting "currpos",
perhaps?) non-aligned chunks?  Does the pool code regard it merely as a
bytestream, rather than something which may contain entities requiring
alignment?

Could someone who knows this area confirm this possibility (or
definitively refute it), please?

If this is the case, then one solution is for its author (or current
maintainer) to rework it to handle alignment.

Alternatively, the attached patch fixes its effects, by replacing the two
(known, remaining) instances of integer assignments by "memcpy()".(*)

(*) Actually he patch itself has a strange wrinkle, documented in its
comment.


-- 

:  David Lee                                I.T. Service          :
:  Senior Systems Programmer                Computer Centre       :
:                                           Durham University     :
:  http://www.dur.ac.uk/t.d.lee/            South Road            :
:                                           Durham DH1 3LE        :
:  Phone: +44 191 334 2752                  U.K.                  :
--- ipcsocket.c.orig    Wed Dec  7 10:07:12 2005
+++ ipcsocket.c Mon Jan  9 12:53:39 2006
@@ -80,6 +80,28 @@
 #define         AF_LOCAL AF_UNIX
 #endif
 
+/*
+ * Code used to have:
+ *     head->msg_len = msg->msg_len;
+ * (and similarly: "head->magic = HEADMAGIC;").
+ *
+ * But it (pool code?) sometimes points "head" at an improperly aligned
+ * (e.g. non-word) location, causing crash on some architectures.
+ *     
+ * The following ought to be able to replace it:
+ *    memcpy(&(head->msg_len), &(msg->msg_len), sizeof(int));
+ *
+ * But for some strange, unknown reason, that doesn't work on Solaris.
+ * Seems to need intermediate variables.  Instead:
+ */
+#if 1
+#define MEMCPY(to,from,len) \
+  { void *pt = to; void *pf = from; memcpy(pt, pf, len); }
+#else
+#define MEMCPY(to,from,len) \
+  memcpy(to, from, len)
+#endif
+
 /***********************************************************************
  *
  * Determine the IPC authentication scheme...  More machine dependent than
@@ -1301,6 +1323,7 @@
                char*                           p;
                unsigned int                    bytes_remaining;
                int                             diff;
+               int                             magic = HEADMAGIC;
  
                CHANAUDIT(ch);
                element = g_list_first(ch->send_queue->queue);
@@ -1335,8 +1358,8 @@
                }
                
                head = (struct SOCKET_MSG_HEAD*) msg->msg_buf;
-                head->msg_len = msg->msg_len;
-               head->magic = HEADMAGIC;
+               MEMCPY(&(head->msg_len), &(msg->msg_len), sizeof(int));
+               MEMCPY(&(head->magic), &magic, sizeof(unsigned int));
                
                if (ch->bytes_remaining == 0){
                        /*we start to send a new message*/
_______________________________________________________
Linux-HA-Dev: [email protected]
http://lists.linux-ha.org/mailman/listinfo/linux-ha-dev
Home Page: http://linux-ha.org/

Reply via email to