Linux Archive

Linux Archive (http://www.linux-archive.org/)
-   Kubuntu User (http://www.linux-archive.org/kubuntu-user/)
-   -   Support long 'option domain-name' values in loader (#578110) (http://www.linux-archive.org/kubuntu-user/409684-support-long-option-domain-name-values-loader-578110-a.html)

08-07-2010 05:42 AM

Support long 'option domain-name' values in loader (#578110)
 
From: David Cantrell <dcantrell@redhat.com>

During anaconda installation, resolv.conf is not updated with the proper
domain name in the "search" field if the domain name is too long. Eg,

/etc/dhcpd.conf
---------------------
option domain-name stl.kewr1.s.vonagenetworks.net
stl.kewr1.m.vonagenetworks.net vonagenetworks.net vonage.net vonage.com";
---------------------

This happens only during the install process ONLY; that the system
correctly generates resolv.conf once installed.

This occured by the limitation of setdomainname() and getdomainame() in
doDhcp(). setdomainame() and getdomainname() cannot use with the string
exceeding a length of 64 bytes.

In doDhcp(), a child process is created to get the information from DHCP
with libdhcp. The child process executes setdomainname() with the domain
information collected from DHCP. That's what they configured with
"option domain-name". If it exceeds a length of 64 bytes,
setdomainname() fails and the following error message is outputed.

failed to set domain name in doDhcp: Invalid argument

On the other hand, the parent process waits the child process to exit.
And then, it tries to get the domain information with getdomainname().
But, it should get empty string because setdomainname() failed by the
child process. As the result, nothing is set to 'search' in resolv.conf.

setdomainanme() and getdomainname() are used to pass the domain name
from the child process to the parent process. But, those are used to
set/get NIS domainname, not DNS domainname. So, I think it's better to
pass it as bootfile information in doDhcp() is passed.

(Patch from Masahiro Matsuya <mmatsuya@redhat.com>)
---
loader2/net.c | 47 ++++++++++++++++++++++++++++++++++-------------
1 files changed, 34 insertions(+), 13 deletions(-)

diff --git a/loader2/net.c b/loader2/net.c
index 6580e3f..91082d1 100644
--- a/loader2/net.c
+++ b/loader2/net.c
@@ -1546,7 +1546,7 @@ int doDhcp(struct networkDeviceConfig *dev) {
pid_t pid;
key_t key;
int mturet;
- int culvert[2];
+ int culvert[2], domainp[2];
char buf[PATH_MAX];

/* clear existing IP addresses */
@@ -1613,7 +1613,11 @@ int doDhcp(struct networkDeviceConfig *dev) {
strncpy(pumpdev->device, dev->dev.device, IF_NAMESIZE);

if (pipe(culvert) == -1) {
- logMessage(ERROR, "%s: pipe(): %s", __func__, strerror(errno));
+ logMessage(ERROR, "%s: culvert pipe(): %s", __func__, strerror(errno));
+ return 1;
+ }
+ if (pipe(domainp) == -1) {
+ logMessage(ERROR, "%s: domainp pipe(): %s", __func__, strerror(errno));
return 1;
}

@@ -1621,6 +1625,7 @@ int doDhcp(struct networkDeviceConfig *dev) {
pid = fork();
if (pid == 0) {
close(culvert[0]);
+ close(domainp[0]);

if (pumpdev->set & PUMP_INTFINFO_HAS_MTU) {
mturet = nl_set_device_mtu((char *) pumpdev->device, pumpdev->mtu);
@@ -1667,10 +1672,11 @@ int doDhcp(struct networkDeviceConfig *dev) {

if (pumpdev->set & PUMP_NETINFO_HAS_DOMAIN) {
if (pumpdev->domain) {
- if (setdomainname(pumpdev->domain,
- strlen(pumpdev->domain)) == -1) {
- logMessage(ERROR, "failed to set domain name in %s: %s",
- __func__, strerror(errno));
+ if (write(domainp[1], pumpdev->domain,
+ strlen(pumpdev->domain) + 1) == -1) {
+ logMessage(ERROR, "failed to send domain name to parent "
+ "in %s: %s", __func__,
+ strerror(errno));
}
}
}
@@ -1687,11 +1693,13 @@ int doDhcp(struct networkDeviceConfig *dev) {
}

close(culvert[1]);
+ close(domainp[1]);
exit(0);
} else if (pid == -1) {
logMessage(CRITICAL, "dhcp client failed to start");
} else {
close(culvert[1]);
+ close(domainp[1]);

if (waitpid(pid, &status, 0) == -1) {
logMessage(ERROR, "waitpid() failure in %s", __func__);
@@ -1743,20 +1751,32 @@ int doDhcp(struct networkDeviceConfig *dev) {
}

if (dev->dev.set & PUMP_NETINFO_HAS_DOMAIN) {
+ memset(&buf, '', sizeof(buf));
if (dev->dev.domain) {
free(dev->dev.domain);
dev->dev.domain = NULL;
}

- memset(namebuf, '', HOST_NAME_MAX);
+ while ((sz = read(domainp[0], &buf, sizeof(buf))) > 0) {
+ if (dev->dev.domain == NULL) {
+ dev->dev.domain = calloc(sizeof(char), sz + 1);
+ if (dev->dev.domain == NULL) {
+ logMessage(ERROR, "unable to read domain name");
+ break;
+ }

- if (getdomainname(namebuf, HOST_NAME_MAX) == -1) {
- logMessage(ERROR, "unable to get domain name %s: %s",
- __func__, strerror(errno));
- }
+ dev->dev.domain = strncpy(dev->dev.domain, buf, sz);
+ } else {
+ dev->dev.domain = realloc(dev->dev.domain,
+ strlen(dev->dev.domain) +
+ sz + 1);
+ if (dev->dev.domain == NULL) {
+ logMessage(ERROR, "unable to read domain name");
+ break;
+ }

- if (namebuf != NULL) {
- dev->dev.domain = strdup(namebuf);
+ dev->dev.domain = strncat(dev->dev.domain, buf, sz);
+ }
}
}

@@ -1789,6 +1809,7 @@ int doDhcp(struct networkDeviceConfig *dev) {
}

close(culvert[0]);
+ close(domainp[0]);

if (shmdt(pumpdev) == -1) {
logMessage(ERROR, "%s: shmdt() pumpdev: %s", __func__,
--
1.7.2.1

_______________________________________________
Anaconda-devel-list mailing list
Anaconda-devel-list@redhat.com
https://www.redhat.com/mailman/listinfo/anaconda-devel-list

08-07-2010 05:45 AM

Support long 'option domain-name' values in loader (#578110)
 
From: David Cantrell <dcantrell@redhat.com>

During anaconda installation, resolv.conf is not updated with the proper
domain name in the "search" field if the domain name is too long. Eg,

/etc/dhcpd.conf
---------------------
option domain-name stl.kewr1.s.vonagenetworks.net
stl.kewr1.m.vonagenetworks.net vonagenetworks.net vonage.net vonage.com";
---------------------

This happens only during the install process ONLY; that the system
correctly generates resolv.conf once installed.

This occured by the limitation of setdomainname() and getdomainame() in
doDhcp(). setdomainame() and getdomainname() cannot use with the string
exceeding a length of 64 bytes.

In doDhcp(), a child process is created to get the information from DHCP
with libdhcp. The child process executes setdomainname() with the domain
information collected from DHCP. That's what they configured with
"option domain-name". If it exceeds a length of 64 bytes,
setdomainname() fails and the following error message is outputed.

failed to set domain name in doDhcp: Invalid argument

On the other hand, the parent process waits the child process to exit.
And then, it tries to get the domain information with getdomainname().
But, it should get empty string because setdomainname() failed by the
child process. As the result, nothing is set to 'search' in resolv.conf.

setdomainanme() and getdomainname() are used to pass the domain name
from the child process to the parent process. But, those are used to
set/get NIS domainname, not DNS domainname. So, I think it's better to
pass it as bootfile information in doDhcp() is passed.

(Patch from Masahiro Matsuya <mmatsuya@redhat.com>)
---
loader2/net.c | 47 ++++++++++++++++++++++++++++++++++-------------
1 files changed, 34 insertions(+), 13 deletions(-)

diff --git a/loader2/net.c b/loader2/net.c
index 6580e3f..91082d1 100644
--- a/loader2/net.c
+++ b/loader2/net.c
@@ -1546,7 +1546,7 @@ int doDhcp(struct networkDeviceConfig *dev) {
pid_t pid;
key_t key;
int mturet;
- int culvert[2];
+ int culvert[2], domainp[2];
char buf[PATH_MAX];

/* clear existing IP addresses */
@@ -1613,7 +1613,11 @@ int doDhcp(struct networkDeviceConfig *dev) {
strncpy(pumpdev->device, dev->dev.device, IF_NAMESIZE);

if (pipe(culvert) == -1) {
- logMessage(ERROR, "%s: pipe(): %s", __func__, strerror(errno));
+ logMessage(ERROR, "%s: culvert pipe(): %s", __func__, strerror(errno));
+ return 1;
+ }
+ if (pipe(domainp) == -1) {
+ logMessage(ERROR, "%s: domainp pipe(): %s", __func__, strerror(errno));
return 1;
}

@@ -1621,6 +1625,7 @@ int doDhcp(struct networkDeviceConfig *dev) {
pid = fork();
if (pid == 0) {
close(culvert[0]);
+ close(domainp[0]);

if (pumpdev->set & PUMP_INTFINFO_HAS_MTU) {
mturet = nl_set_device_mtu((char *) pumpdev->device, pumpdev->mtu);
@@ -1667,10 +1672,11 @@ int doDhcp(struct networkDeviceConfig *dev) {

if (pumpdev->set & PUMP_NETINFO_HAS_DOMAIN) {
if (pumpdev->domain) {
- if (setdomainname(pumpdev->domain,
- strlen(pumpdev->domain)) == -1) {
- logMessage(ERROR, "failed to set domain name in %s: %s",
- __func__, strerror(errno));
+ if (write(domainp[1], pumpdev->domain,
+ strlen(pumpdev->domain) + 1) == -1) {
+ logMessage(ERROR, "failed to send domain name to parent "
+ "in %s: %s", __func__,
+ strerror(errno));
}
}
}
@@ -1687,11 +1693,13 @@ int doDhcp(struct networkDeviceConfig *dev) {
}

close(culvert[1]);
+ close(domainp[1]);
exit(0);
} else if (pid == -1) {
logMessage(CRITICAL, "dhcp client failed to start");
} else {
close(culvert[1]);
+ close(domainp[1]);

if (waitpid(pid, &status, 0) == -1) {
logMessage(ERROR, "waitpid() failure in %s", __func__);
@@ -1743,20 +1751,32 @@ int doDhcp(struct networkDeviceConfig *dev) {
}

if (dev->dev.set & PUMP_NETINFO_HAS_DOMAIN) {
+ memset(&buf, '', sizeof(buf));
if (dev->dev.domain) {
free(dev->dev.domain);
dev->dev.domain = NULL;
}

- memset(namebuf, '', HOST_NAME_MAX);
+ while ((sz = read(domainp[0], &buf, sizeof(buf))) > 0) {
+ if (dev->dev.domain == NULL) {
+ dev->dev.domain = calloc(sizeof(char), sz + 1);
+ if (dev->dev.domain == NULL) {
+ logMessage(ERROR, "unable to read domain name");
+ break;
+ }

- if (getdomainname(namebuf, HOST_NAME_MAX) == -1) {
- logMessage(ERROR, "unable to get domain name %s: %s",
- __func__, strerror(errno));
- }
+ dev->dev.domain = strncpy(dev->dev.domain, buf, sz);
+ } else {
+ dev->dev.domain = realloc(dev->dev.domain,
+ strlen(dev->dev.domain) +
+ sz + 1);
+ if (dev->dev.domain == NULL) {
+ logMessage(ERROR, "unable to read domain name");
+ break;
+ }

- if (namebuf != NULL) {
- dev->dev.domain = strdup(namebuf);
+ dev->dev.domain = strncat(dev->dev.domain, buf, sz);
+ }
}
}

@@ -1789,6 +1809,7 @@ int doDhcp(struct networkDeviceConfig *dev) {
}

close(culvert[0]);
+ close(domainp[0]);

if (shmdt(pumpdev) == -1) {
logMessage(ERROR, "%s: shmdt() pumpdev: %s", __func__,
--
1.7.2.1

_______________________________________________
Anaconda-devel-list mailing list
Anaconda-devel-list@redhat.com
https://www.redhat.com/mailman/listinfo/anaconda-devel-list

08-07-2010 05:45 AM

Support long 'option domain-name' values in loader (#578110)
 
From: David Cantrell <dcantrell@redhat.com>

During anaconda installation, resolv.conf is not updated with the proper
domain name in the "search" field if the domain name is too long. Eg,

/etc/dhcpd.conf
---------------------
option domain-name stl.kewr1.s.vonagenetworks.net
stl.kewr1.m.vonagenetworks.net vonagenetworks.net vonage.net vonage.com";
---------------------

This happens only during the install process ONLY; that the system
correctly generates resolv.conf once installed.

This occured by the limitation of setdomainname() and getdomainame() in
doDhcp(). setdomainame() and getdomainname() cannot use with the string
exceeding a length of 64 bytes.

In doDhcp(), a child process is created to get the information from DHCP
with libdhcp. The child process executes setdomainname() with the domain
information collected from DHCP. That's what they configured with
"option domain-name". If it exceeds a length of 64 bytes,
setdomainname() fails and the following error message is outputed.

failed to set domain name in doDhcp: Invalid argument

On the other hand, the parent process waits the child process to exit.
And then, it tries to get the domain information with getdomainname().
But, it should get empty string because setdomainname() failed by the
child process. As the result, nothing is set to 'search' in resolv.conf.

setdomainanme() and getdomainname() are used to pass the domain name
from the child process to the parent process. But, those are used to
set/get NIS domainname, not DNS domainname. So, I think it's better to
pass it as bootfile information in doDhcp() is passed.

(Patch from Masahiro Matsuya <mmatsuya@redhat.com>)
---
loader2/net.c | 47 ++++++++++++++++++++++++++++++++++-------------
1 files changed, 34 insertions(+), 13 deletions(-)

diff --git a/loader2/net.c b/loader2/net.c
index 6580e3f..91082d1 100644
--- a/loader2/net.c
+++ b/loader2/net.c
@@ -1546,7 +1546,7 @@ int doDhcp(struct networkDeviceConfig *dev) {
pid_t pid;
key_t key;
int mturet;
- int culvert[2];
+ int culvert[2], domainp[2];
char buf[PATH_MAX];

/* clear existing IP addresses */
@@ -1613,7 +1613,11 @@ int doDhcp(struct networkDeviceConfig *dev) {
strncpy(pumpdev->device, dev->dev.device, IF_NAMESIZE);

if (pipe(culvert) == -1) {
- logMessage(ERROR, "%s: pipe(): %s", __func__, strerror(errno));
+ logMessage(ERROR, "%s: culvert pipe(): %s", __func__, strerror(errno));
+ return 1;
+ }
+ if (pipe(domainp) == -1) {
+ logMessage(ERROR, "%s: domainp pipe(): %s", __func__, strerror(errno));
return 1;
}

@@ -1621,6 +1625,7 @@ int doDhcp(struct networkDeviceConfig *dev) {
pid = fork();
if (pid == 0) {
close(culvert[0]);
+ close(domainp[0]);

if (pumpdev->set & PUMP_INTFINFO_HAS_MTU) {
mturet = nl_set_device_mtu((char *) pumpdev->device, pumpdev->mtu);
@@ -1667,10 +1672,11 @@ int doDhcp(struct networkDeviceConfig *dev) {

if (pumpdev->set & PUMP_NETINFO_HAS_DOMAIN) {
if (pumpdev->domain) {
- if (setdomainname(pumpdev->domain,
- strlen(pumpdev->domain)) == -1) {
- logMessage(ERROR, "failed to set domain name in %s: %s",
- __func__, strerror(errno));
+ if (write(domainp[1], pumpdev->domain,
+ strlen(pumpdev->domain) + 1) == -1) {
+ logMessage(ERROR, "failed to send domain name to parent "
+ "in %s: %s", __func__,
+ strerror(errno));
}
}
}
@@ -1687,11 +1693,13 @@ int doDhcp(struct networkDeviceConfig *dev) {
}

close(culvert[1]);
+ close(domainp[1]);
exit(0);
} else if (pid == -1) {
logMessage(CRITICAL, "dhcp client failed to start");
} else {
close(culvert[1]);
+ close(domainp[1]);

if (waitpid(pid, &status, 0) == -1) {
logMessage(ERROR, "waitpid() failure in %s", __func__);
@@ -1743,20 +1751,32 @@ int doDhcp(struct networkDeviceConfig *dev) {
}

if (dev->dev.set & PUMP_NETINFO_HAS_DOMAIN) {
+ memset(&buf, '', sizeof(buf));
if (dev->dev.domain) {
free(dev->dev.domain);
dev->dev.domain = NULL;
}

- memset(namebuf, '', HOST_NAME_MAX);
+ while ((sz = read(domainp[0], &buf, sizeof(buf))) > 0) {
+ if (dev->dev.domain == NULL) {
+ dev->dev.domain = calloc(sizeof(char), sz + 1);
+ if (dev->dev.domain == NULL) {
+ logMessage(ERROR, "unable to read domain name");
+ break;
+ }

- if (getdomainname(namebuf, HOST_NAME_MAX) == -1) {
- logMessage(ERROR, "unable to get domain name %s: %s",
- __func__, strerror(errno));
- }
+ dev->dev.domain = strncpy(dev->dev.domain, buf, sz);
+ } else {
+ dev->dev.domain = realloc(dev->dev.domain,
+ strlen(dev->dev.domain) +
+ sz + 1);
+ if (dev->dev.domain == NULL) {
+ logMessage(ERROR, "unable to read domain name");
+ break;
+ }

- if (namebuf != NULL) {
- dev->dev.domain = strdup(namebuf);
+ dev->dev.domain = strncat(dev->dev.domain, buf, sz);
+ }
}
}

@@ -1789,6 +1809,7 @@ int doDhcp(struct networkDeviceConfig *dev) {
}

close(culvert[0]);
+ close(domainp[0]);

if (shmdt(pumpdev) == -1) {
logMessage(ERROR, "%s: shmdt() pumpdev: %s", __func__,
--
1.7.2.1

_______________________________________________
Anaconda-devel-list mailing list
Anaconda-devel-list@redhat.com
https://www.redhat.com/mailman/listinfo/anaconda-devel-list

"Brian C. Lane" 08-09-2010 05:52 PM

Support long 'option domain-name' values in loader (#578110)
 
-----BEGIN PGP SIGNED MESSAGE-----
Hash: SHA1

On 08/06/2010 10:45 PM, dcantrell@redhat.com wrote:
> From: David Cantrell <dcantrell@redhat.com>
>
> During anaconda installation, resolv.conf is not updated with the proper
> domain name in the "search" field if the domain name is too long. Eg,
>
> /etc/dhcpd.conf
> ---------------------
> option domain-name stl.kewr1.s.vonagenetworks.net
> stl.kewr1.m.vonagenetworks.net vonagenetworks.net vonage.net vonage.com";
> ---------------------

Ack

- --
Brian C. Lane <bcl@redhat.com>
Red Hat / Port Orchard, WA
-----BEGIN PGP SIGNATURE-----
Version: GnuPG v2.0.14 (GNU/Linux)
Comment: Remember Lexington Green!

iQEVAwUBTGBASRF+jBaO/jp/AQLoFwf/exTR9eY1fL72Urg2vzsxVCSCl0Tt7hju
+Il/FDqRsfJkUzWGLQkoT+uYru1T6BMgEuWdWDPuQGODU7B4me9ld7 7rayK8wf7S
6ZH9mtFXGAgGMz7I9cbbDp47J/XmIZQVkKcFkX4NL5pnb9BIb66sm9QMOzddpE0p
c0hSLuFnyBNbpBFdKqp/9YWLbFWLOFDqL2N8vhzIwzfMFA7dqJmxgL+zz90S3HZk
D22+mas99/3GH6LikInmuC+SuvEHrRnOj439EHo5u51LHa1PWFPemepJF0X3 Ejvd
Hsw4DdQZnirm5D6ZBXmWNHe77DO9MyrRlCW3/OeafbZ3yBsi04sudA==
=tksG
-----END PGP SIGNATURE-----

_______________________________________________
Anaconda-devel-list mailing list
Anaconda-devel-list@redhat.com
https://www.redhat.com/mailman/listinfo/anaconda-devel-list


All times are GMT. The time now is 08:05 AM.

VBulletin, Copyright ©2000 - 2014, Jelsoft Enterprises Ltd.
Content Relevant URLs by vBSEO ©2007, Crawlability, Inc.