~ubuntu-branches/debian/sid/glusterfs/sid

« back to all changes in this revision

Viewing changes to xlators/cluster/afr/src/afr-self-heal-common.c

  • Committer: Package Import Robot
  • Author(s): Patrick Matthäi
  • Date: 2014-04-22 10:00:41 UTC
  • mfrom: (1.3.25)
  • Revision ID: package-import@ubuntu.com-20140422100041-6mur2ttyvb8zzpfq
Tags: 3.5.0-1
* New upstream release.
  - Rewrite patch 01-spelling-error.
  - Adjust lintian overrides.
  - Install new files.
  - The offical tarball is not properly generated, hack it around.
  - Add symlink from fusermount-glusterfs manpage to mount.glusterfs.
  - Move gsync-sync-gfid from /usr/share to /usr/lib.
  - Add benchmarking directory.
* Remove old versioned build dependencies and build depend on libglib2.0-dev.
* Add lintian override for possible-gpl-code-linked-with-openssl. It is the
  same false positive like with the gluster-server package.

Show diffs side-by-side

added added

removed removed

Lines of Context:
18
18
#include "afr-self-heal.h"
19
19
#include "pump.h"
20
20
 
 
21
#define ADD_FMT_STRING(msg, off, sh_str, status, print_log)                 \
 
22
        do {                                                                \
 
23
                if (AFR_SELF_HEAL_NOT_ATTEMPTED != status) {                \
 
24
                        off += snprintf (msg + off, sizeof (msg) - off,     \
 
25
                                         " "sh_str" self heal %s,",         \
 
26
                                         get_sh_completion_status (status));\
 
27
                        print_log = 1;                                      \
 
28
                }                                                           \
 
29
        } while (0)
 
30
 
 
31
#define ADD_FMT_STRING_SYNC(msg, off, sh_str, status, print_log)            \
 
32
        do {                                                                \
 
33
                if (AFR_SELF_HEAL_SYNC_BEGIN == status ||                   \
 
34
                    AFR_SELF_HEAL_FAILED == status)  {                      \
 
35
                        off += snprintf (msg + off, sizeof (msg) - off,     \
 
36
                                         " "sh_str" self heal %s,",         \
 
37
                                         get_sh_completion_status (status));\
 
38
                        print_log = 1;                                      \
 
39
                }                                                           \
 
40
        } while (0)
 
41
 
 
42
 
21
43
void
22
44
afr_sh_reset (call_frame_t *frame, xlator_t *this)
23
45
{
141
163
        GF_FREE (buf);
142
164
}
143
165
 
144
 
void
145
 
afr_sh_print_split_brain_log (int32_t *pending_matrix[], xlator_t *this,
146
 
                              const char *loc)
 
166
char*
 
167
afr_get_pending_matrix_str (int32_t *pending_matrix[], xlator_t *this)
147
168
{
148
169
        afr_private_t *  priv = this->private;
149
170
        char            *buf  = NULL;
173
194
                        + (child_count * child_count * pending_entry_strlen);
174
195
 
175
196
        buf = GF_CALLOC (1, 1 + strlen (msg) + string_length , gf_afr_mt_char);
176
 
        if (!buf) {
177
 
                buf = "";
 
197
        if (!buf)
178
198
                goto out;
179
 
        }
180
199
 
181
200
        ptr = buf;
182
201
        ptr += sprintf (ptr, "%s", msg);
192
211
        ptr += sprintf (ptr, "%s", matrix_end);
193
212
 
194
213
out:
 
214
        return buf;
 
215
}
 
216
 
 
217
void
 
218
afr_sh_print_split_brain_log (int32_t *pending_matrix[], xlator_t *this,
 
219
                              const char *loc)
 
220
{
 
221
        char *buf      = NULL;
 
222
        char *free_ptr = NULL;
 
223
 
 
224
        buf = afr_get_pending_matrix_str (pending_matrix, this);
 
225
        if (buf)
 
226
                free_ptr = buf;
 
227
        else
 
228
                buf = "";
 
229
 
 
230
 
195
231
        gf_log (this->name, GF_LOG_ERROR, "Unable to self-heal contents of '%s'"
196
232
                " (possible split-brain). Please delete the file from all but "
197
233
                "the preferred subvolume.%s", loc, buf);
198
 
        if (buf)
199
 
                GF_FREE (buf);
 
234
        GF_FREE (free_ptr);
200
235
        return;
201
236
}
202
237
 
480
515
{
481
516
        int i               = 0;
482
517
        int biggest_witness = -1;
 
518
        int biggest_witness_idx = -1;
 
519
        int biggest_witness_cnt = -1;
483
520
 
484
521
        GF_ASSERT (witnesses);
485
522
        GF_ASSERT (characters);
489
526
                if (characters[i].type != AFR_NODE_FOOL)
490
527
                        continue;
491
528
 
492
 
                if (biggest_witness < witnesses[i])
 
529
                if (biggest_witness < witnesses[i]) {
493
530
                        biggest_witness = witnesses[i];
 
531
                        biggest_witness_idx = i;
 
532
                        biggest_witness_cnt = 1;
 
533
                        continue;
 
534
                }
 
535
 
 
536
                if (biggest_witness == witnesses[i])
 
537
                        biggest_witness_cnt++;
494
538
        }
495
 
        return biggest_witness;
 
539
 
 
540
        if (biggest_witness_cnt != 1)
 
541
                return -1;
 
542
 
 
543
        return biggest_witness_idx;
496
544
}
497
545
 
498
546
int
520
568
        return nsources;
521
569
}
522
570
 
 
571
 
 
572
int
 
573
afr_mark_fool_as_source_by_idx (int32_t *sources, int child_count, int idx)
 
574
{
 
575
        if (idx >= 0 && idx < child_count) {
 
576
                sources[idx] = 1;
 
577
                return 1;
 
578
        }
 
579
        return 0;
 
580
}
 
581
 
 
582
 
 
583
static int
 
584
afr_find_largest_file_size (struct iatt *bufs, int32_t *success_children,
 
585
                            int child_count)
 
586
{
 
587
        int idx = -1;
 
588
        int i = -1;
 
589
        int child = -1;
 
590
        uint64_t max_size = 0;
 
591
        uint64_t min_size = 0;
 
592
        int      num_children = 0;
 
593
 
 
594
        for (i = 0; i < child_count; i++) {
 
595
                if (success_children[i] == -1)
 
596
                        break;
 
597
 
 
598
                child = success_children[i];
 
599
                if (bufs[child].ia_size > max_size) {
 
600
                        max_size = bufs[child].ia_size;
 
601
                        idx = child;
 
602
                }
 
603
 
 
604
                if ((num_children == 0) || (bufs[child].ia_size < min_size)) {
 
605
                        min_size = bufs[child].ia_size;
 
606
                }
 
607
 
 
608
                num_children++;
 
609
        }
 
610
 
 
611
        /* If sizes are same for all of them, finding sources will have to
 
612
         * happen with pending changelog. So return -1
 
613
         */
 
614
        if ((num_children > 1) && (min_size == max_size))
 
615
                return -1;
 
616
        return idx;
 
617
}
 
618
 
 
619
 
 
620
static int
 
621
afr_find_newest_file (struct iatt *bufs, int32_t *success_children,
 
622
                      int child_count)
 
623
{
 
624
        int idx = -1;
 
625
        int i = -1;
 
626
        int child = -1;
 
627
        uint64_t max_ctime = 0;
 
628
 
 
629
        for (i = 0; i < child_count; i++) {
 
630
                if (success_children[i] == -1)
 
631
                        break;
 
632
 
 
633
                child = success_children[i];
 
634
                if (bufs[child].ia_ctime > max_ctime) {
 
635
                        max_ctime = bufs[child].ia_ctime;
 
636
                        idx = child;
 
637
                }
 
638
        }
 
639
 
 
640
        return idx;
 
641
}
 
642
 
 
643
 
523
644
static int
524
645
afr_mark_biggest_of_fools_as_source (int32_t *sources, int32_t **pending_matrix,
525
646
                                     afr_node_character *characters,
526
 
                                     int child_count)
 
647
                                     int32_t *success_children,
 
648
                                     int child_count, struct iatt *bufs)
527
649
{
528
650
        int32_t       biggest_witness = 0;
529
651
        int           nsources        = 0;
531
653
 
532
654
        GF_ASSERT (child_count > 0);
533
655
 
 
656
        biggest_witness = afr_find_largest_file_size (bufs, success_children,
 
657
                                                      child_count);
 
658
        if (biggest_witness != -1)
 
659
                goto found;
 
660
 
534
661
        witnesses = GF_CALLOC (child_count, sizeof (*witnesses),
535
662
                               gf_afr_mt_int32_t);
536
663
        if (NULL == witnesses) {
543
670
        biggest_witness = afr_find_biggest_witness_among_fools (witnesses,
544
671
                                                                characters,
545
672
                                                                child_count);
546
 
        nsources = afr_mark_fool_as_source_by_witness (sources, witnesses,
547
 
                                                       characters, child_count,
548
 
                                                       biggest_witness);
 
673
        if (biggest_witness != -1)
 
674
                goto found;
 
675
 
 
676
        biggest_witness = afr_find_newest_file (bufs, success_children,
 
677
                                                child_count);
 
678
 
 
679
found:
 
680
        nsources = afr_mark_fool_as_source_by_idx (sources, child_count,
 
681
                                                   biggest_witness);
549
682
out:
550
683
        GF_FREE (witnesses);
551
684
        return nsources;
923
1056
                nsources = afr_mark_biggest_of_fools_as_source (sources,
924
1057
                                                                pending_matrix,
925
1058
                                                                characters,
926
 
                                                                child_count);
 
1059
                                                                success_children,
 
1060
                                                                child_count, bufs);
927
1061
        }
928
1062
 
929
1063
out:
1060
1194
 
1061
1195
        afr_sh_reset (frame, this);
1062
1196
 
1063
 
        if (local->govinda_gOvinda) {
 
1197
        if (local->unhealable) {
1064
1198
                gf_log (this->name, GF_LOG_DEBUG,
1065
1199
                        "split brain found, aborting selfheal of %s",
1066
1200
                        local->loc.path);
1067
 
                sh->op_failed = 1;
1068
1201
        }
1069
1202
 
1070
 
        if (sh->op_failed) {
 
1203
        if (is_self_heal_failed (sh, AFR_CHECK_SPECIFIC)) {
1071
1204
                sh->completion_cbk (frame, this);
1072
1205
        } else {
1073
1206
                gf_log (this->name, GF_LOG_TRACE,
1299
1432
        if (ret) {
1300
1433
                gf_log (this->name, GF_LOG_ERROR, "impunge of %s failed, "
1301
1434
                        "reason: %s", local->loc.path, strerror (-ret));
1302
 
                sh->op_failed = 1;
 
1435
                afr_set_self_heal_status (sh, AFR_SELF_HEAL_FAILED);
1303
1436
        }
1304
1437
        afr_sh_missing_entries_finish (frame, this);
1305
1438
}
1314
1447
        local = frame->local;
1315
1448
        sh = &local->self_heal;
1316
1449
        if (op_ret < 0)
1317
 
                sh->op_failed = 1;
 
1450
                afr_set_self_heal_status (sh, AFR_SELF_HEAL_FAILED);
1318
1451
        afr_sh_missing_entries_finish (frame, this);
1319
1452
        return 0;
1320
1453
}
1338
1471
        if (!afr_valid_ia_type (type)) {
1339
1472
                gf_log (this->name, GF_LOG_ERROR,
1340
1473
                        "%s: unknown file type: 0%o", local->loc.path, type);
1341
 
                local->govinda_gOvinda = 1;
 
1474
                afr_set_local_for_unhealable (local);
1342
1475
                afr_sh_missing_entries_finish (frame, this);
1343
1476
                goto out;
1344
1477
        }
1371
1504
        loc = &local->loc;
1372
1505
 
1373
1506
        if (op_ret < 0) {
1374
 
                if (op_errno == EIO)
1375
 
                        local->govinda_gOvinda = 1;
 
1507
                if (op_errno == EIO) {
 
1508
                        afr_set_local_for_unhealable (local);
 
1509
                }
1376
1510
                // EIO can happen if finding the fresh parent dir failed
1377
1511
                goto out;
1378
1512
        }
1434
1568
        }
1435
1569
        return;
1436
1570
out:
1437
 
        sh->op_failed = 1;
 
1571
        afr_set_self_heal_status (sh, AFR_SELF_HEAL_FAILED);
1438
1572
        afr_sh_set_error (sh, op_errno);
1439
1573
        afr_sh_missing_entries_finish (frame, this);
1440
1574
        return;
1518
1652
                LOCK (&frame->lock);
1519
1653
                {
1520
1654
                        afr_sh_set_error (sh, EIO);
1521
 
                        sh->op_failed = 1;
 
1655
                        afr_set_self_heal_status (sh, AFR_SELF_HEAL_FAILED);
1522
1656
                }
1523
1657
                UNLOCK (&frame->lock);
1524
1658
        }
1600
1734
        sh       = &local->self_heal;
1601
1735
        priv     = this->private;
1602
1736
 
1603
 
        if (sh->op_failed) {
 
1737
        if (is_self_heal_failed (sh, AFR_CHECK_SPECIFIC)) {
1604
1738
                afr_sh_missing_entries_finish (frame, this);
1605
1739
        } else {
1606
1740
                if (afr_gfid_missing_count (this->name, sh->fresh_children,
1693
1827
                if (!purge_condition (local, priv, i))
1694
1828
                        continue;
1695
1829
                gf_log (this->name, GF_LOG_INFO, "purging the stale entry %s "
1696
 
                        "on %d", local->loc.path, i);
 
1830
                        "on %s", local->loc.path, priv->children[i]->name);
1697
1831
                afr_sh_call_entry_expunge_remove (frame, this,
1698
1832
                                                  (long) i, &sh->buf[i],
1699
1833
                                                  &sh->parentbufs[i],
1813
1947
                                               sh->child_errno,
1814
1948
                                               priv->child_count, ENOENT);
1815
1949
        if (fresh_child_enoents == fresh_parent_count) {
1816
 
                gf_log (this->name, GF_LOG_INFO, "Deleting stale file %s",
1817
 
                        local->loc.path);
1818
1950
                afr_sh_set_error (sh, ENOENT);
1819
 
                sh->op_failed = 1;
 
1951
                afr_set_self_heal_status (sh, AFR_SELF_HEAL_FAILED);
1820
1952
                afr_sh_purge_entry (frame, this);
1821
1953
        } else if (!afr_conflicting_iattrs (sh->buf, sh->fresh_children,
1822
1954
                                            priv->child_count, local->loc.path,
1830
1962
                afr_sh_purge_stale_entry (frame, this);
1831
1963
        } else {
1832
1964
                op_errno = EIO;
1833
 
                local->govinda_gOvinda = 1;
 
1965
                afr_set_local_for_unhealable (local);
1834
1966
                goto fail;
1835
1967
        }
1836
1968
 
1837
1969
        return;
1838
1970
 
1839
1971
fail:
1840
 
        sh->op_failed = 1;
 
1972
        afr_set_self_heal_status (sh, AFR_SELF_HEAL_FAILED);
1841
1973
        afr_sh_set_error (sh, op_errno);
1842
1974
        afr_sh_missing_entries_finish (frame, this);
1843
1975
        return;
1908
2040
 
1909
2041
out:
1910
2042
        afr_sh_set_error (sh, op_errno);
1911
 
        sh->op_failed = 1;
1912
 
        afr_sh_missing_entries_finish (frame, this);
 
2043
        afr_set_self_heal_status (sh, AFR_SELF_HEAL_FAILED);
 
2044
        afr_sh_missing_entries_finish (frame, this);
1913
2045
        return;
1914
2046
}
1915
2047
 
1998
2130
 
1999
2131
 
2000
2132
int
2001
 
afr_sh_post_nb_entrylk_conflicting_sh_cbk (call_frame_t *frame, xlator_t *this)
 
2133
afr_sh_post_nb_entrylk_missing_entry_sh_cbk (call_frame_t *frame,
 
2134
                                             xlator_t *this)
2002
2135
{
2003
2136
        afr_internal_lock_t *int_lock = NULL;
2004
2137
        afr_local_t         *local    = NULL;
2011
2144
        if (int_lock->lock_op_ret < 0) {
2012
2145
                gf_log (this->name, GF_LOG_INFO,
2013
2146
                        "Non blocking entrylks failed.");
2014
 
                sh->op_failed = -1;
 
2147
                afr_set_self_heal_status (sh, AFR_SELF_HEAL_FAILED);
2015
2148
                afr_sh_missing_entries_done (frame, this);
2016
2149
        } else {
2017
2150
 
2027
2160
}
2028
2161
 
2029
2162
int
2030
 
afr_sh_post_nb_entrylk_gfid_sh_cbk (call_frame_t *frame, xlator_t *this)
2031
 
{
2032
 
        afr_internal_lock_t *int_lock = NULL;
2033
 
        afr_local_t         *local    = NULL;
2034
 
        afr_self_heal_t     *sh       = NULL;
2035
 
 
2036
 
        local    = frame->local;
2037
 
        sh       = &local->self_heal;
2038
 
        int_lock = &local->internal_lock;
2039
 
 
2040
 
        if (int_lock->lock_op_ret < 0) {
2041
 
                gf_log (this->name, GF_LOG_INFO,
2042
 
                        "Non blocking entrylks failed.");
2043
 
                afr_sh_missing_entries_done (frame, this);
2044
 
        } else {
2045
 
                gf_log (this->name, GF_LOG_DEBUG,
2046
 
                        "Non blocking entrylks done. Proceeding to FOP");
2047
 
                afr_sh_common_lookup (frame, this, &local->loc,
2048
 
                                      afr_sh_missing_entries_lookup_done,
2049
 
                                      sh->sh_gfid_req, AFR_LOOKUP_FAIL_CONFLICTS|
2050
 
                                      AFR_LOOKUP_FAIL_MISSING_GFIDS,
2051
 
                                      NULL);
2052
 
        }
2053
 
 
2054
 
        return 0;
2055
 
}
2056
 
 
2057
 
int
2058
2163
afr_sh_entrylk (call_frame_t *frame, xlator_t *this, loc_t *loc,
2059
2164
                char *base_name, afr_lock_cbk_t lock_cbk)
2060
2165
{
2074
2179
        int_lock->lk_basename = base_name;
2075
2180
        int_lock->lk_loc      = loc;
2076
2181
        int_lock->lock_cbk    = lock_cbk;
 
2182
        int_lock->domain      = this->name;
2077
2183
 
2078
2184
        int_lock->lockee_count = 0;
2079
2185
        afr_init_entry_lockee (&int_lock->lockee[0], local, loc,
2116
2222
}
2117
2223
 
2118
2224
static int
2119
 
afr_self_heal_conflicting_entries (call_frame_t *frame, xlator_t *this)
2120
 
{
2121
 
        afr_self_heal_parent_entrylk (frame, this,
2122
 
                                      afr_sh_post_nb_entrylk_conflicting_sh_cbk);
2123
 
        return 0;
2124
 
}
2125
 
 
2126
 
static int
2127
 
afr_self_heal_gfids (call_frame_t *frame, xlator_t *this)
2128
 
{
2129
 
        afr_self_heal_parent_entrylk (frame, this,
2130
 
                                      afr_sh_post_nb_entrylk_gfid_sh_cbk);
2131
 
        return 0;
2132
 
}
2133
 
 
2134
 
afr_local_t *afr_local_copy (afr_local_t *l, xlator_t *this)
2135
 
{
2136
 
        afr_private_t *priv = NULL;
2137
 
        afr_local_t   *lc     = NULL;
 
2225
afr_self_heal_missing_entries (call_frame_t *frame, xlator_t *this)
 
2226
{
 
2227
        afr_local_t     *local = NULL;
2138
2228
        afr_self_heal_t *sh = NULL;
2139
 
        afr_self_heal_t *shc = NULL;
2140
 
        int              i   = 0;
 
2229
 
 
2230
        local = frame->local;
 
2231
        sh = &local->self_heal;
 
2232
 
 
2233
        sh->sh_type_in_action  = AFR_SELF_HEAL_GFID_OR_MISSING_ENTRY;
 
2234
 
 
2235
        afr_set_self_heal_status (sh, AFR_SELF_HEAL_STARTED);
 
2236
 
 
2237
        afr_self_heal_parent_entrylk (frame, this,
 
2238
                                      afr_sh_post_nb_entrylk_missing_entry_sh_cbk);
 
2239
        return 0;
 
2240
}
 
2241
 
 
2242
afr_local_t*
 
2243
afr_self_heal_local_init (afr_local_t *l, xlator_t *this)
 
2244
{
 
2245
        afr_private_t   *priv  = NULL;
 
2246
        afr_local_t     *lc    = NULL;
 
2247
        afr_self_heal_t *sh    = NULL;
 
2248
        afr_self_heal_t *shc   = NULL;
 
2249
        int             ret    = 0;
2141
2250
 
2142
2251
        priv = this->private;
2143
2252
 
2160
2269
        shc->forced_merge = sh->forced_merge;
2161
2270
        shc->background = sh->background;
2162
2271
        shc->type = sh->type;
 
2272
        shc->data_sh_info = "";
 
2273
        shc->metadata_sh_info =  "";
2163
2274
 
2164
2275
        uuid_copy (shc->sh_gfid_req, sh->sh_gfid_req);
2165
 
        if (l->loc.path)
2166
 
                loc_copy (&lc->loc, &l->loc);
 
2276
        if (l->loc.path) {
 
2277
                ret = loc_copy (&lc->loc, &l->loc);
 
2278
                if (ret < 0)
 
2279
                        goto out;
 
2280
        }
2167
2281
 
2168
2282
        lc->child_up  = memdup (l->child_up,
2169
2283
                                sizeof (*lc->child_up) * priv->child_count);
 
2284
        if (!lc->child_up) {
 
2285
                ret = -1;
 
2286
                goto out;
 
2287
        }
 
2288
 
2170
2289
        if (l->xattr_req)
2171
2290
                lc->xattr_req = dict_ref (l->xattr_req);
2172
2291
 
2174
2293
                lc->cont.lookup.inode = inode_ref (l->cont.lookup.inode);
2175
2294
        if (l->cont.lookup.xattr)
2176
2295
                lc->cont.lookup.xattr = dict_ref (l->cont.lookup.xattr);
2177
 
        if (l->internal_lock.inode_locked_nodes)
2178
 
                lc->internal_lock.inode_locked_nodes =
2179
 
                        memdup (l->internal_lock.inode_locked_nodes,
2180
 
                                sizeof (*lc->internal_lock.inode_locked_nodes) * priv->child_count);
2181
 
        else
2182
 
                lc->internal_lock.inode_locked_nodes =
2183
 
                        GF_CALLOC (sizeof (*l->internal_lock.inode_locked_nodes),
2184
 
                                   priv->child_count,
2185
 
                                   gf_afr_mt_char);
2186
 
 
2187
 
        if (l->internal_lock.locked_nodes)
2188
 
                lc->internal_lock.locked_nodes =
2189
 
                        memdup (l->internal_lock.locked_nodes,
2190
 
                                sizeof (*lc->internal_lock.locked_nodes) * priv->child_count);
2191
 
        else
2192
 
                lc->internal_lock.locked_nodes =
2193
 
                        GF_CALLOC (sizeof (*l->internal_lock.locked_nodes),
2194
 
                                   priv->child_count,
2195
 
                                   gf_afr_mt_char);
2196
 
 
2197
 
        for (i = 0; i < l->internal_lock.lockee_count; i++) {
2198
 
                loc_copy (&lc->internal_lock.lockee[i].loc,
2199
 
                          &l->internal_lock.lockee[i].loc);
2200
 
 
2201
 
                lc->internal_lock.lockee[i].locked_count =
2202
 
                        l->internal_lock.lockee[i].locked_count;
2203
 
 
2204
 
                if (l->internal_lock.lockee[i].basename)
2205
 
                        lc->internal_lock.lockee[i].basename =
2206
 
                                gf_strdup (l->internal_lock.lockee[i].basename);
2207
 
 
2208
 
                if (l->internal_lock.lockee[i].locked_nodes) {
2209
 
                        lc->internal_lock.lockee[i].locked_nodes =
2210
 
                                memdup (l->internal_lock.lockee[i].locked_nodes,
2211
 
                                        sizeof (*lc->internal_lock.lockee[i].locked_nodes) *
2212
 
                                        priv->child_count);
2213
 
                } else {
2214
 
                        lc->internal_lock.lockee[i].locked_nodes =
2215
 
                                GF_CALLOC (priv->child_count,
2216
 
                                           sizeof (*lc->internal_lock.lockee[i].locked_nodes),
2217
 
                                           gf_afr_mt_char);
2218
 
                }
2219
 
 
 
2296
 
 
2297
        lc->internal_lock.locked_nodes =
 
2298
                             GF_CALLOC (sizeof (*l->internal_lock.locked_nodes),
 
2299
                                        priv->child_count, gf_afr_mt_char);
 
2300
        if (!lc->internal_lock.locked_nodes) {
 
2301
                ret = -1;
 
2302
                goto out;
2220
2303
        }
2221
 
        lc->internal_lock.lockee_count = l->internal_lock.lockee_count;
2222
 
 
2223
 
        lc->internal_lock.inodelk_lock_count =
2224
 
                l->internal_lock.inodelk_lock_count;
2225
 
        lc->internal_lock.entrylk_lock_count =
2226
 
                l->internal_lock.entrylk_lock_count;
2227
 
 
 
2304
 
 
2305
        ret = afr_inodelk_init (&lc->internal_lock.inodelk[0],
 
2306
                                this->name, priv->child_count);
 
2307
        if (ret)
 
2308
                goto out;
2228
2309
 
2229
2310
out:
 
2311
        if (ret) {
 
2312
                afr_local_cleanup (lc, this);
 
2313
                lc = NULL;
 
2314
        }
2230
2315
        return lc;
2231
2316
}
2232
2317
 
2239
2324
        afr_local_t *     orig_frame_local = NULL;
2240
2325
        afr_self_heal_t * orig_frame_sh = NULL;
2241
2326
        char              sh_type_str[256] = {0,};
 
2327
        gf_loglevel_t     loglevel = 0;
2242
2328
 
2243
2329
        priv  = this->private;
2244
2330
        local = bgsh_frame->local;
2245
2331
        sh    = &local->self_heal;
2246
2332
 
2247
 
        if (local->govinda_gOvinda) {
 
2333
        if (local->unhealable) {
2248
2334
                afr_set_split_brain (this, sh->inode, SPB, SPB);
2249
 
                sh->op_failed = 1;
2250
2335
        }
2251
2336
 
2252
2337
        afr_self_heal_type_str_get (sh, sh_type_str,
2253
2338
                                    sizeof(sh_type_str));
2254
 
        if (sh->op_failed) {
2255
 
                gf_loglevel_t     loglevel = GF_LOG_ERROR;
2256
 
                if (priv->shd.iamshd)
2257
 
                        loglevel = GF_LOG_DEBUG;
2258
 
 
2259
 
                gf_log (this->name, loglevel, "background %s self-heal "
2260
 
                        "failed on %s", sh_type_str, local->loc.path);
2261
 
 
 
2339
        if (is_self_heal_failed (sh, AFR_CHECK_ALL) && !priv->shd.iamshd) {
 
2340
                loglevel = GF_LOG_ERROR;
 
2341
        } else if (!is_self_heal_failed (sh, AFR_CHECK_ALL)) {
 
2342
                loglevel = GF_LOG_INFO;
2262
2343
        } else {
2263
 
                gf_log (this->name, GF_LOG_DEBUG, "background %s self-heal "
2264
 
                        "completed on %s", sh_type_str, local->loc.path);
2265
 
 
 
2344
                loglevel = GF_LOG_DEBUG;
2266
2345
        }
2267
2346
 
 
2347
        afr_log_self_heal_completion_status (local, loglevel);
 
2348
 
2268
2349
        FRAME_SU_UNDO (bgsh_frame, afr_local_t);
2269
2350
 
2270
2351
        if (!sh->unwound && sh->unwind) {
2272
2353
                orig_frame_sh = &orig_frame_local->self_heal;
2273
2354
                orig_frame_sh->actual_sh_started = _gf_true;
2274
2355
                sh->unwind (sh->orig_frame, this, sh->op_ret, sh->op_errno,
2275
 
                            sh->op_failed);
 
2356
                            is_self_heal_failed (sh, AFR_CHECK_ALL));
2276
2357
        }
2277
2358
 
2278
2359
        if (sh->background) {
2321
2402
        afr_set_lk_owner (sh_frame, this, sh_frame->root);
2322
2403
        afr_set_low_priority (sh_frame);
2323
2404
 
2324
 
        sh_local        = afr_local_copy (local, this);
 
2405
        sh_local        = afr_self_heal_local_init (local, this);
2325
2406
        if (!sh_local)
2326
2407
                goto out;
2327
2408
        sh_frame->local = sh_local;
2386
2467
                sh->do_gfid_self_heal = _gf_false;
2387
2468
        }
2388
2469
 
 
2470
        sh->sh_type_in_action = AFR_SELF_HEAL_INVALID;
 
2471
 
2389
2472
        FRAME_SU_DO (sh_frame, afr_local_t);
2390
 
        if (sh->do_missing_entry_self_heal) {
2391
 
                afr_self_heal_conflicting_entries (sh_frame, this);
2392
 
        } else if (sh->do_gfid_self_heal) {
2393
 
                GF_ASSERT (!uuid_is_null (sh->sh_gfid_req));
2394
 
                afr_self_heal_gfids (sh_frame, this);
 
2473
        if (sh->do_missing_entry_self_heal || sh->do_gfid_self_heal) {
 
2474
                afr_self_heal_missing_entries (sh_frame, this);
2395
2475
        } else {
2396
2476
                loc = &sh_local->loc;
2397
2477
                if (uuid_is_null (loc->inode->gfid) && uuid_is_null (loc->gfid)) {
2598
2678
        GF_FREE (erase_xattr);
2599
2679
 
2600
2680
        if (ret < 0) {
2601
 
                sh->op_failed = _gf_true;
 
2681
                afr_set_self_heal_status (sh, AFR_SELF_HEAL_FAILED);
2602
2682
                finish (frame, this);
2603
2683
        }
2604
2684
 
2605
2685
        return 0;
2606
2686
}
 
2687
 
 
2688
void
 
2689
afr_set_self_heal_status(afr_self_heal_t *sh, afr_self_heal_status status)
 
2690
{
 
2691
        xlator_t                *this = NULL;
 
2692
        afr_sh_status_for_all_type *sh_status = &(sh->afr_all_sh_status);
 
2693
        afr_self_heal_type  sh_type_in_action = sh->sh_type_in_action;
 
2694
        this = THIS;
 
2695
 
 
2696
        if (!sh) {
 
2697
                gf_log_callingfn (this->name, GF_LOG_ERROR, "Null self heal"
 
2698
                                  "Structure");
 
2699
                goto out;
 
2700
        }
 
2701
 
 
2702
        switch (sh_type_in_action) {
 
2703
                case AFR_SELF_HEAL_GFID_OR_MISSING_ENTRY:
 
2704
                       sh_status->gfid_or_missing_entry_self_heal = status;
 
2705
                        break;
 
2706
                case AFR_SELF_HEAL_METADATA:
 
2707
                        sh_status->metadata_self_heal = status;
 
2708
                        break;
 
2709
                case AFR_SELF_HEAL_DATA:
 
2710
                        sh_status->data_self_heal = status;
 
2711
                        break;
 
2712
                case AFR_SELF_HEAL_ENTRY:
 
2713
                        sh_status->entry_self_heal = status;
 
2714
                        break;
 
2715
                case AFR_SELF_HEAL_INVALID:
 
2716
                        gf_log_callingfn (this->name, GF_LOG_ERROR, "Invalid"
 
2717
                                          "self heal type in action");
 
2718
                        break;
 
2719
        }
 
2720
out:
 
2721
        return;
 
2722
}
 
2723
 
 
2724
void
 
2725
afr_set_local_for_unhealable (afr_local_t *local)
 
2726
{
 
2727
        afr_self_heal_t  *sh = NULL;
 
2728
 
 
2729
        sh = &local->self_heal;
 
2730
 
 
2731
        local->unhealable = 1;
 
2732
        afr_set_self_heal_status (sh, AFR_SELF_HEAL_FAILED);
 
2733
}
 
2734
 
 
2735
int
 
2736
is_self_heal_failed (afr_self_heal_t *sh, afr_sh_fail_check_type type)
 
2737
{
 
2738
        afr_sh_status_for_all_type      sh_status = sh->afr_all_sh_status;
 
2739
        afr_self_heal_type   sh_type_in_action =  AFR_SELF_HEAL_INVALID;
 
2740
        afr_self_heal_status    status = AFR_SELF_HEAL_FAILED;
 
2741
        xlator_t                *this = NULL;
 
2742
        int                     sh_failed = 0;
 
2743
 
 
2744
        this = THIS;
 
2745
 
 
2746
        if (!sh) {
 
2747
                gf_log_callingfn (this->name, GF_LOG_ERROR, "Null self heal "
 
2748
                                  "structure");
 
2749
                sh_failed = 1;
 
2750
                goto out;
 
2751
        }
 
2752
 
 
2753
        if (type == AFR_CHECK_ALL) {
 
2754
                if ((sh_status.gfid_or_missing_entry_self_heal == AFR_SELF_HEAL_FAILED)
 
2755
                    || (sh_status.metadata_self_heal == AFR_SELF_HEAL_FAILED)
 
2756
                    || (sh_status.data_self_heal == AFR_SELF_HEAL_FAILED)
 
2757
                    || (sh_status.entry_self_heal == AFR_SELF_HEAL_FAILED))
 
2758
                sh_failed = 1;
 
2759
        } else if (type == AFR_CHECK_SPECIFIC) {
 
2760
                sh_type_in_action = sh->sh_type_in_action;
 
2761
                switch (sh_type_in_action) {
 
2762
                        case AFR_SELF_HEAL_GFID_OR_MISSING_ENTRY:
 
2763
                             status = sh_status.gfid_or_missing_entry_self_heal;
 
2764
                                break;
 
2765
                        case AFR_SELF_HEAL_METADATA:
 
2766
                                status = sh_status.metadata_self_heal;
 
2767
                                break;
 
2768
                        case AFR_SELF_HEAL_ENTRY:
 
2769
                                status = sh_status.entry_self_heal;
 
2770
                                break;
 
2771
                        case AFR_SELF_HEAL_DATA:
 
2772
                                status = sh_status.data_self_heal;
 
2773
                                break;
 
2774
                        case AFR_SELF_HEAL_INVALID:
 
2775
                                status = AFR_SELF_HEAL_NOT_ATTEMPTED;
 
2776
                                break;
 
2777
                }
 
2778
                if (status == AFR_SELF_HEAL_FAILED)
 
2779
                        sh_failed = 1;
 
2780
 
 
2781
        }
 
2782
 
 
2783
out:
 
2784
        return sh_failed;
 
2785
}
 
2786
 
 
2787
char *
 
2788
get_sh_completion_status (afr_self_heal_status status)
 
2789
{
 
2790
 
 
2791
        char *not_attempted       = " is not attempted";
 
2792
        char *failed              = " failed";
 
2793
        char *started             = " is started";
 
2794
        char *sync_begin          = " is successfully completed";
 
2795
        char *result              = " has unknown status";
 
2796
 
 
2797
        switch (status)
 
2798
        {
 
2799
                case AFR_SELF_HEAL_NOT_ATTEMPTED:
 
2800
                        result = not_attempted;
 
2801
                        break;
 
2802
                case AFR_SELF_HEAL_FAILED:
 
2803
                        result = failed;
 
2804
                        break;
 
2805
                case AFR_SELF_HEAL_STARTED:
 
2806
                        result = started;
 
2807
                        break;
 
2808
                case AFR_SELF_HEAL_SYNC_BEGIN:
 
2809
                        result = sync_begin;
 
2810
                        break;
 
2811
        }
 
2812
 
 
2813
        return result;
 
2814
 
 
2815
}
 
2816
 
 
2817
void
 
2818
afr_log_self_heal_completion_status (afr_local_t *local, gf_loglevel_t loglvl)
 
2819
{
 
2820
 
 
2821
        char sh_log[4096]              = {0};
 
2822
        afr_self_heal_t *sh            = &local->self_heal;
 
2823
        afr_sh_status_for_all_type   all_status = sh->afr_all_sh_status;
 
2824
        xlator_t      *this            = NULL;
 
2825
        size_t        off              = 0;
 
2826
        int           data_sh          = 0;
 
2827
        int           metadata_sh      = 0;
 
2828
        int           print_log        = 0;
 
2829
 
 
2830
        this = THIS;
 
2831
 
 
2832
        ADD_FMT_STRING (sh_log, off, "gfid or missing entry",
 
2833
                        all_status.gfid_or_missing_entry_self_heal, print_log);
 
2834
        ADD_FMT_STRING_SYNC (sh_log, off, "metadata",
 
2835
                             all_status.metadata_self_heal, print_log);
 
2836
        if (sh->background) {
 
2837
                ADD_FMT_STRING_SYNC (sh_log, off, "backgroung data",
 
2838
                                all_status.data_self_heal, print_log);
 
2839
        } else {
 
2840
                ADD_FMT_STRING_SYNC (sh_log, off, "foreground data",
 
2841
                                all_status.data_self_heal, print_log);
 
2842
        }
 
2843
        ADD_FMT_STRING_SYNC (sh_log, off, "entry", all_status.entry_self_heal,
 
2844
                             print_log);
 
2845
 
 
2846
        if (AFR_SELF_HEAL_SYNC_BEGIN == all_status.data_self_heal &&
 
2847
            strcmp (sh->data_sh_info, "") && sh->data_sh_info )
 
2848
                data_sh = 1;
 
2849
        if (AFR_SELF_HEAL_SYNC_BEGIN == all_status.metadata_self_heal &&
 
2850
            strcmp (sh->metadata_sh_info, "") && sh->metadata_sh_info)
 
2851
                metadata_sh = 1;
 
2852
 
 
2853
        if (!print_log)
 
2854
                return;
 
2855
 
 
2856
        gf_log (this->name, loglvl, "%s %s %s on %s", sh_log,
 
2857
                ((data_sh == 1) ? sh->data_sh_info : ""),
 
2858
                ((metadata_sh == 1) ? sh->metadata_sh_info : ""),
 
2859
                local->loc.path);
 
2860
}