From alane@geeksrus.net  Sun Dec  9 01:03:33 2001
Return-Path: <alane@geeksrus.net>
Received: from wwweasel.geeksrus.net (wwweasel.geeksrus.net [64.67.200.82])
	by hub.freebsd.org (Postfix) with ESMTP id DF6CB37B416
	for <FreeBSD-gnats-submit@freebsd.org>; Sun,  9 Dec 2001 01:03:32 -0800 (PST)
Received: (from alane@localhost)
	by wwweasel.geeksrus.net (8.11.6/8.11.6) id fB992u294974;
	Sun, 9 Dec 2001 04:02:56 -0500 (EST)
	(envelope-from alane)
Message-Id: <200112090902.fB992u294974@wwweasel.geeksrus.net>
Date: Sun, 9 Dec 2001 04:02:56 -0500 (EST)
From: Alan E <alane@geeksrus.net>
Reply-To: Alan E <alane@geeksrus.net>
To: FreeBSD-gnats-submit@freebsd.org
Cc:
Subject: freeamp: preference AllowMultipleInstances=false does not work
X-Send-Pr-Version: 3.113
X-GNATS-Notify:

>Number:         32639
>Category:       ports
>Synopsis:       freeamp: preference AllowMultipleInstances=false does not work
>Confidential:   no
>Severity:       serious
>Priority:       medium
>Responsible:    ade
>State:          closed
>Quarter:        
>Keywords:       
>Date-Required:  
>Class:          sw-bug
>Submitter-Id:   current-users
>Arrival-Date:   Sun Dec 09 01:10:01 PST 2001
>Closed-Date:    Fri Apr 12 19:56:01 PDT 2002
>Last-Modified:  Fri Apr 12 19:56:01 PDT 2002
>Originator:     Alan E
>Release:        FreeBSD 4.4-STABLE i386
>Organization:
Geeksrus.NET
>Environment:
System: FreeBSD wwweasel.geeksrus.net 4.4-STABLE FreeBSD 4.4-STABLE #0: Sun Dec 2 19:14:12 EST 2001 root@wwweasel.geeksrus.net:/usr/obj/usr/src/sys/WWWEASEL i386
>Description:
Freeamp has a preference to cause it to delegate actions to an already
running freeamp and exit. This does not, and *cannot*, work on FreeBSD the
way it is designed.

I'm going to describe a mismatch between freeamp's design and FreeBSD's
process implementation.

The first instance of freeamp to start up creates a semaphore. It puts its
PID in the semaphore using semctl. Other freeamps check the value in the
semaphore to see if they are subordinate to the first and should exit if the
user pref AllowMultipleInstances is false.

Semctl uses a union semun to hold values. This union is just a bit misleading.
It looks like this (/usr/include/sys/sem.h):

union semun {
	int	val;		/* value for SETVAL */
	struct	semid_ds *buf;	/* buffer for IPC_STAT & IPC_SET */
	u_short	*array;		/* array for GETALL & SETALL */
};

You'd think you could put an int value into a semaphore with the SETVAL
operator, wouldn't you? Yes? You'd be wrong. The value a semaphore can hold
is really a "u_short", seen in the array for GETALL and SETALL values. 
(Is this clearly documented anywhere? Well, no, but I don't recall ever
seeing it clearly documented anywhere outside of a Stevens book.)

FreeBSD uses an int as its PID type. A 32 bit int. It's defined in
<machine/ansi.h>, which is included by <sys/inttypes.h>, which is included
by <sys/types.h>, which is included by <unistd.h>. Easy to find.

C++ does type checking. So, we'll get warned when we try to store a 32-bit
PID into a 16-bit semaphore value, right? Umm, no, that brain-damaged union
with the "int val" that really only holds a short int kills our hopes of
that.

So, can this be fixed? No, not short of a design change in freeamp to
communicate that PID some other way to other, non-child freeamp processes.

>How-To-Repeat:

Set the AllowMultipleInstances preference to false. Start up two Freeamp
instances. See two Freeamp instances.

Note: if the master freeamp has a low process ID (< USHRT_MAX), the feature
should work. If this happens, start and kill a few thousand processes and
try again. 

You can also patch freeamp/base/unix/src/bootstrap.cpp to show you what PID
it thinks is its master. I can supply that patch on request.

To see the semaphore problem in an isolated state, compile and run this
program:

---8<-snip---8<-snip---8<-snip---8<-snip---8<-snip---8<-snip---8<---
#include <stdio.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/ipc.h>
#include <sys/sem.h> 
#include <sys/shm.h> 
#include <sys/types.h>
#include <signal.h>

const int iSemKey = 0xDEADBEEF;

int 
main(int argc, char **argv) 
{
    int        rc = 0;
    int        iCmdSem = -1;
    key_t      tSemKey = iSemKey;
    int        iSemVal;

    union semun unsem;

    iCmdSem = semget(tSemKey, 1, IPC_CREAT | 0660);
    unsem.val = 0xDEADBEEF;
    semctl(iCmdSem, 0, SETVAL, unsem);
    iSemVal = semctl(iCmdSem, 0, GETVAL, unsem);
    if (iSemVal == unsem.val) {
      printf("semctl(SETVAL) and GETVAL agree\n");
    } else {
      rc = 1;
      printf("OHSHIT! semctl(SETVAL,%08x) but GETVAL=> %08x\n",
	     unsem.val, iSemVal);
    }

    return rc;
}
---8<-snip---8<-snip---8<-snip---8<-snip---8<-snip---8<-snip---8<---

>Fix:

Design a new method for freeamp to use to communicate the PID of the
"master" instance to any new new freeamps that are started.

For Extra Credit:

Try to get the freeamp team, who have never answered email in my experience,
to accept a design-changing patch for an OS they don't officially support.

For Extra Extra Credit:

Try to get the freeamp team to admit to having brain-lock when they assumed
that a PID was a short int.

For the Nobel Prize:

Fix the "union semun" to have a "short int" val, or fix the semaphore
implementation to allow "int" values. Fix all the applications and ports
that break because of the fix; remember, things will break because of
signedness as well as number of bits. Convince at least 2 authors whose apps
you broke that *you* aren't brain-damaged for changing a broken legacy
structure that so many things depend on.


>Release-Note:
>Audit-Trail:
State-Changed-From-To: open->analyzed 
State-Changed-By: petef 
State-Changed-When: Tue Feb 19 18:59:02 PST 2002 
State-Changed-Why:  
This requires a design change:  we're still waiting on the freeamp maintainers 
to adopt this. 

http://www.FreeBSD.org/cgi/query-pr.cgi?pr=32639 
State-Changed-From-To: analyzed->closed 
State-Changed-By: ade 
State-Changed-When: Fri Apr 12 19:55:13 PDT 2002 
State-Changed-Why:  
Requires update by authors of software, not port maintainers. 
Timeout in analyzed (2 months). 


Responsible-Changed-From-To: freebsd-ports->ade 
Responsible-Changed-By: ade 
Responsible-Changed-When: Fri Apr 12 19:55:13 PDT 2002 
Responsible-Changed-Why:  
My fault[tm] 

http://www.freebsd.org/cgi/query-pr.cgi?pr=32639 
>Unformatted:
