Revision 87d1bf2e snf-image-host/copy-monitor.py

b/snf-image-host/copy-monitor.py
52 52
                      help="The expected number of bytes to be read, " \
53 53
                           "used to compute input progress",
54 54
                      default=None)
55
    parser.add_option("-o", "--output", dest="output", default=None,
56
                    metavar="FILE",
57
                    help="Write output notifications to this file")
55
    parser.add_option("-o", "--output_fd", dest="output", default=None,
56
                    metavar="FILE", type="int",
57
                    help="Write output notifications to this file descriptor")
58 58

  
59 59
    (opts, args) = parser.parse_args(args)
60 60

  
......
95 95

  
96 96
def send_message(to, message):
97 97
    message['timestamp'] = time.time()
98
    to.write("%s\n" % json.dumps(message))
99
    to.flush()
98
    os.write(to, "%s\n" % json.dumps(message))
100 99

  
101 100

  
102 101
def main():
103 102
    (opts, args) = parse_arguments(sys.argv[1:])
104

  
105
    with open(opts.output, 'w') as out:
106
        pid = os.fork()
107
        if pid == 0:
108
            # In child process:
109

  
110
            # Make sure we die with the parent and are not left behind
111
            # WARNING: This uses the prctl(2) call and is Linux-specific.
112
            prctl.set_pdeathsig(signal.SIGHUP)
113

  
114
            # exec command specified in arguments,
115
            # searching the $PATH, keeping all environment
116
            os.execvpe(args[0], args, os.environ)
117
            sys.stderr.write("execvpe failed, exiting with non-zero status")
118
            os.exit(1)
119

  
120
        # In parent process:
121
        iofname = "/proc/%d/io" % pid
122
        iof = open(iofname, "r", 0)   # 0: unbuffered open
123
        sys.stderr.write("%s: created child PID = %d, monitoring file %s\n" %
124
                         (sys.argv[0], pid, iofname))
125

  
126
        message = {}
127
        message['type'] = 'copy-progress'
128
        message['total'] = opts.read_bytes
129

  
130
        while True:
131
            # check if the child process is still alive
132
            (wpid, status) = os.waitpid(pid, os.WNOHANG)
133
            if wpid == pid:
134
                report_wait_status(pid, status)
135
                if (os.WIFEXITED(status) or os.WIFSIGNALED(status)):
136
                    if not (os.WIFEXITED(status) and
137
                                                os.WEXITSTATUS(status) == 0):
138
                        return 1
139
                    else:
140
                        message['position'] = message['total']
141
                        message['progress'] = float(100)
142
                        send_message(out, message)
143
                        return 0
144

  
145
            iof.seek(0)
146
            for l in iof.readlines():
147
                if l.startswith("rchar:"):
148
                    message['position'] = int(l.split(': ')[1])
149
                    message['progress'] = float(100) if opts.read_bytes == 0 \
150
                        else float("%2.2f" % (
151
                            message['position'] * 100.0 / message['total']))
103
    out = opts.output
104
    pid = os.fork()
105
    if pid == 0:
106
        # In child process:
107

  
108
        # Make sure we die with the parent and are not left behind
109
        # WARNING: This uses the prctl(2) call and is Linux-specific.
110
        prctl.set_pdeathsig(signal.SIGHUP)
111

  
112
        # exec command specified in arguments,
113
        # searching the $PATH, keeping all environment
114
        os.execvpe(args[0], args, os.environ)
115
        sys.stderr.write("execvpe failed, exiting with non-zero status")
116
        os.exit(1)
117

  
118
    # In parent process:
119
    iofname = "/proc/%d/io" % pid
120
    iof = open(iofname, "r", 0)   # 0: unbuffered open
121
    sys.stderr.write("%s: created child PID = %d, monitoring file %s\n" %
122
                     (sys.argv[0], pid, iofname))
123

  
124
    message = {}
125
    message['type'] = 'copy-progress'
126
    message['total'] = opts.read_bytes
127

  
128
    while True:
129
        # check if the child process is still alive
130
        (wpid, status) = os.waitpid(pid, os.WNOHANG)
131
        if wpid == pid:
132
            report_wait_status(pid, status)
133
            if (os.WIFEXITED(status) or os.WIFSIGNALED(status)):
134
                if not (os.WIFEXITED(status) and
135
                                            os.WEXITSTATUS(status) == 0):
136
                    return 1
137
                else:
138
                    message['position'] = message['total']
139
                    message['progress'] = float(100)
152 140
                    send_message(out, message)
153
                    break
154

  
155
            # Sleep for a while
156
            time.sleep(3)
157

  
141
                    return 0
142

  
143
        iof.seek(0)
144
        for l in iof.readlines():
145
            if l.startswith("rchar:"):
146
                message['position'] = int(l.split(': ')[1])
147
                message['progress'] = float(100) if opts.read_bytes == 0 \
148
                    else float("%2.2f" % (
149
                        message['position'] * 100.0 / message['total']))
150
                send_message(out, message)
151
                break
152

  
153
        # Sleep for a while
154
        time.sleep(3)
158 155

  
159 156
if __name__ == "__main__":
160 157
    sys.exit(main())

Also available in: Unified diff