Skip to content

Commit ca94abc

Browse files
committed
Fix caching when calling D-Bus methods on individual objects.
This is done in a pretty ham-fisted way, calling back into the bus rather than add another internal communication channel between objects and the manager. If it turns out that this is too costly from a performance perspective, we could always walk back this decision.
1 parent cebc7db commit ca94abc

2 files changed

Lines changed: 129 additions & 80 deletions

File tree

NEWS.md

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,10 @@
55
* `beadm daemon` will no longer emit changed signals for the Space property on
66
boot environment objects, which were causing unnecessary message traffic.
77

8+
* Methods called on individual boot environment objects (as opposed to the
9+
manager) will now flush the cache, emitting signals for any changed properties
10+
immediately and yielding correct `beadm list` output.
11+
812
# beadm v0.2.0
913

1014
* When compiled with D-Bus support, all non-`daemon` subcommands now attempt to

src/dbus.rs

Lines changed: 125 additions & 80 deletions
Original file line numberDiff line numberDiff line change
@@ -448,6 +448,20 @@ impl<T: Client + 'static> BootEnvironmentObject<T> {
448448

449449
Ok(())
450450
}
451+
452+
/// Instruct the boot environment manager to flush its cached boot
453+
/// environments.
454+
async fn refresh(&self, conn: &zbus::Connection) -> Result<(), zbus::fdo::Error> {
455+
conn.call_method(
456+
Some(SERVICE_NAME),
457+
BOOT_ENV_PATH,
458+
Some(MANAGER_INTERFACE),
459+
"Refresh",
460+
&(),
461+
)
462+
.await?;
463+
Ok(())
464+
}
451465
}
452466

453467
#[interface(name = "ca.kamacite.BootEnvironment")]
@@ -531,11 +545,13 @@ impl<T: Client + 'static> BootEnvironmentObject<T> {
531545
#[zbus(connection)] conn: &zbus::Connection,
532546
) -> zbus::fdo::Result<()> {
533547
check_authorization(conn, &header, "ca.kamacite.BootEnvironments1.manage").await?;
534-
let data = self.data.read().unwrap();
535-
self.client
536-
.activate(&data.name, temporary, Some(&data.root))?;
537-
tracing::info!(name = data.name, temporary, "Activated boot environment");
538-
Ok(())
548+
{
549+
let data = self.data.read().unwrap();
550+
self.client
551+
.activate(&data.name, temporary, Some(&data.root))?;
552+
tracing::info!(name = data.name, temporary, "Activated boot environment");
553+
}
554+
self.refresh(conn).await
539555
}
540556

541557
/// Destroy this boot environment.
@@ -547,20 +563,22 @@ impl<T: Client + 'static> BootEnvironmentObject<T> {
547563
#[zbus(connection)] conn: &zbus::Connection,
548564
) -> zbus::fdo::Result<()> {
549565
check_authorization(conn, &header, "ca.kamacite.BootEnvironments1.manage").await?;
550-
let data = self.data.read().unwrap();
551-
self.client.destroy(
552-
&Label::Name(data.name.clone()),
553-
force_unmount,
554-
snapshots,
555-
Some(&data.root),
556-
)?;
557-
tracing::info!(
558-
name = data.name,
559-
force_unmount,
560-
snapshots,
561-
"Destroyed boot environment"
562-
);
563-
Ok(())
566+
{
567+
let data = self.data.read().unwrap();
568+
self.client.destroy(
569+
&Label::Name(data.name.clone()),
570+
force_unmount,
571+
snapshots,
572+
Some(&data.root),
573+
)?;
574+
tracing::info!(
575+
name = data.name,
576+
force_unmount,
577+
snapshots,
578+
"Destroyed boot environment"
579+
);
580+
}
581+
self.refresh(conn).await
564582
}
565583

566584
/// Destroy a snapshot of this boot environment.
@@ -571,16 +589,23 @@ impl<T: Client + 'static> BootEnvironmentObject<T> {
571589
#[zbus(connection)] conn: &zbus::Connection,
572590
) -> zbus::fdo::Result<()> {
573591
check_authorization(conn, &header, "ca.kamacite.BootEnvironments1.manage").await?;
574-
let data = self.data.read().unwrap();
575-
let label = Label::Snapshot(data.name.clone(), snapshot.to_string());
576-
self.client
577-
.destroy(&label, false, false, Some(&data.root))?;
578-
tracing::info!(snapshot = label.to_string(), "Destroyed snapshot");
579-
Ok(())
592+
{
593+
let data = self.data.read().unwrap();
594+
let label = Label::Snapshot(data.name.clone(), snapshot.to_string());
595+
self.client
596+
.destroy(&label, false, false, Some(&data.root))?;
597+
tracing::info!(snapshot = label.to_string(), "Destroyed snapshot");
598+
}
599+
self.refresh(conn).await
580600
}
581601

582602
/// Mount this boot environment.
583-
fn mount(&self, mountpoint: &str, read_only: bool) -> zbus::fdo::Result<()> {
603+
async fn mount(
604+
&self,
605+
mountpoint: &str,
606+
read_only: bool,
607+
#[zbus(connection)] conn: &zbus::Connection,
608+
) -> zbus::fdo::Result<()> {
584609
let mode = if read_only {
585610
MountMode::ReadOnly
586611
} else {
@@ -591,31 +616,41 @@ impl<T: Client + 'static> BootEnvironmentObject<T> {
591616
} else {
592617
Some(PathBuf::from(mountpoint))
593618
};
594-
let data = self.data.read().unwrap();
595-
let result = self.client.mount(
596-
&data.name,
597-
mountpoint.as_ref().map(|mp| mp.as_path()),
598-
mode,
599-
Some(&data.root),
600-
)?;
601-
tracing::info!(
602-
name = data.name,
603-
mountpoint = result.display().to_string(),
604-
read_only,
605-
"Mounted boot environment"
606-
);
607-
Ok(())
619+
{
620+
let data = self.data.read().unwrap();
621+
let result = self.client.mount(
622+
&data.name,
623+
mountpoint.as_ref().map(|mp| mp.as_path()),
624+
mode,
625+
Some(&data.root),
626+
)?;
627+
tracing::info!(
628+
name = data.name,
629+
mountpoint = result.display().to_string(),
630+
read_only,
631+
"Mounted boot environment"
632+
);
633+
}
634+
self.refresh(conn).await
608635
}
609636

610637
/// Unmount this boot environment.
611638
#[zbus(out_args("mountpoint"))]
612-
fn unmount(&self, force: bool) -> zbus::fdo::Result<String> {
613-
let data = self.data.read().unwrap();
614-
let mountpoint = self
615-
.client
616-
.unmount(&data.name, force, Some(&data.root))?
617-
.map(|p| p.display().to_string());
618-
tracing::info!(name = data.name, mountpoint, "Unmounted boot environment");
639+
async fn unmount(
640+
&self,
641+
force: bool,
642+
#[zbus(connection)] conn: &zbus::Connection,
643+
) -> zbus::fdo::Result<String> {
644+
let mountpoint = {
645+
let data = self.data.read().unwrap();
646+
let mountpoint = self
647+
.client
648+
.unmount(&data.name, force, Some(&data.root))?
649+
.map(|p| p.display().to_string());
650+
tracing::info!(name = data.name, mountpoint, "Unmounted boot environment");
651+
mountpoint
652+
};
653+
self.refresh(conn).await?;
619654
Ok(mountpoint.unwrap_or_default())
620655
}
621656

@@ -627,10 +662,12 @@ impl<T: Client + 'static> BootEnvironmentObject<T> {
627662
#[zbus(connection)] conn: &zbus::Connection,
628663
) -> zbus::fdo::Result<()> {
629664
check_authorization(conn, &header, "ca.kamacite.BootEnvironments1.manage").await?;
630-
let data = self.data.read().unwrap();
631-
self.client.rename(&data.name, new_name, Some(&data.root))?;
632-
tracing::info!(name = data.name, new_name, "Renamed boot environment");
633-
Ok(())
665+
{
666+
let data = self.data.read().unwrap();
667+
self.client.rename(&data.name, new_name, Some(&data.root))?;
668+
tracing::info!(name = data.name, new_name, "Renamed boot environment");
669+
}
670+
self.refresh(conn).await
634671
}
635672

636673
/// Roll this boot environment back to a snapshot.
@@ -641,15 +678,17 @@ impl<T: Client + 'static> BootEnvironmentObject<T> {
641678
#[zbus(connection)] conn: &zbus::Connection,
642679
) -> zbus::fdo::Result<()> {
643680
check_authorization(conn, &header, "ca.kamacite.BootEnvironments1.manage").await?;
644-
let data = self.data.read().unwrap();
645-
self.client
646-
.rollback(&data.name, snapshot, Some(&data.root))?;
647-
tracing::info!(
648-
name = data.name,
649-
snapshot,
650-
"Rolled boot environment back to snapshot"
651-
);
652-
Ok(())
681+
{
682+
let data = self.data.read().unwrap();
683+
self.client
684+
.rollback(&data.name, snapshot, Some(&data.root))?;
685+
tracing::info!(
686+
name = data.name,
687+
snapshot,
688+
"Rolled boot environment back to snapshot"
689+
);
690+
}
691+
self.refresh(conn).await
653692
}
654693

655694
/// Get snapshots for this boot environment.
@@ -689,19 +728,23 @@ impl<T: Client + 'static> BootEnvironmentObject<T> {
689728
#[zbus(connection)] conn: &zbus::Connection,
690729
) -> zbus::fdo::Result<String> {
691730
check_authorization(conn, &header, "ca.kamacite.BootEnvironments1.manage").await?;
692-
let data = self.data.read().unwrap();
693-
let label = if snapshot_name.is_empty() {
694-
Label::Name(data.name.clone())
695-
} else {
696-
Label::Snapshot(data.name.clone(), snapshot_name.to_string())
697-
};
698-
let desc = if !description.is_empty() {
699-
Some(description)
700-
} else {
701-
None
731+
let snapshot = {
732+
let data = self.data.read().unwrap();
733+
let label = if snapshot_name.is_empty() {
734+
Label::Name(data.name.clone())
735+
} else {
736+
Label::Snapshot(data.name.clone(), snapshot_name.to_string())
737+
};
738+
let desc = if !description.is_empty() {
739+
Some(description)
740+
} else {
741+
None
742+
};
743+
let snapshot = self.client.snapshot(Some(&label), desc, Some(&data.root))?;
744+
tracing::info!(snapshot, "Created snapshot");
745+
snapshot
702746
};
703-
let snapshot = self.client.snapshot(Some(&label), desc, Some(&data.root))?;
704-
tracing::info!(snapshot, "Created snapshot");
747+
self.refresh(conn).await?;
705748
Ok(snapshot)
706749
}
707750

@@ -713,14 +756,16 @@ impl<T: Client + 'static> BootEnvironmentObject<T> {
713756
#[zbus(connection)] conn: &zbus::Connection,
714757
) -> zbus::fdo::Result<()> {
715758
check_authorization(conn, &header, "ca.kamacite.BootEnvironments1.manage").await?;
716-
let data = self.data.read().unwrap();
717-
self.client.describe(
718-
&Label::Name(data.name.clone()),
719-
description,
720-
Some(&data.root),
721-
)?;
722-
tracing::info!(name = data.name, description, "Set description");
723-
Ok(())
759+
{
760+
let data = self.data.read().unwrap();
761+
self.client.describe(
762+
&Label::Name(data.name.clone()),
763+
description,
764+
Some(&data.root),
765+
)?;
766+
tracing::info!(name = data.name, description, "Set description");
767+
}
768+
self.refresh(conn).await
724769
}
725770
}
726771

0 commit comments

Comments
 (0)