Bug#455743: closed by Morten Werner Forsbring [EMAIL PROTECTED] (Bug#455743: fixed in cfengine2 2.2.5-1)
Hi Chun, thanks a lot for your diagnosis of this issue. I appreciate it. Your patch seems ok, and the most important thing is to have your test. I have applied this patch to the sources and we'll hope it works out. M Chun Tian (binghe) wrote: Hi, Werner Mark Sorry to reply this mail late. I just find time to do this job, and to test cfengine, I must set up a new test environment and bootstrap a new cfengine config, that's not easy. By checking Mark's svn commit (r524): http://svn.iu.hio.no/viewvc/trunk/src/nameinfo.c?root=Cfengine-2r1=498r2=524pathrev=524 Now I'm quite sure there's a new bug invoked which caused CFengine can only detect one interface's address. In function GetInterfaceInfo (nameinfo.c), Mark added a first_address var which been set to true at start: int fd,len,i,j,first_address = true; There's no other assignment to set this variable to true again but a chance to set it false: if (first_address) { first_address = false; strcpy(ip,inet_ntoa(sin-sin_addr)); snprintf(name,CF_MAXVARSIZE-1,ipv4[%s],CanonifyName(ifp-ifr_name)); AddMacroValue(CONTEXTID,name,ip); So this IF block can only run exactly ONCE, which caused global.ipv4[ethX] got only one interface's address, which depends the interfaces order on linux. For most cases, eth0 appear before eth1, so global.ipv4[eth0] is good but global.ipv4[eth1] cannot expand to any address because it didn't exist in cfengine's nameinfo list. For a quick fix, I attach a new patch which can be put into Debian package's debian/patches directory, or merge into cfengine trunk. I test it, and works for me. Please review it. Thanks, Chun Tian (binghe) Chun Tian (binghe) [EMAIL PROTECTED] writes: I have this editfiles class definition: editfiles: { /etc/default/snmpd ReplaceFirst ^SNMPDOPTS.*$ With SNMPDOPTS='-Lsd -Lf /dev/null - u snmp -I -smux -p /var/run/snmpd.pid ${global.ipv4[eth0]}:1185 $ {global.ipv4[eth1]}' } I found one of ${global.ipv4[eth0]} and ${global.ipv4[eth1]} cannot be expanded into right value, which depends my interfaces order on server. I haven't had time to test this myself, but this worked as intended before we applied the patch from upstream? - Werner -- Mark Burgess Web: http://www.iu.hio.no/~mark Tlf: +47 22453272 -- To UNSUBSCRIBE, email to [EMAIL PROTECTED] with a subject of unsubscribe. Trouble? Contact [EMAIL PROTECTED]
Bug#455743: global.ipv4 cannot handle multiple addresses on same interface
I have made a change (Committed revision 524 which hopefully addresses this. Could someone test it please? M Morten Werner Forsbring wrote: Hi! Here is another bugreport from one of our Debian users. Chun Tian (binghe) [EMAIL PROTECTED] writes: I have servers with multiple addresses on the same interface eth1: 2: eth1: BROADCAST,MULTICAST,UP,1 mtu 1500 qdisc pfifo_fast qlen 1000 link/ether 00:1c:c4:a9:73:74 brd ff:ff:ff:ff:ff:ff inet 172.17.2.6/20 brd 172.17.15.255 scope global eth1 inet 192.168.0.24/24 brd 192.168.0.255 scope global eth1:0 inet 172.17.2.18/20 brd 172.17.15.255 scope global secondary eth1 inet 172.17.2.15/20 brd 172.17.15.255 scope global secondary eth1 inet6 fe80::21c:c4ff:fea9:7374/64 scope link valid_lft forever preferred_lft forever cfengine's ${global.ipv4[eth1]} returns 172.17.2.15, which is the last address on eth1 (not included eth1:0). I need it return the first address of eth1 (172.17.2.6), because other addresses are dynamic and under control of the Linux-HA/Heartbeat. I think cfengine cannot handle this correctly now, could DD fix this or forward it to the author? Thanks. Chun TIAN (binghe) I have similar output on servers running Linux Virtual Server [1] and HP ServiceGuard [2], e.g. like this for LVS: [EMAIL PROTECTED] / # ip addr ls ... 12: bond1: BROADCAST,MULTICAST,MASTER,UP mtu 1500 qdisc noqueue link/ether 00:11:43:de:74:c1 brd ff:ff:ff:ff:ff:ff inet x.y.z.47/25 brd x.y.z.127 scope global bond1 inet x.y.z.20/32 scope global bond1 inet x.y.z.50/32 scope global bond1 [EMAIL PROTECTED] / # So this is a more or less common setup on Linux cluster-solutions. I've tried a bit with cfengine 2.2.3, and it's the last IP listed by 'ip addr ls' that cfengine store in the global.ipv4[ethX]-variable: sue:~# ip addr ls ... 3: eth1: BROADCAST,MULTICAST,UP,LOWER_UP mtu 1500 qdisc pfifo_fast qlen 1000 link/ether 00:13:ce:a4:e3:e4 brd ff:ff:ff:ff:ff:ff inet 192.168.0.101/24 brd 192.168.0.255 scope global eth1 inet 192.168.0.199/24 brd 192.168.0.255 scope global secondary eth1 inet6 fe80::213:ceff:fea4:e3e4/64 scope link valid_lft forever preferred_lft forever sue:~# cfagent -d3 | grep ipv4 ... 590 : ipv4_2[eth1]=192.168 1895 : ipv4[eth1]=192.168.0.199 2100 : ipv4_1[eth1]=192 4049 : ipv4_3[eth1]=192.168.0 sue:~# I agree with Chun Tian that the first IP-address listed by 'ip addr ls' should be the one picked up for global.ipvx[ethX], at least with these kinds of Linux cluster-solutions in mind. What do you think? Marry christmas! :) - Werner [1] http://www.linuxvirtualserver.org/ [2] http://h20219.www2.hp.com/enterprise/cache/6468-0-0-0-121.html ___ Bug-cfengine mailing list [EMAIL PROTECTED] https://cfengine.org/mailman/listinfo/bug-cfengine -- Mark Burgess Web: http://www.iu.hio.no/~mark Tlf: +47 22453272 -- To UNSUBSCRIBE, email to [EMAIL PROTECTED] with a subject of unsubscribe. Trouble? Contact [EMAIL PROTECTED]
Bug#448139: cfagent crashes with a segmentation fault when 31+ arguments are supplied
Patch applied to correct the problem as reported. Iain Patterson wrote: Quoth Mark Burgess, This is probably true, but the case cited in the mail is not a limitation of cfengine but the argument getopt code in the operating system concerned. It is normal that Unix limits to 31 args, and internally cfengine does the same for consistency. I tried compiling the getopt example code at http://www.gnu.org/software/libc/manual/html_node/Getopt.html and didn't get a segfault with 31 arguments on Linux x86_64. cfagent 2.2.1 on the same OS did indeed segfault with 31 arguments. The conclusion is that, while I agree there should be no segfault, I am not sure what I can do about it, since there is no code in cfengine that lead to this fault. It seems the bug is in the code which preparses arguments. Line 253 of cfagent.c (at least in version 2.2.1) describes the case where a script is called with the shell magic #!/bla/cfengine -v -f and this ends up being passed in argv[1] as a single string. cfagent then parses this into an array of size CF_MAXARGS, which is 31 as you state. The attached quick and very dirty patch does the preparse in two stages, first allocating a dynamic buffer big enough for the arguments and then filling it in as before. An alternative option (if you excuse the pun) would be to use popt, which has the function poptParseArgvString(). The downside is that this is an added dependency. --- cfengine-2.2.1/src/cf.defs.h.orig 2007-11-30 08:24:22.122979592 + +++ cfengine-2.2.1/src/cf.defs.h 2007-11-30 08:24:26.734643977 + @@ -287,7 +287,6 @@ #define CF_NONCELEN (CF_BUFSIZE/16) #define CF_MAXLINKSIZE 256 #define CF_MAXLINKLEVEL 4 -#define CF_MAXARGS 31 #define CF_MAXFARGS 8 #define CF_MAX_IP_LEN 64 /* numerical ip length */ #define CF_PROCCOLS 16 --- cfengine-2.2.1/src/cfagent.c.orig 2007-11-30 08:24:04.652251054 + +++ cfengine-2.2.1/src/cfagent.c 2007-11-30 08:47:17.382186413 + @@ -198,8 +198,8 @@ void Initialize(int argc,char *argv[]) -{ char *sp, *cfargv[CF_MAXARGS]; - int i, cfargc, seed; +{ char *sp, **cfargv; + int i, j, cfargc, seed; struct stat statbuf; unsigned char s[16]; char ebuff[CF_EXPANDSIZE]; @@ -235,9 +235,40 @@ /* Everything ends up inside a single argument! Here's the fix */ cfargc = 1; -cfargv[0]=cfagent; -for (i = 1; i argc; i++) +/* Pass 1: Find how many arguments there are. */ +for (i = 1, j = 1; i argc; i++) + { + sp = argv[i]; + + while (*sp != '\0') + { + while (*sp == ' ' *sp != '\0') /* Skip to arg */ + { + sp++; + } + + cfargc++; + + while (*sp != ' ' *sp != '\0') /* Skip to white space */ + { + sp++; + } + } + } + +/* Allocate memory for cfargv. */ +cfargv = (char **) malloc(sizeof(char *) * cfargc + 1); +if (! cfargv) + { + /* I guess CfLog(cferror, ...) isn't available yet. */ + fprintf(stderr,cfagent: Out of memory parsing arguments\n); + exit(111); + } + +/* Pass 2: Parse the arguments. */ +cfargv[0] = cfagent; +for (i = 1, j = 1; i argc; i++) { sp = argv[i]; @@ -252,7 +283,7 @@ sp++; } - cfargv[cfargc++] = sp; + cfargv[j++] = sp; while (*sp != ' ' *sp != '\0') /* Skip to white space */ { @@ -260,6 +291,7 @@ } } } +cfargv[j] = 0; VDEFAULTBINSERVER.name = ; @@ -315,6 +347,7 @@ seed = ElfHash(s); srand48((long)seed); CheckOpts(cfargc,cfargv); + free(cfargv); AddInstallable(no_default_route); CfenginePort(); ___ Bug-cfengine mailing list [EMAIL PROTECTED] https://cfengine.org/mailman/listinfo/bug-cfengine -- Mark Burgess Professor of Network and System Administration Oslo University College ~~ Work: +47 22453272Email: [EMAIL PROTECTED] Fax : +47 22453205WWW : http://www.iu.hio.no/~mark ~~ -- To UNSUBSCRIBE, email to [EMAIL PROTECTED] with a subject of unsubscribe. Trouble? Contact [EMAIL PROTECTED]
Bug#448139: cfagent crashes with a segmentation fault when 31+ arguments are supplied
THank you for this analysis. The original bug message did not contain enough context to see this interaction. M Iain Patterson wrote: Quoth Mark Burgess, This is probably true, but the case cited in the mail is not a limitation of cfengine but the argument getopt code in the operating system concerned. It is normal that Unix limits to 31 args, and internally cfengine does the same for consistency. I tried compiling the getopt example code at http://www.gnu.org/software/libc/manual/html_node/Getopt.html and didn't get a segfault with 31 arguments on Linux x86_64. cfagent 2.2.1 on the same OS did indeed segfault with 31 arguments. The conclusion is that, while I agree there should be no segfault, I am not sure what I can do about it, since there is no code in cfengine that lead to this fault. It seems the bug is in the code which preparses arguments. Line 253 of cfagent.c (at least in version 2.2.1) describes the case where a script is called with the shell magic #!/bla/cfengine -v -f and this ends up being passed in argv[1] as a single string. cfagent then parses this into an array of size CF_MAXARGS, which is 31 as you state. The attached quick and very dirty patch does the preparse in two stages, first allocating a dynamic buffer big enough for the arguments and then filling it in as before. An alternative option (if you excuse the pun) would be to use popt, which has the function poptParseArgvString(). The downside is that this is an added dependency. --- cfengine-2.2.1/src/cf.defs.h.orig 2007-11-30 08:24:22.122979592 + +++ cfengine-2.2.1/src/cf.defs.h 2007-11-30 08:24:26.734643977 + @@ -287,7 +287,6 @@ #define CF_NONCELEN (CF_BUFSIZE/16) #define CF_MAXLINKSIZE 256 #define CF_MAXLINKLEVEL 4 -#define CF_MAXARGS 31 #define CF_MAXFARGS 8 #define CF_MAX_IP_LEN 64 /* numerical ip length */ #define CF_PROCCOLS 16 --- cfengine-2.2.1/src/cfagent.c.orig 2007-11-30 08:24:04.652251054 + +++ cfengine-2.2.1/src/cfagent.c 2007-11-30 08:47:17.382186413 + @@ -198,8 +198,8 @@ void Initialize(int argc,char *argv[]) -{ char *sp, *cfargv[CF_MAXARGS]; - int i, cfargc, seed; +{ char *sp, **cfargv; + int i, j, cfargc, seed; struct stat statbuf; unsigned char s[16]; char ebuff[CF_EXPANDSIZE]; @@ -235,9 +235,40 @@ /* Everything ends up inside a single argument! Here's the fix */ cfargc = 1; -cfargv[0]=cfagent; -for (i = 1; i argc; i++) +/* Pass 1: Find how many arguments there are. */ +for (i = 1, j = 1; i argc; i++) + { + sp = argv[i]; + + while (*sp != '\0') + { + while (*sp == ' ' *sp != '\0') /* Skip to arg */ + { + sp++; + } + + cfargc++; + + while (*sp != ' ' *sp != '\0') /* Skip to white space */ + { + sp++; + } + } + } + +/* Allocate memory for cfargv. */ +cfargv = (char **) malloc(sizeof(char *) * cfargc + 1); +if (! cfargv) + { + /* I guess CfLog(cferror, ...) isn't available yet. */ + fprintf(stderr,cfagent: Out of memory parsing arguments\n); + exit(111); + } + +/* Pass 2: Parse the arguments. */ +cfargv[0] = cfagent; +for (i = 1, j = 1; i argc; i++) { sp = argv[i]; @@ -252,7 +283,7 @@ sp++; } - cfargv[cfargc++] = sp; + cfargv[j++] = sp; while (*sp != ' ' *sp != '\0') /* Skip to white space */ { @@ -260,6 +291,7 @@ } } } +cfargv[j] = 0; VDEFAULTBINSERVER.name = ; @@ -315,6 +347,7 @@ seed = ElfHash(s); srand48((long)seed); CheckOpts(cfargc,cfargv); + free(cfargv); AddInstallable(no_default_route); CfenginePort(); ___ Bug-cfengine mailing list [EMAIL PROTECTED] https://cfengine.org/mailman/listinfo/bug-cfengine -- Mark Burgess Professor of Network and System Administration Oslo University College ~~ Work: +47 22453272Email: [EMAIL PROTECTED] Fax : +47 22453205WWW : http://www.iu.hio.no/~mark ~~ -- To UNSUBSCRIBE, email to [EMAIL PROTECTED] with a subject of unsubscribe. Trouble? Contact [EMAIL PROTECTED]
Bug#448139: cfagent crashes with a segmentation fault when 31+ arguments are supplied
Pardon me for saying so, but one recalls the story of the patient visiting the doctor: Doctor, doctor, it hurts when I do this. To which the answer is Then don't do that! Can anyone provide an example of a case in which one need to approach this number of arguments? M Morten Werner Forsbring wrote: tags 448139 upstream thanks Hi, here is a bugreport from one of our Debian users. I've confirmed this bug on cfengine version 2.2.2. - Werner Cyril Bouthors [EMAIL PROTECTED] writes: Package: cfengine2 Version: 2.1.22-2 Severity: critical cfagent crashes with a segmentation fault when 31+ arguments are supplied It can easily be reproduced with: $ cfagent -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a Segmentation fault $ The typical use case of 31+ arguments is with multiple -Dfoo arguments, like: $ cfagent --no-lock -x -H -Dmyfai_munin_node -Dmyfai_eth0 -Dmyfai_libnssdb_passwd -Dmyfai_libnssdb_shadow -Dmyfai_resolv_conf -Dmyfai_etc_hosts -Dmyfai_lilo -Dmyfai_firewall_web -Dmyfai_apt_preferences -Dmyfai_apt_list_changes -Dmyfai_apt_sources_list -Dmyfai_forward_root_emails -Dmyfai_exim_smarthost -Dmyfai_cyb_dotfiles -Dmyfai_ssh_key_root -Dmyfai_apt_cache_limit -Dmyfai_init_d_oshosting_nfs_mounts -Dmyfai_init_d_oshosting_links -Dmyfai_init_d_oshosting_update_config_web -Dmyfai_init_d_oshosting_update_nssdb_passwd -Dmyfai_init_d_oshosting_update_nssdb_shadow -Dmyfai_nfsmount_sessions -Dmyfai_nfsmount_myfai -Dmyfai_enable_rsyncd -Dmyfai_oshosting_nfs_mounts -Dmyfai_web_suexec_romain -Dmyfai_web_oshosting_phpkill -Dmyfai_bind9_forwarders -Dmyfai_static_route_to_mail_by_lbgw -Dmyfai_static_route_to_ns_by_lbgw -Dmyfai_enable_spamd -Dmyfai_spamd_flock -Dmyfai_spamd_disable_bayes -Dmyfai_spamd_enable_network -Dmyfai_cron_d_myfai_ntp -f /usr/local/myfai/etc/cfengine/generic.c ! onf Segmentation fault $ I'm almost sure that this command used to be working on previous versions of cfengine. ___ Bug-cfengine mailing list [EMAIL PROTECTED] https://cfengine.org/mailman/listinfo/bug-cfengine -- Mark Burgess Professor of Network and System Administration Oslo University College ~~ Work: +47 22453272Email: [EMAIL PROTECTED] Fax : +47 22453205WWW : http://www.iu.hio.no/~mark ~~ -- To UNSUBSCRIBE, email to [EMAIL PROTECTED] with a subject of unsubscribe. Trouble? Contact [EMAIL PROTECTED]
Bug#448139: cfagent crashes with a segmentation fault when 31+ arguments are supplied
Morten Werner Forsbring wrote: Mark Burgess [EMAIL PROTECTED] writes: Pardon me for saying so, but one recalls the story of the patient visiting the doctor: Doctor, doctor, it hurts when I do this. To which the answer is Then don't do that! I don't agree with your comparison here, but ok. In my opinion a program shouldn't _segfault_ just if it's called with more than 31 arguments. This is probably true, but the case cited in the mail is not a limitation of cfengine but the argument getopt code in the operating system concerned. It is normal that Unix limits to 31 args, and internally cfengine does the same for consistency. The conclusion is that, while I agree there should be no segfault, I am not sure what I can do about it, since there is no code in cfengine that lead to this fault. As you see: (gdb) run -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a Starting program: /home/mark/LapTop/GNU-cfengine/trunk/src/cfagent -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a Failed to read a valid object file image from memory. [Thread debugging using libthread_db enabled] [New Thread -1212573488 (LWP 12444)] Program received signal SIGSEGV, Segmentation fault. [Switching to Thread -1212573488 (LWP 12444)] 0xb7c77b34 in _getopt_internal_r () from /lib/libc.so.6 (gdb) back #0 0xb7c77b34 in _getopt_internal_r () from /lib/libc.so.6 #1 0xb7c78721 in _getopt_internal () from /lib/libc.so.6 #2 0xb7c788d1 in getopt_long () from /lib/libc.so.6 #3 0x0804b4cf in CheckOpts (argc=32, argv=0xbf9926f0) at cfagent.c:1693 #4 0x0804ec3b in Initialize (argc=32, argv=0xbf9928a4) at cfagent.c:379 #5 0x0804edad in main (argc=Cannot access memory at address 0x1f -- To UNSUBSCRIBE, email to [EMAIL PROTECTED] with a subject of unsubscribe. Trouble? Contact [EMAIL PROTECTED]
Bug#232512: Copying the same file twice fails
Morten Werner Olsen wrote: Hi! I am trying to clean a bit in the open bugreports against cfengine2 in the Debian BTS[1]. This mail is about an old bug that noone has commented on yet, but as I believe still is an issue with 2.1.20. This is bug #232512 [2]: I have a cfengine2 configuration, where occassionally (on purpose!) during a single run of cfexecd, a destination file gets copied from two different locations on the server. For example: /foo/file dest=/foo/bar server=host backup=true /foo2/file dest=/foo/bar server=host backup=true This results, in /foo: /foo/bar (identical to /foo/file) /foo/bar.cfsaved (identical to whatever there was originally) /foo/bar.cfnew (identical to /foo2/file) Obviously, the latter copy has failed. During the next run, the first copy line copies nothing since /foo/bar is already identical to /foo/file and thus the directory now looks like: /foo/bar (identical to /foo2/file) /foo/bar.cfsaved (identical to /foo/bar) Then we go back to square one and repeat this all over again. The culprit is lines 1509-1512 in image.c: if (IsItemIn(VREPOSLIST,backup)) { return true; } This exits the whole CopyReg() and leaves .cfnew in place if AND ONLY IF, the same file (i.e. /foo/bar) was already in backup repository. Thus, the quick hack is to change either of the two lines to NOT create backups. However, it is, in my opinion, the wrong solution. Correct behaviour should be to either create a backup of a backup (troublesome), skip backup of a file already backed up (my choice) or at least print out a warning. The first one may be a little difficult to implement, but the second one is easy: change return true; to continue;. This would skip the remainder of the backup procedure and continue as if it had been backed up. I do not think any harm would come from this, since the *original* file was already backed up earlier and now we just skip backing up a file cfengine previously copied into place. The patch is untested (I only have production systems at hand at the moment), but should work. --- image.old.c 2004-02-13 11:45:28.0 +0200 +++ image.c 2004-02-13 11:45:57.0 +0200 @@ -1508,7 +1508,7 @@ if (IsItemIn(VREPOSLIST,backup)) { - return true; + continue; } /* Mainly important if there is a dir in the way */ After looking at the code, this is still an issue, right? So what do you think? The bugreport can be found at [2]. - Werner [1] http://bugs.debian.org/cgi-bin/pkgreport.cgi?pkg=cfengine2 [2] http://bugs.debian.org/cgi-bin/bugreport.cgi?bug=232512 ___ Bug-cfengine mailing list Bug-cfengine@cfengine.org http://cfengine.org/mailman/listinfo/bug-cfengine The proposed patch is not correct, since there is no loop to continue. However the analysis is okay -- I have patched the svn code to that the behaviour you suggest is honoured. (Previously the user was warned of this silly request - I believe that was okay, but now you get both a warning and the multiple copy honoured as suggested.) -- Mark Burgess Professor of Network and System Administration Oslo University College ~~ Work: +47 22453272Email: [EMAIL PROTECTED] Fax : +47 22453205WWW : http://www.iu.hio.no/~mark ~~ -- To UNSUBSCRIBE, email to [EMAIL PROTECTED] with a subject of unsubscribe. Trouble? Contact [EMAIL PROTECTED]