1.. uml::
2  :caption: Control flow of UseDeviceCmd()
3
4  @startuml
5  'BEGIN macros
6  !definelong RESERVE_DEVICE()
7  :ReserveDevice()|
8  !enddefinelong
9
10  !definelong AUTOCHANGER()
11  partition autochanger {
12    while (with each device in autochanger device)
13      #limegreen:if (device autoselect?) then (yes)
14        RESERVE_DEVICE()
15        if (have_device?) then (yes)
16          #tomato:return;
17          detach
18        endif
19      endif
20    endwhile
21  }
22  !enddefinelong
23
24  !definelong PLAIN_DEVICE()
25  partition plain_device {
26  RESERVE_DEVICE()
27  note right
28    try to reserve the named device
29  end note
30  if (have_device?) then (yes)
31    #tomato:return;
32    detach
33  endif
34  #limegreen:if (DeviceReserveByMediatype) then(yes)
35    while (each device with matching media_type)
36      RESERVE_DEVICE()
37      if (have_device?) then (yes)
38        #tomato:return;
39        detach
40      endif
41    endwhile
42  endif
43  }
44  !enddefinelong
45
46  !definelong MOUNTED_VOLUMES()
47  partition mounted_volumes {
48  if (append?) then(yes)
49    while(with each mounted volume)
50      :ask director if volume is ok/
51      if (volume ok?) then(yes)
52        :find device for volume;
53        RESERVE_DEVICE()
54        if (have_device?) then (yes)
55          #tomato:return;
56          detach
57        endif
58      endif
59    endwhile
60  endif
61  }
62  !enddefinelong
63  'END macros
64  |UseDeviceCmd|
65  start
66  partition read_data_from_director {
67    repeat
68      :storage specification<
69      repeat
70        :device specification<
71      repeat while (more devices?)
72    repeat while (more storages?)
73  }
74
75    repeat
76    #aqua:clear suitable_device]
77    #aqua:clear have_volume]
78    #aqua:clear VolumeName]
79    #aqua:clear any_drive]
80    #limegreen:if (PreferMountedVols) then (no)
81        #aqua:clear low_use_drive]
82        #aqua:clear PreferMountedVols]
83        #aqua:clear exact_match]
84        #aqua:set autochanger_only]
85        |FindSuitableDeviceForJob|
86        while (with every device)
87          |SearchResForDevice|
88          AUTOCHANGER()
89          |FindSuitableDeviceForJob|
90        endwhile
91        |UseDeviceCmd|
92        if (have_device) then (yes)
93          stop
94        else (no)
95          #aqua:if (low_use_drive set?) then (yes)
96            #aqua:set try_low_use_drive]
97            |FindSuitableDeviceForJob|
98            while (with every device)
99              |SearchResForDevice|
100              AUTOCHANGER()
101              |FindSuitableDeviceForJob|
102            endwhile
103            |UseDeviceCmd|
104            if (have_device) then (yes)
105              stop
106            endif
107            #aqua:clear try_low_use_drive]
108          endif
109          #aqua:clear autochanger_only]
110          |FindSuitableDeviceForJob|
111          while (with every device)
112            |SearchResForDevice|
113            AUTOCHANGER()
114            PLAIN_DEVICE()
115            |FindSuitableDeviceForJob|
116          endwhile
117          |UseDeviceCmd|
118          if (have_device) then (yes)
119            stop
120          endif
121        endif
122      else (yes)
123      endif
124      #aqua:set PreferMountedVols]
125      #aqua:set exact_match]
126      #aqua:clear autochanger_only]
127      |FindSuitableDeviceForJob|
128      MOUNTED_VOLUMES()
129          while (with every device)
130            |SearchResForDevice|
131            AUTOCHANGER()
132            PLAIN_DEVICE()
133            |FindSuitableDeviceForJob|
134          endwhile
135      |UseDeviceCmd|
136      if (have_device) then (yes)
137        stop
138      else (no)
139        #aqua:clear exact_match]
140        |FindSuitableDeviceForJob|
141      MOUNTED_VOLUMES()
142          while (with every device)
143            |SearchResForDevice|
144            AUTOCHANGER()
145            PLAIN_DEVICE()
146            |FindSuitableDeviceForJob|
147          endwhile
148        |UseDeviceCmd|
149        if (have_device) then (yes)
150          stop
151        else (no)
152          #aqua:set any_drive]
153          |FindSuitableDeviceForJob|
154      MOUNTED_VOLUMES()
155          while (with every device)
156            |SearchResForDevice|
157            AUTOCHANGER()
158            PLAIN_DEVICE()
159            |FindSuitableDeviceForJob|
160          endwhile
161          |UseDeviceCmd|
162          if (have_device) then (yes)
163            stop
164          else (no)
165            if (attempt 3+?) then (yes)
166              :wait 30 seconds;
167            else (no)
168              #aqua:if (suitable_device set?) then (yes)
169                :WaitForDevice()|
170                note right
171                  This will acquire a mutex to queue up
172                  multiple jobs waiting for a device.
173                  Then it waits up to 60 seconds for some
174                  other thread to call ReleaseDeviceCond()
175                end note
176              else (no)
177                (F)
178                detach
179              endif
180            endif
181          endif
182        endif
183      endif
184    repeat while (repeat forever)
185    detach
186  partition failed_to_reserve {
187    (F)
188    :no device message>
189    stop
190  }
191  @enduml
192