Browse Source

Extend link detection time, with a progress bar. Closes: #414117

Simple function to check repetitively for link and update a progress bar as
we do so.  In the simplest case, we'll find link immediately and move on
with our lives; in the worst case, the setup will be delayed by 3 seconds
times the number of interfaces (if there is no link anywhere).  It will,
however, not slow anything down if link is detected immediately, and it
should definitely solve the "link detection" problems people have been
seeing.
tags/1.60
Matt Palmer 10 years ago
parent
commit
145c337cd0
7 changed files with 65 additions and 22 deletions
  1. +1
    -1
      Makefile
  2. +4
    -1
      debian/changelog
  3. +4
    -0
      debian/netcfg-common.templates
  4. +12
    -12
      ethtool-lite.c
  5. +34
    -0
      netcfg-common.c
  6. +2
    -7
      netcfg.c
  7. +8
    -1
      netcfg.h

+ 1
- 1
Makefile View File

@@ -26,7 +26,7 @@ endif

all: $(TARGETS)

netcfg-static: netcfg-static.o static.o
netcfg-static: netcfg-static.o static.o ethtool-lite.o
netcfg: netcfg.o dhcp.o static.o ethtool-lite.o

ethtool-lite: ethtool-lite-test.o


+ 4
- 1
debian/changelog View File

@@ -8,8 +8,11 @@ netcfg (1.60) UNRELEASED; urgency=low
* Modify ethtool-lite so that it distinguishes between "ethtool failed"
and "ethtool says link is down". This should reduce link up/link down
confusion. Closes: #496647.
* Wait for up to 3 seconds (in 0.25s increments) looking for the link on
an interface. Add a progress bar to show the progress of this
operation. Closes: #414117.

-- Matt Palmer <mpalmer@debian.org> Fri, 21 Jan 2011 12:44:21 +1100
-- Matt Palmer <mpalmer@debian.org> Sat, 22 Jan 2011 10:34:25 +1100

netcfg (1.59) unstable; urgency=low



+ 4
- 0
debian/netcfg-common.templates View File

@@ -173,6 +173,10 @@ Default: false
Description: for internal use; can be preseeded
Set to true to force static network configuration

Template: netcfg/link_detect_progress
Type: text
_Description: Detecting link on ${interface}; please wait...

Template: netcfg/internal-none
Type: text
# :sl2:


+ 12
- 12
ethtool-lite.c View File

@@ -43,7 +43,7 @@ struct ethtool_value
#ifdef TEST
int main(int argc, char** argv)
#else
int ethtool_lite (char * iface)
int ethtool_lite (const char * iface)
#endif
{
#ifdef TEST
@@ -53,14 +53,14 @@ int ethtool_lite (char * iface)

if (fd < 0)
{
di_warning("could not open control socket\n");
di_warning("ethtool-lite: could not open control socket\n");
return UNKNOWN;
}

#ifdef TEST
if (argc < 2)
{
fprintf(stderr, "Error: must pass an interface name\n");
fprintf(stderr, "ethtool-lite: Error: must pass an interface name\n");
return 1;
}
iface = argv[1];
@@ -77,13 +77,13 @@ int ethtool_lite (char * iface)

if (ioctl (fd, SIOCETHTOOL, &ifr) >= 0)
{
di_info("%s is %sconnected.\n", iface,
di_info("ethtool-lite: %s is %sconnected.\n", iface,
(edata.data) ? "" : "dis");
return (edata.data) ? CONNECTED : DISCONNECTED;
}
else
{
di_info("ethtool ioctl on %s failed\n", iface);
di_info("ethtool-lite: ethtool ioctl on %s failed\n", iface);
u_int16_t *data = (u_int16_t *)&ifr.ifr_data;
int ctl;
data[0] = 0;
@@ -94,7 +94,7 @@ int ethtool_lite (char * iface)
ctl = SIOCDEVPRIVATE + 1;
else
{
di_warning("couldn't determine MII ioctl to use for %s\n", iface);
di_warning("ethtool-lite: couldn't determine MII ioctl to use for %s\n", iface);
return UNKNOWN;
}

@@ -104,14 +104,14 @@ int ethtool_lite (char * iface)
{
int ret = !(data[3] & 0x0004);

di_info ("%s is %sconnected. (MII)\n", iface,
di_info ("ethtool-lite: %s is %sconnected. (MII)\n", iface,
(ret) ? "dis" : "");

return ret ? DISCONNECTED : CONNECTED;
}
}

di_warning("MII ioctl failed for %s\n", iface);
di_warning("ethtool-lite: MII ioctl failed for %s\n", iface);

#elif defined(__FreeBSD_kernel__)
struct ifmediareq ifmr;
@@ -120,21 +120,21 @@ int ethtool_lite (char * iface)
strncpy(ifmr.ifm_name, iface, sizeof(ifmr.ifm_name));

if (ioctl(fd, SIOCGIFMEDIA, (caddr_t)&ifmr) < 0) {
di_warning("SIOCGIFMEDIA ioctl on %s failed\n", iface);
di_warning("ethtool-lite: SIOCGIFMEDIA ioctl on %s failed\n", iface);
return UNKNOWN;
}

if (ifmr.ifm_status & IFM_AVALID) {
if (ifmr.ifm_status & IFM_ACTIVE) {
di_info("%s is connected.\n", iface);
di_info("ethtool-lite: %s is connected.\n", iface);
return CONNECTED;
} else {
di_info("%s is disconnected.\n", iface);
di_info("ethtool-lite: %s is disconnected.\n", iface);
return DISCONNECTED;
}
}

di_warning("couldn't determine status for %s\n", iface);
di_warning("ethtool-lite: couldn't determine status for %s\n", iface);
#endif
return UNKNOWN;
}

+ 34
- 0
netcfg-common.c View File

@@ -980,3 +980,37 @@ void netcfg_update_entropy (void)
di_exec_shell("ip addr show >/dev/random");
#endif
}

/* Bring up an interface and attempt to find out whether we've got link.
* Use a progress bar so the user knows what's going on. Return true
* if we got link, and false otherwise.
*/
int netcfg_detect_link(struct debconfclient *client, const char *if_name)
{
int wait_count, rv = 0;
interface_up(if_name);
debconf_capb(client, "progresscancel");
debconf_subst(client, "netcfg/link_detect_progress", "interface", if_name);
debconf_progress_start(client, 0, NETCFG_LINK_WAIT_TIME * 4, "netcfg/link_detect_progress");
for (wait_count = 0; wait_count < NETCFG_LINK_WAIT_TIME * 4; wait_count++) {
usleep(250000);
if (debconf_progress_step(client, 1) == 30) {
/* User cancelled on us... bugger */
rv = 0;
break;
}
if (ethtool_lite (if_name) == 1) /* ethtool-lite's CONNECTED */ {
debconf_progress_set(client, NETCFG_LINK_WAIT_TIME * 4);
rv = 1;
break;
}
}

interface_down(if_name);
debconf_progress_stop(client);
debconf_capb(client, "");
return rv;
}

+ 2
- 7
netcfg.c View File

@@ -116,7 +116,7 @@ int main(int argc, char *argv[])
case BACKUP:
return 10;
case GET_INTERFACE:
/* Choose a default from ethtool-lite */
/* Choose a default by looking for link */
if (get_all_ifs(1, &ifaces) > 1) {
while (*ifaces) {
if (check_kill_switch(*ifaces)) {
@@ -133,14 +133,9 @@ int main(int argc, char *argv[])
}
}

interface_up(*ifaces);

usleep(250);

if (ethtool_lite (*ifaces) == 1) /* CONNECTED */ {
if (netcfg_detect_link (client, *ifaces) == 1) /* CONNECTED */ {
di_info("found link on interface %s, making it the default.", *ifaces);
defiface = strdup(*ifaces);
interface_down(*ifaces);
break;
} else {
#ifdef WIRELESS


+ 8
- 1
netcfg.h View File

@@ -41,6 +41,12 @@
"ff02::1 ip6-allnodes\n" \
"ff02::2 ip6-allrouters\n"

/* The time, in seconds, that we will wait for a link to be established
* via link autonegotiation. Sometime in the future this may become a
* preseed option.
*/
#define NETCFG_LINK_WAIT_TIME 3

typedef enum { NOT_ASKED = 30, GO_BACK } response_t;
typedef enum { DHCP, STATIC, DUNNO } method_t;
typedef enum { ADHOC = 1, MANAGED = 2 } wifimode_t;
@@ -135,6 +141,7 @@ extern void netcfg_update_entropy (void);

extern int netcfg_write_resolv (char*, struct in_addr *);

extern int ethtool_lite (char*);
extern int ethtool_lite (const char *if_name);
extern int netcfg_detect_link(struct debconfclient *client, const char *if_name);

#endif /* _NETCFG_H_ */

Loading…
Cancel
Save