4

これを実行すると、リークが発生します。何が起こっているのかわかりません。パイプが閉じていないか、何か他のことが起こっている可能性があります。

def deactivateMetadataDevice(input_dmd_lun_wwn):
    #print('pvremove /dev/mapper/' + input_dmd_lun_wwn)
    status_cmd = False
    ps = subprocess.Popen('/sbin/pvremove /dev/mapper/' + input_dmd_lun_wwn, shell=True, stdout=subprocess.PIPE, stderr=subprocess.STDOUT)
    for line in iter(ps.stdout.readline, ''):
        print line
        if re.search('wiped', line):
           status_cmd = True
        else:
           # Cleaning metadata and removing from LVM if ok then return true
           status_cmd = False
           raise Warning('\t\t PV /dev/mapper/'+ input_dmd_lun_wwn +' belongs to Volume Group')

    return status_cmd

上記のコードを実行すると、この問題が発生します。

File descriptor 4 (pipe:[323948]) leaked on pvremove invocation. Parent PID 15380: python
4

3 に答える 3

4

問題は、パイプ内のすべてのデータを読み取る前に戻り、戻りコードを取得してオペレーティング システムの pid テーブルからプロセスを削除するための待機を発行しないことです。いくつかの調整でうまくいくと思います(冗長だと思ったものもいくつか削除しました)。

def deactivateMetadataDevice(input_dmd_lun_wwn):
    #print('pvremove /dev/mapper/' + input_dmd_lun_wwn)
    status_cmd = False
    ps = subprocess.Popen('/sbin/pvremove /dev/mapper/' + input_dmd_lun_wwn, shell=True, stdout=subprocess.PIPE, stderr=subprocess.STDOUT)
    for line in ps.stdout:
        print line
        if 'wiped' in line:
           status_cmd = True
    ps.wait()
    # need to handle ps.returncode != 0
    if status_cmd is False:
       # Cleaning metadata and removing from LVM if ok then return true
       raise Warning('\t\t PV /dev/mapper/'+ input_dmd_lun_wwn +' belongs to Volume Group')
    return status_cmd # likely not needed because you are using exceptions for errors
于 2013-08-23T18:26:00.547 に答える
0

私は結局このようにしました。残念ながら、env のほとんどのサーバーには python 2.6 があります。Check_output は python 2.7 バージョンに付属しています。

# check_output in subprocess unfortunately comes by default in 2.7 version
def check_output(*popenargs, **kwargs):
    # Passing all arguments to process
    process = subprocess.Popen(stdout=subprocess.PIPE, *popenargs, **kwargs)
    output, unused_err = process.communicate()
    retcode = process.poll()

    if retcode:
       cmd = kwargs.get("args")
       if cmd is None:
          cmd = popenargs[0]
       error = subprocess.CalledProcessError(retcode, cmd)
       error.output = output
       raise error

    return output

# Function to remove metadata from phisical device
def deactivateMetadataDevice(input_dmd_lun_wwn):
    #print('pvremove /dev/mapper/' + input_dmd_lun_wwn)
    status_cmd = False
    if 'wiped' in check_output(["/sbin/pvremove", "/dev/mapper/" + input_dmd_lun_wwn]):
       status_cmd = True

    return status_cmd
于 2013-08-30T06:06:23.427 に答える