section id="vs1.27-linux2.4.25-manual-patch"
rcsinfo="$Header: /home/radek/cvs/unix-book/unix.xml,v 1.7 2009-03-07 03:52:40 radek Exp $"
Následující příklad je spíše než ukázkou překladu jádra ukázkou řešení problému při záplatování. Vlastně jsem prováděl celé záplatování zbytečně neb jsem vycházel z mylného předpokladu že nový patch vyřeší můj „problém“. Problém s nefungováním příkazu hostname pro nastavení jména počítače ve virtuálním serveru. Jak jsem posléze zjistil toto se nastavuje v hostitelském serveru v konfiguračním souboru virtuálního stroje. Dále tedy následuje uvedený, „zbytečný“ postup.
Protože jsem nebyl spokojený s předchozím jádrem, rozhodl jsem se připravit si jádro s poslední stabilní záplatou vserveru vs1.27. Postupoval jsem následovně.
Stáhl jsem si poslední záplatu a utility.
# wget http://www.13thfloor.at/vserver/s_release/v1.27/patch-2.4.25-vs1.27.diff.bz2 # wget http://www.13thfloor.at/vserver/s_release/v1.27/util-vserver-0.29.3.tar.bz2
Záplaty jsem aplikoval na zdroje jádra.
# cd /usr/src/linux # bzcat /home/radek/work/vserver/patch-2.4.25-vs1.27.diff.bz2 \ | patch -p1 | tee patch.log
Celý průběh záplatování jsem si nechal zapsat do souboru patch.log
aby jej mohl podrobně prozkoumat. Záplatování s v několika kouscích (hunk) nepovedlo, tak se podíváme na neúspěchy.
# grep FAILED patch.log
Hunk #1 FAILED at 807.
Hunk #2 FAILED at 1088.
2 out of 2 hunks FAILED -- saving rejects to file arch/ppc64/kernel/misc.S.rej
Hunk #1 FAILED at 29.
1 out of 1 hunk FAILED -- saving rejects to file include/net/ip.h.rej
Hunk #2 FAILED at 168.
1 out of 2 hunks FAILED -- saving rejects to file include/net/route.h.rej
Hunk #6 FAILED at 557.
1 out of 7 hunks FAILED -- saving rejects to file net/ipv4/udp.c.rej
Nezbylo mi než se zahloubat do kódu a aplikovat neúspěšné kousky ručně.
Začal jsem odmítnutým kódem v souboru include/net/ip.h.rej
. Tato část je nejjednodušší.
*************** *** 29,34 **** #include <linux/netdevice.h> #include <linux/inetdevice.h> #include <linux/in_route.h> #include <net/route.h> #include <net/arp.h> --- 29,35 ---- #include <linux/netdevice.h> #include <linux/inetdevice.h> #include <linux/in_route.h> + #include <linux/vcontext.h> #include <net/route.h> #include <net/arp.h>
Tady byla oprava triviální. Za řádku
#include <linux/in_route.h>
jsem vsunul potřebnou řádku
#include <linux/vcontext.h>
Poté jsem pokračoval souborem include/net/route.h.rej
. Tady je neúspěšný kód již delší.
*************** *** 167,172 **** static inline int ip_route_connect(struct rtable **rp, u32 dst, u32 src, u32 tos, int oif) { int err; err = ip_route_output(rp, dst, src, tos, oif); if (err || (dst && src)) return err; --- 168,211 ---- static inline int ip_route_connect(struct rtable **rp, u32 dst, u32 src, u32 tos, int oif) { int err; + struct iproot_info *ip_info = current->ip_info; + if (ip_info != NULL) { + __u32 ipv4root = ip_info->ipv4[0]; + if (ipv4root != 0) { + int n = ip_info->nbipv4; + if (src == 0) { + if (n > 1) { + u32 foundsrc; + int i; + err = ip_route_output(rp, dst, src, tos, oif); + if (err) return err; + foundsrc = (*rp)->rt_src; + ip_rt_put(*rp); + for (i=0; i<n; i++){ + u32 mask = ip_info->mask[i]; + u32 ipv4 = ip_info->ipv4[i]; + u32 netipv4 = ipv4 & mask; + if ((foundsrc & mask) == netipv4) { + src = ipv4; + break; + } + } + } + if (src == 0) + src = dst == 0x0100007f + ? 0x0100007f: ipv4root; + } else { + int i; + for (i=0; i<n; i++) { + if (ip_info->ipv4[i] == src) break; + } + if (i == n) + return -EPERM; + } + if (dst == 0x0100007f && !vx_check(0, VX_ADMIN)) + dst = ipv4root; + } + } err = ip_route_output(rp, dst, src, tos, oif); if (err || (dst && src)) return err;
Po ruční opravě vypadá rozdíl takto
@@ -156,6 +157,45 @@ .dport = dport } } }; int err; + struct iproot_info *ip_info = current->ip_info; + if (ip_info != NULL) { + __u32 ipv4root = ip_info->ipv4[0]; + if (ipv4root != 0) { + int n = ip_info->nbipv4; + if (src == 0) { + if (n > 1) { + u32 foundsrc; + int i; + err = ip_route_output_flow(rp, &fl, sk, 0); + if (err) return err; + foundsrc = (*rp)->rt_src; + ip_rt_put(*rp); + for (i=0; i<n; i++){ + u32 mask = ip_info->mask[i]; + u32 ipv4 = ip_info->ipv4[i]; + u32 netipv4 = ipv4 & mask; + if ((foundsrc & mask) == netipv4) { + src = ipv4; + break; + } + } + } + if (src == 0) + src = dst == 0x0100007f + ? 0x0100007f: ipv4root; + } else { + int i; + for (i=0; i<n; i++) { + if (ip_info->ipv4[i] == src) break; + } + if (i == n) + return -EPERM; + } + if (dst == 0x0100007f && !vx_check(0, VX_ADMIN)) + dst = ipv4root; + } + } +
Poslední kousek který neuspěl je include/net/ipv4/udp.c.rej
*************** *** 540,545 **** rt = (struct rtable*)sk_dst_check(sk, 0); if (rt == NULL) { err = ip_route_output(&rt, daddr, ufh.saddr, tos, ipc.oif); if (err) goto out; --- 557,574 ---- rt = (struct rtable*)sk_dst_check(sk, 0); if (rt == NULL) { + struct iproot_info *ip_info = current->ip_info; + + if (ip_info != NULL) { + __u32 ipv4root = ip_info->ipv4[0]; + if (ipv4root) { + if (daddr == 0x0100007f && + !vx_check(0, VX_ADMIN)) + daddr = ipv4root; + if (ufh.saddr == 0) + ufh.saddr = ipv4root; + } + } err = ip_route_output(&rt, daddr, ufh.saddr, tos, ipc.oif); if (err) goto out;
Záplatu jsem vsunul za řádku 618
.dport = dport } } };
@@ -599,6 +616,19 @@ .uli_u = { .ports = { .sport = sk->sport, .dport = dport } } }; + struct iproot_info *ip_info = current->ip_info; + + if (ip_info != NULL) { + __u32 ipv4root = ip_info->ipv4[0]; + if (ipv4root) { + if (daddr == 0x0100007f && + !vx_check(0, VX_ADMIN)) + daddr = ipv4root; + if (fl.nl_u.ip4_u.saddr == 0) + fl.nl_u.ip4_u.saddr = ipv4root; + } + } + err = ip_route_output_flow(&rt, &fl, sk, !(msg->msg_flags&MSG_DONTWAIT)); if (err) goto out;
Záplatováním souboru arch/ppc64/kernel/misc.S
jsem se nazabýval, neb jádro použiji jen na platformě Intel.
Uschování ozáplatovaných zdrojů
# cd /usr/src # mv kernel-source-2.4.25 kernel-source-2.4.25-vs1.27 # cd kernel-source-2.4.25-vs1.27 # make mrproper # cd .. # tar cf kernel-source-2.4.25-vs1.27.tar kernel-source-2.4.25-vs1.27 # bzip2 --best kernel-source-2.4.25-vs1.27.tar.bz2
Vlastní překlad jádra
# /root/sbin/build-kernel yoda 6