Обсуждение: compile error via SIOCGLIFCONF from ip.c on hpux-11

Поиск
Список
Период
Сортировка

compile error via SIOCGLIFCONF from ip.c on hpux-11

От
Merlin Moncure
Дата:
PostgreSQL 9 is breaking for me on line 654 of ip.c.  ip.c is checking
on presence SIOCGLIFCONF to determine if it's ok to use linux method
of polling if addrs etc over ioctl, which is not enough. hpux provides
this method in similar fashion, but the structs are named different,
and have different members.


for example, we have:
struct  if_laddrreq {       char    iflr_name[IF_NAMESIZE];            /* if name, e.g. "lan0" */       union {
     struct  sockaddr_ext iflru_addr;               struct  sockaddr_ext iflru_dstaddr;               int
iflru_flags;
#if defined(__STDC_EXT__) || defined(__LP64__)               uint64_t iflru_xflags;
#endif               int     iflru_metric;               struct  iflife  iflru_lifetimes;               caddr_t
iflru_data;              unsigned char  __iflru_padding[32]; /* alignment for 32/64bit*/       } iflr_iflru;
 

which is similar to      struct ifreq {   char ifr_name[IFNAMSIZ]; /* Interface name */   union {       struct sockaddr
ifr_addr;      struct sockaddr ifr_dstaddr;       struct sockaddr ifr_broadaddr;       struct sockaddr ifr_netmask;
 struct sockaddr ifr_hwaddr;       short           ifr_flags;       int           ifr_ifindex;       int
ifr_metric;      int           ifr_mtu;       struct ifmap    ifr_map;       char           ifr_slave[IFNAMSIZ];
char          ifr_newname[IFNAMSIZ];       char *           ifr_data;   };      };
 

(via http://unixhelp.ed.ac.uk/CGI/man-cgi?netdevice+7)

forcing the #if check of SIOCGLIFCONF to false allowed postgres to
continue and compile.  Searching the archives turned up the
samehost/samenet patch...did that break this?  was hpux checked, or is
this a version issue? (I'm testing on 11.23 Itanium).

merlin


Re: compile error via SIOCGLIFCONF from ip.c on hpux-11

От
Tom Lane
Дата:
Merlin Moncure <mmoncure@gmail.com> writes:
> PostgreSQL 9 is breaking for me on line 654 of ip.c.  ip.c is checking
> on presence SIOCGLIFCONF to determine if it's ok to use linux method
> of polling if addrs etc over ioctl, which is not enough. hpux provides
> this method in similar fashion, but the structs are named different,
> and have different members.

This was complained of last month, and the situation has not changed:
http://archives.postgresql.org/pgsql-general/2010-10/msg00408.php
        regards, tom lane


Re: compile error via SIOCGLIFCONF from ip.c on hpux-11

От
Merlin Moncure
Дата:
On Mon, Nov 29, 2010 at 1:38 PM, Tom Lane <tgl@sss.pgh.pa.us> wrote:
> Merlin Moncure <mmoncure@gmail.com> writes:
>> PostgreSQL 9 is breaking for me on line 654 of ip.c.  ip.c is checking
>> on presence SIOCGLIFCONF to determine if it's ok to use linux method
>> of polling if addrs etc over ioctl, which is not enough. hpux provides
>> this method in similar fashion, but the structs are named different,
>> and have different members.
>
> This was complained of last month, and the situation has not changed:
> http://archives.postgresql.org/pgsql-general/2010-10/msg00408.php

well, what should the fix be?  checking on presence of SIOCGLIFCONF is
obviously weak sauce...it looks like some type of configure check is
needed  I converted the function to a version that compiles clean on
hpux (note, I couldn't figure out how to set family, maybe that's not
required?).  How do you test this feature?

merlin

int
pg_foreach_ifaddr(PgIfAddrCallback callback, void *cb_data)
{       struct if_laddrconf lifc;       struct  if_laddrreq *lifr,                               lmask;       struct
sockaddr*addr,                          *mask;       char       *ptr,                          *buffer = NULL;
size_t         n_buffer = 1024;       pgsocket        sock,                               fd; 

#ifdef HAVE_IPV6       pgsocket        sock6;
#endif       int                     i,                               total;
       sock = socket(AF_INET, SOCK_DGRAM, 0);       if (sock == -1)               return -1;
       while (n_buffer < 1024 * 100)       {               n_buffer += 1024;               ptr = realloc(buffer,
n_buffer);              if (!ptr)               {                       free(buffer);
close(sock);                      errno = ENOMEM;                       return -1;               } 
               memset(&lifc, 0, sizeof(lifc));               /* XXX how to set family? lifc.iflc_family = AF_UNSPEC; */
             lifc.iflc_buf = buffer = ptr;               lifc.iflc_len = n_buffer; 
               if (ioctl(sock, SIOCGLIFCONF, &lifc) < 0)               {                       if (errno == EINVAL)
                         continue;                       free(buffer);                       close(sock);
       return -1;               } 
               /*                * Some Unixes try to return as much data as possible, with no                *
indicationof whether enough space allocated. Don't 
believe we have                * it all unless there's lots of slop.                */               if (lifc.iflc_len
<n_buffer - 1024)                       break;      } 

#ifdef HAVE_IPV6       /* We'll need an IPv6 socket too for the SIOCGLIFNETMASK ioctls */       sock6 =
socket(AF_INET6,SOCK_DGRAM, 0);       if (sock6 == -1)       {               free(buffer);               close(sock);
           return -1;       } 
#endif
       total = lifc.iflc_len / sizeof(struct lifreq);       lifr = lifc.iflc_req;       for (i = 0; i < total; ++i)
 {               addr = (struct sockaddr *) & lifr[i].iflr_addr;               memcpy(&lmask, &lifr[i], sizeof(struct
lifreq));
#ifdef HAVE_IPV6               fd = (addr->sa_family == AF_INET6) ? sock6 : sock;
#else               fd = sock;
#endif               if (ioctl(fd, SIOCGLIFNETMASK, &lmask) < 0)                       mask = NULL;               else
                    mask = (struct sockaddr *) & lmask.iflr_addr;               run_ifaddr_callback(callback, cb_data,
addr,mask);       } 
       free(buffer);       close(sock);
#ifdef HAVE_IPV6       close(sock6);
#endif       return 0;
}


Re: compile error via SIOCGLIFCONF from ip.c on hpux-11

От
Tom Lane
Дата:
Merlin Moncure <mmoncure@gmail.com> writes:
> How do you test this feature?

Try src/tools/ifaddrs/test_ifaddrs.c.  I think the only usage in the
core code is testing samehost/samenet matches in pg_hba.conf.
        regards, tom lane


Re: compile error via SIOCGLIFCONF from ip.c on hpux-11

От
Merlin Moncure
Дата:
On Mon, Nov 29, 2010 at 2:26 PM, Tom Lane <tgl@sss.pgh.pa.us> wrote:
> Merlin Moncure <mmoncure@gmail.com> writes:
>> How do you test this feature?
>
> Try src/tools/ifaddrs/test_ifaddrs.c.  I think the only usage in the
> core code is testing samehost/samenet matches in pg_hba.conf.

It looks like this is unfortunately more involved.  The test of my
adjustment above immediately failed with ENOENT, which you have to
expect on hpux apparently.   According to some googling (see:

http://cvsweb.netbsd.org/bsdweb.cgi/src/dist/bind/lib/isc/unix/Attic/ifiter_ioctl.c?rev=1.1.1.4.4.1&content-type=text/x-cvsweb-markup
and others), the long method returns ip6 addresses and the short
method returns ip4 addresses, and you have to do both on hpux always.

Forcing the short method, the test worked, I got the loopback and the
local address.  So we have a couple of options here: hacking the
foreach to use the short method on hpux is certainly better situation
than we have now, or fixing this 'properly', means refactoring this
file a bit and adding a configure test or leaning on an hpux macro.  I
have no way of testing the long form method I posed above -- does
anybody have an ipv6 hpux box?

merlin