jborean93 / smbprotocol

Python SMBv2 and v3 Client
MIT License
318 stars 73 forks source link

scandir working once. 24h later SMBOSError w/ STATUS_PATH_NOT_COVERED for same dir. #159

Closed jahn-michael closed 2 years ago

jahn-michael commented 2 years ago

Hello,

I have a problem where I can't scandir the same directory twice in an interval of 24h. After I let the script crash and it is restarted everything works fine again. For me it seems, that some state of the previous connection seems to survive even after (or without) explicitly resetting the connection cache.

Traceback (most recent call last): File "importer.py", line 129, in spec_scheduler=SpecScheduler(assert_env('CONF_SCHEDULE')) File "importer.py", line 87, in run_import spec_scheduler.run(importer.run) File "spec_scheduler.py", line 27, in run self.scheduler.run_pending() File ".../schedule/init.py", line 94, in run_pending self._run_job(job) File ".../schedule/init.py", line 147, in _run_job ret = job.run() File ".../schedule/init.py", line 491, in run ret = self.job_func() File "spec_scheduler.py", line 19, in func self.current_func() File "importer.py", line 42, in run for file_content in self.resource_provider File "importer.py", line 41, in value File ".../resource_provider.py", line 66, in iter for path in self.list_matching_paths(self.path): File ".../resource_provider.py", line 90, in __list_matching_paths0 if entry.is_file() and self.regex.match(entry.path): File ".../smbclient/_os.py", line 1139, in is_file is_lnk = self.is_symlink() File ".../smbclient/_os.py", line 1164, in is_symlink lstat = self.stat(follow_symlinks=False) File ".../smbclient/_os.py", line 1194, in stat self._lstat = lstat(self.path) File ".../smbclient/_os.py", line 250, in lstat return stat(path, follow_symlinks=False, **kwargs) File ".../smbclient/_os.py", line 561, in stat query_info(transaction, FileAttributeTagInformation) File ".../smbclient/_io.py", line 211, in exit__ self.commit() File ".../smbclient/_io.py", line 251, in commit raise failures[0] smbprotocol.exceptions.SMBOSError: [Error 0] [NtStatus 0xc0000257] Unknown NtStatus error returned 'STATUS_PATH_NOT_COVERED': '\foo.bar.baz\dfs\my\first\time\working\path.xlsx'

def __list_matching_paths(self, path: str) -> Generator[str, None, None]:
    try:
        smbclient.ClientConfig(
            username=self.username,
            password=self.password,
            skip_dfs=True
        )
        return self.__list_matching_paths0(path)
    finally:
        smbclient.reset_connection_cache(fail_on_error=False)

def __list_matching_paths0(self, path: str) -> Generator[str, None, None]:
    dir_entries = smbclient.scandir(path=path)
    for entry in dir_entries:
        if entry.is_file() and self.regex.match(entry.path):
            yield entry.path
        if entry.is_dir():
            yield from self.__list_matching_paths0(entry.path)
    return None

I also tried it w/o the rest_connection_cache() as well as w/ skip_dfs=True|False to no avail. It seems it is keeping some of the state from the previous connection and then everything falls to pieces.

Do you have any idea what I could try to make it work? Is there a way to get rid of any state the library supposedly maintains? This definitely works if the process is crashing and simply restarted.

Thanks in advance for any insight on this.

jahn-michael commented 2 years ago

Found a way to get this working. Problem of the code above was a misunderstanding on my side how python generators work. Sorry for the bothering you with this.

jborean93 commented 2 years ago

Apologies for not getting back to your earlier, glad you got it working properly.