~ubuntu-branches/ubuntu/raring/autofs5/raring

« back to all changes in this revision

Viewing changes to modules/replicated.c

  • Committer: Bazaar Package Importer
  • Author(s): Jan Christoph Nordholz
  • Date: 2009-03-09 01:16:48 UTC
  • mfrom: (1.1.1 upstream)
  • Revision ID: james.westby@ubuntu.com-20090309011648-gjynlid883f0s2c4
Tags: 5.0.4-1
* New upstream version (5.0.4 plus patchset as of 2009/03/09).
  * Closes: #518728.
  * Remove dpatch 14, applied upstream.
* New dpatch 14 to avoid using the relatively young SOCK_CLOEXEC
  feature.
* Only invoke 'make clean' on clean target so ./configure isn't
  purged.
* Fix a typo in the postinst regarding the ucf conffile handling.
* Add 'set -e' to package maintenance scripts.
* Drop unnecessary /var/run/autofs from package.

Show diffs side-by-side

added added

removed removed

Lines of Context:
62
62
#ifndef MAX_ERR_BUF
63
63
#define MAX_ERR_BUF             512
64
64
#endif
 
65
 
65
66
#define MAX_IFC_BUF             2048
 
67
static int volatile ifc_buf_len = MAX_IFC_BUF;
 
68
static int volatile ifc_last_len = 0;
66
69
 
67
70
#define MASK_A  0x7F000000
68
71
#define MASK_B  0xBFFF0000
79
82
        int fd;
80
83
        unsigned int seed;
81
84
 
82
 
        fd = open("/dev/random", O_RDONLY);
 
85
        fd = open("/dev/urandom", O_RDONLY);
83
86
        if (fd < 0) {
84
87
                srandom(time(NULL));
85
88
                return;
95
98
        return;
96
99
}
97
100
 
 
101
static int alloc_ifreq(struct ifconf *ifc, int sock)
 
102
{
 
103
        int ret, lastlen = ifc_last_len, len = ifc_buf_len;
 
104
        char err_buf[MAX_ERR_BUF], *buf;
 
105
 
 
106
        while (1) {
 
107
                buf = malloc(len);
 
108
                if (!buf) {
 
109
                        char *estr = strerror_r(errno, err_buf, MAX_ERR_BUF);
 
110
                        logerr("malloc: %s", estr);
 
111
                        return 0;
 
112
                }
 
113
 
 
114
                ifc->ifc_len = len;
 
115
                ifc->ifc_req = (struct ifreq *) buf;
 
116
 
 
117
                ret = ioctl(sock, SIOCGIFCONF, ifc);
 
118
                if (ret == -1) {
 
119
                        char *estr = strerror_r(errno, err_buf, MAX_ERR_BUF);
 
120
                        logerr("ioctl: %s", estr);
 
121
                        free(buf);
 
122
                        return 0;
 
123
                }
 
124
 
 
125
                if (ifc->ifc_len <= lastlen)
 
126
                        break;
 
127
 
 
128
                lastlen = ifc->ifc_len;
 
129
                len += MAX_IFC_BUF;
 
130
                free(buf);
 
131
        }
 
132
 
 
133
        if (lastlen != ifc_last_len) {
 
134
                ifc_last_len = lastlen;
 
135
                ifc_buf_len = len;
 
136
        }
 
137
 
 
138
        return 1;
 
139
}
 
140
 
98
141
static unsigned int get_proximity(const char *host_addr, int addr_len)
99
142
{
100
143
        struct sockaddr_in *msk_addr, *if_addr;
122
165
                fcntl(sock, F_SETFD, cl_flags);
123
166
        }
124
167
 
125
 
        ifc.ifc_len = sizeof(buf);
126
 
        ifc.ifc_req = (struct ifreq *) buf;
127
 
        ret = ioctl(sock, SIOCGIFCONF, &ifc);
128
 
        if (ret == -1) {
129
 
                char *estr = strerror_r(errno, buf, MAX_ERR_BUF);
130
 
                logerr("ioctl: %s", estr);
 
168
        if (!alloc_ifreq(&ifc, sock)) {
131
169
                close(sock);
132
170
                return PROXIMITY_ERROR;
133
171
        }
138
176
        i = 0;
139
177
        ptr = (char *) &ifc.ifc_buf[0];
140
178
 
141
 
        while (ptr < buf + ifc.ifc_len) {
 
179
        while (ptr < (char *) ifc.ifc_req + ifc.ifc_len) {
142
180
                ifr = (struct ifreq *) ptr;
143
181
 
144
182
                switch (ifr->ifr_addr.sa_family) {
147
185
                        ret = memcmp(&if_addr->sin_addr, hst_addr, addr_len);
148
186
                        if (!ret) {
149
187
                                close(sock);
 
188
                                free(ifc.ifc_req);
150
189
                                return PROXIMITY_LOCAL;
151
190
                        }
152
191
                        break;
162
201
        i = 0;
163
202
        ptr = (char *) &ifc.ifc_buf[0];
164
203
 
165
 
        while (ptr < buf + ifc.ifc_len) {
 
204
        while (ptr < (char *) ifc.ifc_req + ifc.ifc_len) {
166
205
                ifr = (struct ifreq *) ptr;
167
206
 
168
207
                switch (ifr->ifr_addr.sa_family) {
178
217
                                char *estr = strerror_r(errno, buf, MAX_ERR_BUF);
179
218
                                logerr("ioctl: %s", estr);
180
219
                                close(sock);
 
220
                                free(ifc.ifc_req);
181
221
                                return PROXIMITY_ERROR;
182
222
                        }
183
223
 
186
226
 
187
227
                        if ((ia & mask) == (ha & mask)) {
188
228
                                close(sock);
 
229
                                free(ifc.ifc_req);
189
230
                                return PROXIMITY_SUBNET;
190
231
                        }
191
232
 
208
249
 
209
250
                        if ((ia & mask) == (ha & mask)) {
210
251
                                close(sock);
 
252
                                free(ifc.ifc_req);
211
253
                                return PROXIMITY_NET;
212
254
                        }
213
255
                        break;
221
263
        }
222
264
 
223
265
        close(sock);
 
266
        free(ifc.ifc_req);
224
267
 
225
268
        return PROXIMITY_OTHER;
226
269
}
227
270
 
228
 
static struct host *new_host(const char *name, const char *addr, unsigned int proximity, unsigned int weight)
 
271
static struct host *new_host(const char *name,
 
272
                             const char *addr, size_t addr_len,
 
273
                             unsigned int proximity, unsigned int weight)
229
274
{
230
275
        struct host *new;
231
276
        char *tmp1, *tmp2;
237
282
        if (!tmp1)
238
283
                return NULL;
239
284
 
240
 
        tmp2 = strdup(addr);
 
285
        tmp2 = malloc(addr_len);
241
286
        if (!tmp2) {
242
287
                free(tmp1);
243
288
                return NULL;
244
289
        }
 
290
        memcpy(tmp2, addr, addr_len);
245
291
 
246
292
        new = malloc(sizeof(struct host));
247
293
        if (!new) {
253
299
        memset(new, 0, sizeof(struct host));
254
300
 
255
301
        new->name = tmp1;
 
302
        new->addr_len = addr_len;
256
303
        new->addr = tmp2;
257
304
        new->proximity = proximity;
258
305
        new->weight = weight;
400
447
        double taken = 0;
401
448
        int status, count = 0;
402
449
 
 
450
        debug(logopt,
 
451
              "called for host %s proto %s version 0x%x",
 
452
              host->name, proto, version);
 
453
 
403
454
        memset(&parms, 0, sizeof(struct pmap));
404
455
 
405
456
        parms.pm_prog = NFS_PROGRAM;
424
475
                status = rpc_ping_proto(rpc_info);
425
476
                gettimeofday(&end, &tz);
426
477
                if (status) {
427
 
                        if (random_selection)
 
478
                        double reply;
 
479
                        if (random_selection) {
428
480
                                /* Random value between 0 and 1 */
429
 
                                taken += ((float) random())/((float) RAND_MAX+1);
430
 
                        else
431
 
                                taken += elapsed(start, end);;
 
481
                                reply = ((float) random())/((float) RAND_MAX+1);
 
482
                                debug(logopt,
 
483
                                      "nfs v4 random selection time: %f", reply);
 
484
                        } else {
 
485
                                reply = elapsed(start, end);
 
486
                                debug(logopt, "nfs v4 rpc ping time: %f", reply);
 
487
                        }
 
488
                        taken += reply;
432
489
                        count++;
433
490
                        supported = NFS4_SUPPORTED;
434
491
                }
437
494
v3_ver:
438
495
        if (!have_port_opt) {
439
496
                status = rpc_portmap_getclient(pm_info,
440
 
                                 host->name, proto, RPC_CLOSE_DEFAULT);
 
497
                                host->name, host->addr, host->addr_len,
 
498
                                proto, RPC_CLOSE_DEFAULT);
441
499
                if (!status)
442
500
                        goto done_ver;
443
501
        }
465
523
                status = rpc_ping_proto(rpc_info);
466
524
                gettimeofday(&end, &tz);
467
525
                if (status) {
468
 
                        if (random_selection)
 
526
                        double reply;
 
527
                        if (random_selection) {
469
528
                                /* Random value between 0 and 1 */
470
 
                                taken += ((float) random())/((float) RAND_MAX+1);
471
 
                        else
472
 
                                taken += elapsed(start, end);;
 
529
                                reply = ((float) random())/((float) RAND_MAX+1);
 
530
                                debug(logopt,
 
531
                                      "nfs v3 random selection time: %f", reply);
 
532
                        } else {
 
533
                                reply = elapsed(start, end);
 
534
                                debug(logopt, "nfs v3 rpc ping time: %f", reply);
 
535
                        }
 
536
                        taken += reply;
473
537
                        count++;
474
538
                        supported |= NFS3_SUPPORTED;
475
539
                }
499
563
                status = rpc_ping_proto(rpc_info);
500
564
                gettimeofday(&end, &tz);
501
565
                if (status) {
502
 
                        if (random_selection)
 
566
                        double reply;
 
567
                        if (random_selection) {
503
568
                                /* Random value between 0 and 1 */
504
 
                                taken += ((float) random())/((float) RAND_MAX+1);
505
 
                        else
506
 
                                taken += elapsed(start, end);;
 
569
                                reply = ((float) random())/((float) RAND_MAX+1);
 
570
                                debug(logopt,
 
571
                                      "nfs v2 random selection time: %f", reply);
 
572
                        } else {
 
573
                                reply = elapsed(start, end);;
 
574
                                debug(logopt, "nfs v2 rpc ping time: %f", reply);
 
575
                        }
 
576
                        taken += reply;
507
577
                        count++;
508
578
                        supported |= NFS2_SUPPORTED;
509
579
                }
528
598
                /* Allow for user bias */
529
599
                if (host->weight)
530
600
                        host->cost *= (host->weight + 1);
 
601
 
 
602
                debug(logopt, "host %s cost %ld weight %d",
 
603
                      host->name, host->cost, host->weight);
531
604
        }
532
605
 
533
606
        return supported;
547
620
 
548
621
        if (host->proximity == PROXIMITY_NET)
549
622
                timeout = RPC_TIMEOUT * 2;
550
 
        else if (host->proximity == PROXIMITY_NET)
 
623
        else if (host->proximity == PROXIMITY_OTHER)
551
624
                timeout = RPC_TIMEOUT * 8;
552
625
 
553
626
        rpc_info.host = host->name;
 
627
        rpc_info.addr = host->addr;
 
628
        rpc_info.addr_len = host->addr_len;
554
629
        rpc_info.program = NFS_PROGRAM;
555
630
        rpc_info.timeout.tv_sec = timeout;
556
631
        rpc_info.close_option = RPC_CLOSE_DEFAULT;
596
671
        time_t timeout = RPC_TIMEOUT;
597
672
        int status;
598
673
 
 
674
        debug(logopt,
 
675
              "called with host %s version 0x%x", host->name, version);
 
676
 
599
677
        memset(&pm_info, 0, sizeof(struct conn_info));
600
678
        memset(&rpc_info, 0, sizeof(struct conn_info));
601
679
        memset(&parms, 0, sizeof(struct pmap));
602
680
 
603
681
        if (host->proximity == PROXIMITY_NET)
604
682
                timeout = RPC_TIMEOUT * 2;
605
 
        else if (host->proximity == PROXIMITY_NET)
 
683
        else if (host->proximity == PROXIMITY_OTHER)
606
684
                timeout = RPC_TIMEOUT * 8;
607
685
 
608
686
        rpc_info.host = host->name;
 
687
        rpc_info.addr = host->addr;
 
688
        rpc_info.addr_len = host->addr_len;
609
689
        rpc_info.program = NFS_PROGRAM;
610
690
        rpc_info.timeout.tv_sec = timeout;
611
691
        rpc_info.close_option = RPC_CLOSE_DEFAULT;
652
732
                        return 0;
653
733
        } else {
654
734
                int ret = rpc_portmap_getclient(&pm_info,
655
 
                                 host->name, proto, RPC_CLOSE_DEFAULT);
 
735
                                host->name, host->addr, host->addr_len,
 
736
                                proto, RPC_CLOSE_DEFAULT);
656
737
                if (!ret)
657
738
                        return 0;
658
739
 
671
752
                status = rpc_ping_proto(&rpc_info);
672
753
                gettimeofday(&end, &tz);
673
754
                if (status) {
674
 
                        if (random_selection)
 
755
                        if (random_selection) {
675
756
                                /* Random value between 0 and 1 */
676
757
                                taken = ((float) random())/((float) RAND_MAX+1);
677
 
                        else
 
758
                                debug(logopt, "random selection time %f", taken);
 
759
                        } else {
678
760
                                taken = elapsed(start, end);
 
761
                                debug(logopt, "rpc ping time %f", taken);
 
762
                        }
679
763
                }
680
764
        }
681
765
done:
695
779
                if (host->weight)
696
780
                        host->cost *= (host->weight + 1);
697
781
 
 
782
                debug(logopt, "cost %ld weight %d", host->cost, host->weight);
 
783
 
698
784
                return 1;
699
785
        }
700
786
 
758
844
                this = next;
759
845
        }
760
846
 
 
847
        /*
 
848
         * The list of hosts that aren't proximity local may now
 
849
         * be empty if we haven't been able probe any so we need
 
850
         * to check again for a list containing only proximity
 
851
         * local hosts.
 
852
         */
 
853
        if (!first)
 
854
                return 1;
 
855
 
761
856
        last = this;
762
857
 
763
858
        /* Select NFS version of highest number of closest servers */
792
887
        max_udp_count = mmax(v4_udp_count, v3_udp_count, v2_udp_count);
793
888
        max_count = max(max_tcp_count, max_udp_count);
794
889
 
795
 
        if (max_count == v4_tcp_count)
 
890
        if (max_count == v4_tcp_count) {
796
891
                selected_version = NFS4_TCP_SUPPORTED;
797
 
        else if (max_count == v3_tcp_count)
 
892
                debug(logopt,
 
893
                      "selected subset of hosts that support NFS4 over TCP");
 
894
        } else if (max_count == v3_tcp_count) {
798
895
                selected_version = NFS3_TCP_SUPPORTED;
799
 
        else if (max_count == v2_tcp_count)
 
896
                debug(logopt,
 
897
                      "selected subset of hosts that support NFS3 over TCP");
 
898
        } else if (max_count == v2_tcp_count) {
800
899
                selected_version = NFS2_TCP_SUPPORTED;
801
 
        else if (max_count == v4_udp_count)
 
900
                debug(logopt,
 
901
                      "selected subset of hosts that support NFS2 over TCP");
 
902
        } else if (max_count == v4_udp_count) {
802
903
                selected_version = NFS4_UDP_SUPPORTED;
803
 
        else if (max_count == v3_udp_count)
 
904
                debug(logopt,
 
905
                      "selected subset of hosts that support NFS4 over UDP");
 
906
        } else if (max_count == v3_udp_count) {
804
907
                selected_version = NFS3_UDP_SUPPORTED;
805
 
        else if (max_count == v2_udp_count)
 
908
                debug(logopt,
 
909
                      "selected subset of hosts that support NFS3 over UDP");
 
910
        } else if (max_count == v2_udp_count) {
806
911
                selected_version = NFS2_UDP_SUPPORTED;
 
912
                debug(logopt,
 
913
                      "selected subset of hosts that support NFS2 over UDP");
 
914
        }
807
915
 
808
916
        /* Add local and hosts with selected version to new list */
809
917
        this = *list;
868
976
                if (prx == PROXIMITY_ERROR)
869
977
                        return 0;
870
978
 
871
 
                if (!(new = new_host(host, thost, prx, weight)))
 
979
                if (!(new = new_host(host, thost, sizeof(saddr.sin_addr), prx, weight)))
872
980
                        return 0;
873
981
 
874
982
                if (!add_host(list, new))
891
999
        }
892
1000
 
893
1001
        for (haddr = phe->h_addr_list; *haddr; haddr++) {
 
1002
                struct in_addr tt;
 
1003
 
894
1004
                prx = get_proximity(*haddr, phe->h_length);
895
1005
                if (prx == PROXIMITY_ERROR)
896
1006
                        return 0;
897
1007
 
898
 
                if (!(new = new_host(host, *haddr, prx, weight)))
 
1008
                memcpy(&tt, *haddr, sizeof(struct in_addr));
 
1009
                if (!(new = new_host(host, *haddr, phe->h_length, prx, weight)))
899
1010
                        return 0;
900
1011
 
901
1012
                if (!add_host(list, new)) {