recon-cron: Tolerate missing directories
Any of these directories may get unlinked between when we saw them in their parent's directory listing and when we go to descend. Change-Id: I1dfc0ee1d9e70cb0600557cde980bd5880bd40b3
This commit is contained in:
parent
b6dc24dbc0
commit
f31b6f7353
|
@ -18,18 +18,18 @@ import time
|
||||||
from eventlet import Timeout
|
from eventlet import Timeout
|
||||||
|
|
||||||
from swift.common.utils import get_logger, dump_recon_cache, readconf, \
|
from swift.common.utils import get_logger, dump_recon_cache, readconf, \
|
||||||
lock_path
|
lock_path, listdir
|
||||||
from swift.common.recon import RECON_OBJECT_FILE, DEFAULT_RECON_CACHE_PATH
|
from swift.common.recon import RECON_OBJECT_FILE, DEFAULT_RECON_CACHE_PATH
|
||||||
from swift.obj.diskfile import ASYNCDIR_BASE
|
from swift.obj.diskfile import ASYNCDIR_BASE
|
||||||
|
|
||||||
|
|
||||||
def get_async_count(device_dir):
|
def get_async_count(device_dir):
|
||||||
async_count = 0
|
async_count = 0
|
||||||
for i in os.listdir(device_dir):
|
for i in listdir(device_dir):
|
||||||
device = os.path.join(device_dir, i)
|
device = os.path.join(device_dir, i)
|
||||||
if not os.path.isdir(device):
|
if not os.path.isdir(device):
|
||||||
continue
|
continue
|
||||||
for asyncdir in os.listdir(device):
|
for asyncdir in listdir(device):
|
||||||
# skip stuff like "accounts", "containers", etc.
|
# skip stuff like "accounts", "containers", etc.
|
||||||
if not (asyncdir == ASYNCDIR_BASE or
|
if not (asyncdir == ASYNCDIR_BASE or
|
||||||
asyncdir.startswith(ASYNCDIR_BASE + '-')):
|
asyncdir.startswith(ASYNCDIR_BASE + '-')):
|
||||||
|
@ -37,10 +37,10 @@ def get_async_count(device_dir):
|
||||||
async_pending = os.path.join(device, asyncdir)
|
async_pending = os.path.join(device, asyncdir)
|
||||||
|
|
||||||
if os.path.isdir(async_pending):
|
if os.path.isdir(async_pending):
|
||||||
for entry in os.listdir(async_pending):
|
for entry in listdir(async_pending):
|
||||||
if os.path.isdir(os.path.join(async_pending, entry)):
|
if os.path.isdir(os.path.join(async_pending, entry)):
|
||||||
async_hdir = os.path.join(async_pending, entry)
|
async_hdir = os.path.join(async_pending, entry)
|
||||||
async_count += len(os.listdir(async_hdir))
|
async_count += len(listdir(async_hdir))
|
||||||
return async_count
|
return async_count
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -16,6 +16,7 @@
|
||||||
import tempfile
|
import tempfile
|
||||||
import shutil
|
import shutil
|
||||||
import os
|
import os
|
||||||
|
import mock
|
||||||
|
|
||||||
from unittest import TestCase
|
from unittest import TestCase
|
||||||
from swift.cli.recon_cron import get_async_count
|
from swift.cli.recon_cron import get_async_count
|
||||||
|
@ -48,3 +49,32 @@ class TestReconCron(TestCase):
|
||||||
|
|
||||||
count = get_async_count(device_dir)
|
count = get_async_count(device_dir)
|
||||||
self.assertEqual(count, 3)
|
self.assertEqual(count, 3)
|
||||||
|
|
||||||
|
def test_get_async_count_deleted(self):
|
||||||
|
device_dir = os.path.join(self.temp_dir, 'device')
|
||||||
|
device_index = os.path.join(device_dir, '1')
|
||||||
|
async_dir = os.path.join(device_index, ASYNCDIR_BASE)
|
||||||
|
entry1 = os.path.join(async_dir, 'entry1')
|
||||||
|
entry2 = os.path.join(async_dir, 'entry2')
|
||||||
|
os.makedirs(entry1)
|
||||||
|
os.makedirs(entry2)
|
||||||
|
|
||||||
|
pending_file1 = os.path.join(entry1, 'pending_file1')
|
||||||
|
pending_file2 = os.path.join(entry1, 'pending_file2')
|
||||||
|
pending_file3 = os.path.join(entry2, 'pending_file3')
|
||||||
|
open(pending_file1, 'w').close()
|
||||||
|
open(pending_file2, 'w').close()
|
||||||
|
open(pending_file3, 'w').close()
|
||||||
|
|
||||||
|
orig_isdir = os.path.isdir
|
||||||
|
|
||||||
|
def racy_isdir(d):
|
||||||
|
result = orig_isdir(d)
|
||||||
|
if d == entry1:
|
||||||
|
# clean it up before caller has a chance to descend
|
||||||
|
shutil.rmtree(entry1)
|
||||||
|
return result
|
||||||
|
|
||||||
|
with mock.patch('os.path.isdir', racy_isdir):
|
||||||
|
count = get_async_count(device_dir)
|
||||||
|
self.assertEqual(count, 1)
|
||||||
|
|
Loading…
Reference in New Issue