Skip to content

Commit b3a2561

Browse files
committed
disk_monitor: Fix message fields and dreadlocks
1 parent 9f9d2db commit b3a2561

File tree

1 file changed

+97
-35
lines changed

1 file changed

+97
-35
lines changed

src/system/libroot2/fs/disk_monitor.cpp

Lines changed: 97 additions & 35 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@
55

66
#include "disk_monitor.h"
77

8+
#include <DiskDeviceRoster.h>
89
#include <NodeMonitor.h>
910

1011
#include <sys/poll.h>
@@ -17,6 +18,7 @@
1718

1819
#include <util/KMessage.h>
1920

21+
#include "disk_device.h"
2022
#include "Team.h"
2123
#include "KernelDebug.h"
2224

@@ -82,24 +84,56 @@ init_udev()
8284

8385

8486
static void
85-
send_device_notification(port_id port, uint32 token, uint32 opcode, dev_t newDevice)
87+
send_device_notification(port_id port, uint32 token, uint32 opcode, dev_t device,
88+
dev_t parentDevice = -1, ino_t parentDirectory = -1)
8689
{
90+
// TODO this code doesn't really understand mount points, we should
91+
// send notifications for volumes that are actually mounted/unmounted.
8792
KMessage message;
88-
char buffer[128];
93+
char buffer[256];
8994
const int32 kPortMessageCode = 'pjpp';
9095
message.SetTo(buffer, sizeof(buffer), B_NODE_MONITOR);
9196
message.AddInt32("opcode", opcode);
9297
if (opcode == B_DEVICE_MOUNTED) {
93-
message.AddInt32("new device", (int32)newDevice);
98+
message.AddInt32("new device", (int32)device);
99+
if (parentDevice != (dev_t)-1)
100+
message.AddInt32("device", (int32)parentDevice);
101+
if (parentDirectory != (ino_t)-1)
102+
message.AddInt64("directory", parentDirectory);
94103
} else {
95-
message.AddInt32("device", (int32)newDevice);
104+
message.AddInt32("device", (int32)device);
96105
}
97106
message.SetDeliveryInfo(token, port, -1, find_thread(NULL));
98107

99108
write_port(port, kPortMessageCode, message.Buffer(), message.ContentSize());
100109
}
101110

102111

112+
static void
113+
send_disk_device_notification(port_id port, uint32 token, uint32 event,
114+
const char* devNode)
115+
{
116+
partition_id deviceId = -1;
117+
if (devNode && devNode[0])
118+
deviceId = make_partition_id(devNode);
119+
120+
if (deviceId < 0)
121+
return;
122+
123+
KMessage message;
124+
char buffer[256];
125+
const int32 kPortMessageCode = 'pjpp';
126+
127+
message.SetTo(buffer, sizeof(buffer), B_DEVICE_UPDATE);
128+
message.AddInt32("event", event);
129+
message.AddInt32("device_id", deviceId);
130+
message.AddInt32("partition_id", deviceId);
131+
message.SetDeliveryInfo(token, port, -1, find_thread(NULL));
132+
133+
write_port(port, kPortMessageCode, message.Buffer(), message.ContentSize());
134+
}
135+
136+
103137
static uint32
104138
udev_action_to_opcode(const char* action)
105139
{
@@ -113,6 +147,21 @@ udev_action_to_opcode(const char* action)
113147
}
114148

115149

150+
static uint32
151+
udev_action_to_disk_event(const char* action)
152+
{
153+
if (!action)
154+
return 0;
155+
if (strcmp(action, "add") == 0)
156+
return B_DEVICE_ADDED;
157+
if (strcmp(action, "remove") == 0)
158+
return B_DEVICE_REMOVED;
159+
if (strcmp(action, "change") == 0)
160+
return B_DEVICE_MEDIA_CHANGED;
161+
return 0;
162+
}
163+
164+
116165
static void
117166
udev_thread_func()
118167
{
@@ -165,10 +214,10 @@ udev_thread_func()
165214
struct udev_device* dev;
166215
while ((dev = udev_monitor_receive_device(udevMonitor)) != nullptr) {
167216
const char* action = udev_device_get_action(dev);
168-
const char* devnode = udev_device_get_devnode(dev);
169-
(void)devnode;
217+
const char* devNode = udev_device_get_devnode(dev);
170218

171219
uint32 opcode = udev_action_to_opcode(action);
220+
uint32 diskEvent = udev_action_to_disk_event(action);
172221
if (opcode != 0) {
173222
dev_t devnum = udev_device_get_devnum(dev);
174223

@@ -206,12 +255,22 @@ udev_thread_func()
206255
const VolumeWatcherKey& key = p.first;
207256
uint32 mask = p.second;
208257
bool send = false;
209-
if (opcode == B_DEVICE_MOUNTED && (mask & WATCH_DISK_ADD))
258+
uint32 eventToSend = 0;
259+
260+
if (diskEvent == B_DEVICE_ADDED && (mask & WATCH_DISK_ADD)) {
261+
send = true;
262+
eventToSend = B_DEVICE_ADDED;
263+
} else if (diskEvent == B_DEVICE_REMOVED && (mask & WATCH_DISK_REMOVE)) {
210264
send = true;
211-
else if (opcode == B_DEVICE_UNMOUNTED && (mask & WATCH_DISK_REMOVE))
265+
eventToSend = B_DEVICE_REMOVED;
266+
} else if (diskEvent == B_DEVICE_MEDIA_CHANGED && (mask & WATCH_DISK_ADD)) {
212267
send = true;
213-
if (send) {
214-
send_device_notification(key.port, key.token, opcode, devnum);
268+
eventToSend = B_DEVICE_MEDIA_CHANGED;
269+
}
270+
271+
if (send && eventToSend != 0) {
272+
send_disk_device_notification(key.port, key.token,
273+
eventToSend, devNode);
215274
}
216275
}
217276
}
@@ -231,38 +290,39 @@ udev_thread_func()
231290
static void
232291
start_thread()
233292
{
234-
bool start = false;
235293
{
236294
std::lock_guard<std::mutex> guard(gWatchLock);
237-
if (!gWatchThreadRunning &&
238-
(!gMountWatchers.empty() || !gVolumeWatchers.empty() || !gDiskWatchers.empty())) {
239-
gWatchThreadRunning = true;
295+
if (gWatchThreadRunning)
296+
return;
297+
if (!gMountWatchers.empty() || !gVolumeWatchers.empty() || !gDiskWatchers.empty()) {
240298
gWatcherExitRequested = false;
241-
start = true;
299+
gWatchThread = std::thread(udev_thread_func);
300+
gWatchThreadRunning = true;
242301
}
243302
}
244-
if (start)
245-
gWatchThread = std::thread(udev_thread_func);
246303
}
247304

305+
248306
static void
249307
stop_thread()
250308
{
251-
bool stop = false;
309+
std::thread threadToJoin;
252310
{
253311
std::lock_guard<std::mutex> guard(gWatchLock);
254-
if (gWatchThreadRunning &&
255-
gMountWatchers.empty() && gVolumeWatchers.empty() && gDiskWatchers.empty()) {
256-
stop = true;
312+
if (!gWatchThreadRunning)
313+
return;
314+
315+
if (gMountWatchers.empty() && gVolumeWatchers.empty() && gDiskWatchers.empty()) {
316+
gWatcherExitRequested = true;
317+
if (gWatchThread.joinable())
318+
threadToJoin = std::move(gWatchThread);
319+
320+
gWatchThreadRunning = false;
257321
}
258322
}
259-
if (stop) {
260-
gWatcherExitRequested = true;
261-
if (gWatchThread.joinable())
262-
gWatchThread.join();
263323

264-
gWatchThreadRunning = false;
265-
}
324+
if (threadToJoin.joinable())
325+
threadToJoin.join();
266326
}
267327

268328

@@ -271,10 +331,11 @@ start_mount_watching(port_id port, uint32 token)
271331
{
272332
printf("start mount_watching\n");
273333

274-
std::lock_guard<std::mutex> guard(gWatchLock);
275-
276-
VolumeWatcherKey key = { port, token };
277-
gMountWatchers[key] = 1;
334+
{
335+
std::lock_guard<std::mutex> guard(gWatchLock);
336+
VolumeWatcherKey key = { port, token };
337+
gMountWatchers[key] = 1;
338+
}
278339

279340
start_thread();
280341
return B_OK;
@@ -302,8 +363,11 @@ start_volume_watching(dev_t device, port_id port, uint32 token)
302363
{
303364
std::lock_guard<std::mutex> guard(gWatchLock);
304365

305-
VolumeWatcher watcher = { port, token, device };
306-
gVolumeWatchers.push_back(watcher);
366+
{
367+
std::lock_guard<std::mutex> guard(gWatchLock);
368+
VolumeWatcher watcher = { port, token, device };
369+
gVolumeWatchers.push_back(watcher);
370+
}
307371

308372
start_thread();
309373
return B_OK;
@@ -369,15 +433,13 @@ extern "C" {
369433
status_t
370434
_kern_start_watching_volume(dev_t device, uint32 flags, port_id port, uint32 token)
371435
{
372-
std::lock_guard<std::mutex> guard(gWatchLock);
373436
return start_volume_watching(device, port, token);
374437
}
375438

376439

377440
status_t
378441
_kern_stop_watching_volume(dev_t device, port_id port, uint32 token)
379442
{
380-
std::lock_guard<std::mutex> guard(gWatchLock);
381443
return stop_volume_watching(device, port, token);
382444
}
383445

0 commit comments

Comments
 (0)