Skip to content

Commit cf30a8c

Browse files
committed
machined: port machined's bus APIs to use new image metadata API
Let's rework the D-Bus APIs GetImageOSRelease() to use the new internal metadata API, to query what it needs to know. Augment it with GetImageHostname(), GetImageMachineID(), GetImageMachineInfo(), that expose the other new APIS.
1 parent c7664c0 commit cf30a8c

File tree

4 files changed

+153
-122
lines changed

4 files changed

+153
-122
lines changed

src/machine/image-dbus.c

Lines changed: 51 additions & 122 deletions
Original file line numberDiff line numberDiff line change
@@ -290,159 +290,85 @@ int bus_image_method_set_limit(
290290
return sd_bus_reply_method_return(message, NULL);
291291
}
292292

293-
#define EXIT_NOT_FOUND 2
294-
295-
static int directory_image_get_os_release(Image *image, char ***ret, sd_bus_error *error) {
293+
int bus_image_method_get_hostname(
294+
sd_bus_message *message,
295+
void *userdata,
296+
sd_bus_error *error) {
296297

297-
_cleanup_free_ char *path = NULL;
298+
_cleanup_(sd_bus_message_unrefp) sd_bus_message *reply = NULL;
299+
Image *image = userdata;
298300
int r;
299301

300-
assert(image);
301-
assert(ret);
302-
303-
r = chase_symlinks("/etc/os-release", image->path, CHASE_PREFIX_ROOT, &path);
304-
if (r == -ENOENT)
305-
r = chase_symlinks("/usr/lib/os-release", image->path, CHASE_PREFIX_ROOT, &path);
306-
if (r == -ENOENT)
307-
return sd_bus_error_setf(error, SD_BUS_ERROR_FAILED, "Image does not contain OS release information");
308-
if (r < 0)
309-
return sd_bus_error_set_errnof(error, r, "Failed to resolve %s: %m", image->path);
310-
311-
r = load_env_file_pairs(NULL, path, NULL, ret);
312-
if (r < 0)
313-
return sd_bus_error_set_errnof(error, r, "Failed to open %s: %m", path);
302+
if (!image->metadata_valid) {
303+
r = image_read_metadata(image);
304+
if (r < 0)
305+
return sd_bus_error_set_errnof(error, r, "Failed to read image metadata: %m");
306+
}
314307

315-
return 0;
308+
return sd_bus_reply_method_return(message, "s", image->hostname);
316309
}
317310

318-
static int raw_image_get_os_release(Image *image, char ***ret, sd_bus_error *error) {
319-
_cleanup_(rmdir_and_freep) char *t = NULL;
320-
_cleanup_(loop_device_unrefp) LoopDevice *d = NULL;
321-
_cleanup_(dissected_image_unrefp) DissectedImage *m = NULL;
322-
_cleanup_(sigkill_waitp) pid_t child = 0;
323-
_cleanup_close_pair_ int pair[2] = { -1, -1 };
324-
_cleanup_fclose_ FILE *f = NULL;
325-
_cleanup_strv_free_ char **v = NULL;
326-
siginfo_t si;
327-
int r;
328-
329-
assert(image);
330-
assert(ret);
331-
332-
r = mkdtemp_malloc("/tmp/machined-root-XXXXXX", &t);
333-
if (r < 0)
334-
return sd_bus_error_set_errnof(error, r, "Failed to create temporary directory: %m");
335-
336-
r = loop_device_make_by_path(image->path, O_RDONLY, &d);
337-
if (r < 0)
338-
return sd_bus_error_set_errnof(error, r, "Failed to set up loop block device for %s: %m", image->path);
339-
340-
r = dissect_image(d->fd, NULL, 0, DISSECT_IMAGE_REQUIRE_ROOT, &m);
341-
if (r == -ENOPKG)
342-
return sd_bus_error_set_errnof(error, r, "Disk image %s not understood: %m", image->path);
343-
if (r < 0)
344-
return sd_bus_error_set_errnof(error, r, "Failed to dissect image %s: %m", image->path);
345-
346-
if (pipe2(pair, O_CLOEXEC) < 0)
347-
return sd_bus_error_set_errnof(error, errno, "Failed to create communication pipe: %m");
348-
349-
child = raw_clone(SIGCHLD|CLONE_NEWNS);
350-
if (child < 0)
351-
return sd_bus_error_set_errnof(error, errno, "Failed to fork(): %m");
352-
353-
if (child == 0) {
354-
int fd;
355-
356-
pair[0] = safe_close(pair[0]);
357-
358-
/* Make sure we never propagate to the host */
359-
if (mount(NULL, "/", NULL, MS_SLAVE | MS_REC, NULL) < 0)
360-
_exit(EXIT_FAILURE);
361-
362-
r = dissected_image_mount(m, t, DISSECT_IMAGE_READ_ONLY);
363-
if (r < 0)
364-
_exit(EXIT_FAILURE);
365-
366-
r = mount_move_root(t);
367-
if (r < 0)
368-
_exit(EXIT_FAILURE);
311+
int bus_image_method_get_machine_id(
312+
sd_bus_message *message,
313+
void *userdata,
314+
sd_bus_error *error) {
369315

370-
fd = open("/etc/os-release", O_RDONLY|O_CLOEXEC|O_NOCTTY);
371-
if (fd < 0 && errno == ENOENT) {
372-
fd = open("/usr/lib/os-release", O_RDONLY|O_CLOEXEC|O_NOCTTY);
373-
if (fd < 0 && errno == ENOENT)
374-
_exit(EXIT_NOT_FOUND);
375-
}
376-
if (fd < 0)
377-
_exit(EXIT_FAILURE);
316+
_cleanup_(sd_bus_message_unrefp) sd_bus_message *reply = NULL;
317+
Image *image = userdata;
318+
int r;
378319

379-
r = copy_bytes(fd, pair[1], (uint64_t) -1, 0);
320+
if (!image->metadata_valid) {
321+
r = image_read_metadata(image);
380322
if (r < 0)
381-
_exit(EXIT_FAILURE);
382-
383-
_exit(EXIT_SUCCESS);
323+
return sd_bus_error_set_errnof(error, r, "Failed to read image metadata: %m");
384324
}
385325

386-
pair[1] = safe_close(pair[1]);
387-
388-
f = fdopen(pair[0], "re");
389-
if (!f)
390-
return -errno;
391-
392-
pair[0] = -1;
393-
394-
r = load_env_file_pairs(f, "os-release", NULL, &v);
326+
r = sd_bus_message_new_method_return(message, &reply);
395327
if (r < 0)
396328
return r;
397329

398-
r = wait_for_terminate(child, &si);
330+
if (sd_id128_is_null(image->machine_id)) /* Add an empty array if the ID is zero */
331+
r = sd_bus_message_append(reply, "ay", 0);
332+
else
333+
r = sd_bus_message_append_array(reply, 'y', image->machine_id.bytes, 16);
399334
if (r < 0)
400-
return sd_bus_error_set_errnof(error, r, "Failed to wait for child: %m");
401-
child = 0;
402-
if (si.si_code == CLD_EXITED && si.si_status == EXIT_NOT_FOUND)
403-
return sd_bus_error_setf(error, SD_BUS_ERROR_FAILED, "Image does not contain OS release information");
404-
if (si.si_code != CLD_EXITED || si.si_status != EXIT_SUCCESS)
405-
return sd_bus_error_setf(error, SD_BUS_ERROR_FAILED, "Child died abnormally.");
406-
407-
*ret = v;
408-
v = NULL;
335+
return r;
409336

410-
return 0;
337+
return sd_bus_send(NULL, reply, NULL);
411338
}
412339

413-
int bus_image_method_get_os_release(
340+
int bus_image_method_get_machine_info(
414341
sd_bus_message *message,
415342
void *userdata,
416343
sd_bus_error *error) {
417344

418-
_cleanup_release_lock_file_ LockFile tree_global_lock = LOCK_FILE_INIT, tree_local_lock = LOCK_FILE_INIT;
419-
_cleanup_strv_free_ char **v = NULL;
420345
Image *image = userdata;
421346
int r;
422347

423-
r = image_path_lock(image->path, LOCK_SH|LOCK_NB, &tree_global_lock, &tree_local_lock);
424-
if (r < 0)
425-
return sd_bus_error_set_errnof(error, r, "Failed to lock image: %m");
348+
if (!image->metadata_valid) {
349+
r = image_read_metadata(image);
350+
if (r < 0)
351+
return sd_bus_error_set_errnof(error, r, "Failed to read image metadata: %m");
352+
}
426353

427-
switch (image->type) {
354+
return bus_reply_pair_array(message, image->machine_info);
355+
}
428356

429-
case IMAGE_DIRECTORY:
430-
case IMAGE_SUBVOLUME:
431-
r = directory_image_get_os_release(image, &v, error);
432-
break;
357+
int bus_image_method_get_os_release(
358+
sd_bus_message *message,
359+
void *userdata,
360+
sd_bus_error *error) {
433361

434-
case IMAGE_RAW:
435-
case IMAGE_BLOCK:
436-
r = raw_image_get_os_release(image, &v, error);
437-
break;
362+
Image *image = userdata;
363+
int r;
438364

439-
default:
440-
assert_not_reached("Unknown image type");
365+
if (!image->metadata_valid) {
366+
r = image_read_metadata(image);
367+
if (r < 0)
368+
return sd_bus_error_set_errnof(error, r, "Failed to read image metadata: %m");
441369
}
442-
if (r < 0)
443-
return r;
444370

445-
return bus_reply_pair_array(message, v);
371+
return bus_reply_pair_array(message, image->os_release);
446372
}
447373

448374
const sd_bus_vtable image_vtable[] = {
@@ -462,6 +388,9 @@ const sd_bus_vtable image_vtable[] = {
462388
SD_BUS_METHOD("Clone", "sb", NULL, bus_image_method_clone, SD_BUS_VTABLE_UNPRIVILEGED),
463389
SD_BUS_METHOD("MarkReadOnly", "b", NULL, bus_image_method_mark_read_only, SD_BUS_VTABLE_UNPRIVILEGED),
464390
SD_BUS_METHOD("SetLimit", "t", NULL, bus_image_method_set_limit, SD_BUS_VTABLE_UNPRIVILEGED),
391+
SD_BUS_METHOD("GetHostname", NULL, "s", bus_image_method_get_hostname, SD_BUS_VTABLE_UNPRIVILEGED),
392+
SD_BUS_METHOD("GetMachineID", NULL, "ay", bus_image_method_get_machine_id, SD_BUS_VTABLE_UNPRIVILEGED),
393+
SD_BUS_METHOD("GetMachineInfo", NULL, "a{ss}", bus_image_method_get_machine_info, SD_BUS_VTABLE_UNPRIVILEGED),
465394
SD_BUS_METHOD("GetOSRelease", NULL, "a{ss}", bus_image_method_get_os_release, SD_BUS_VTABLE_UNPRIVILEGED),
466395
SD_BUS_VTABLE_END
467396
};

src/machine/image-dbus.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -34,4 +34,7 @@ int bus_image_method_rename(sd_bus_message *message, void *userdata, sd_bus_erro
3434
int bus_image_method_clone(sd_bus_message *message, void *userdata, sd_bus_error *error);
3535
int bus_image_method_mark_read_only(sd_bus_message *message, void *userdata, sd_bus_error *error);
3636
int bus_image_method_set_limit(sd_bus_message *message, void *userdata, sd_bus_error *error);
37+
int bus_image_method_get_hostname(sd_bus_message *message, void *userdata, sd_bus_error *error);
38+
int bus_image_method_get_machine_id(sd_bus_message *message, void *userdata, sd_bus_error *error);
39+
int bus_image_method_get_machine_info(sd_bus_message *message, void *userdata, sd_bus_error *error);
3740
int bus_image_method_get_os_release(sd_bus_message *message, void *userdata, sd_bus_error *error);

src/machine/machined-dbus.c

Lines changed: 75 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -846,6 +846,78 @@ static int method_mark_image_read_only(sd_bus_message *message, void *userdata,
846846
return bus_image_method_mark_read_only(message, i, error);
847847
}
848848

849+
static int method_get_image_hostname(sd_bus_message *message, void *userdata, sd_bus_error *error) {
850+
_cleanup_(image_unrefp) Image *i = NULL;
851+
const char *name;
852+
int r;
853+
854+
assert(message);
855+
856+
r = sd_bus_message_read(message, "s", &name);
857+
if (r < 0)
858+
return r;
859+
860+
if (!image_name_is_valid(name))
861+
return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Image name '%s' is invalid.", name);
862+
863+
r = image_find(name, &i);
864+
if (r < 0)
865+
return r;
866+
if (r == 0)
867+
return sd_bus_error_setf(error, BUS_ERROR_NO_SUCH_IMAGE, "No image '%s' known", name);
868+
869+
i->userdata = userdata;
870+
return bus_image_method_get_hostname(message, i, error);
871+
}
872+
873+
static int method_get_image_machine_id(sd_bus_message *message, void *userdata, sd_bus_error *error) {
874+
_cleanup_(image_unrefp) Image *i = NULL;
875+
const char *name;
876+
int r;
877+
878+
assert(message);
879+
880+
r = sd_bus_message_read(message, "s", &name);
881+
if (r < 0)
882+
return r;
883+
884+
if (!image_name_is_valid(name))
885+
return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Image name '%s' is invalid.", name);
886+
887+
r = image_find(name, &i);
888+
if (r < 0)
889+
return r;
890+
if (r == 0)
891+
return sd_bus_error_setf(error, BUS_ERROR_NO_SUCH_IMAGE, "No image '%s' known", name);
892+
893+
i->userdata = userdata;
894+
return bus_image_method_get_machine_id(message, i, error);
895+
}
896+
897+
static int method_get_image_machine_info(sd_bus_message *message, void *userdata, sd_bus_error *error) {
898+
_cleanup_(image_unrefp) Image *i = NULL;
899+
const char *name;
900+
int r;
901+
902+
assert(message);
903+
904+
r = sd_bus_message_read(message, "s", &name);
905+
if (r < 0)
906+
return r;
907+
908+
if (!image_name_is_valid(name))
909+
return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Image name '%s' is invalid.", name);
910+
911+
r = image_find(name, &i);
912+
if (r < 0)
913+
return r;
914+
if (r == 0)
915+
return sd_bus_error_setf(error, BUS_ERROR_NO_SUCH_IMAGE, "No image '%s' known", name);
916+
917+
i->userdata = userdata;
918+
return bus_image_method_get_machine_info(message, i, error);
919+
}
920+
849921
static int method_get_image_os_release(sd_bus_message *message, void *userdata, sd_bus_error *error) {
850922
_cleanup_(image_unrefp) Image *i = NULL;
851923
const char *name;
@@ -1442,6 +1514,9 @@ const sd_bus_vtable manager_vtable[] = {
14421514
SD_BUS_METHOD("RenameImage", "ss", NULL, method_rename_image, SD_BUS_VTABLE_UNPRIVILEGED),
14431515
SD_BUS_METHOD("CloneImage", "ssb", NULL, method_clone_image, SD_BUS_VTABLE_UNPRIVILEGED),
14441516
SD_BUS_METHOD("MarkImageReadOnly", "sb", NULL, method_mark_image_read_only, SD_BUS_VTABLE_UNPRIVILEGED),
1517+
SD_BUS_METHOD("GetImageHostname", "s", "s", method_get_image_hostname, SD_BUS_VTABLE_UNPRIVILEGED),
1518+
SD_BUS_METHOD("GetImageMachineID", "s", "ay", method_get_image_machine_id, SD_BUS_VTABLE_UNPRIVILEGED),
1519+
SD_BUS_METHOD("GetImageMachineInfo", "s", "a{ss}", method_get_image_machine_info, SD_BUS_VTABLE_UNPRIVILEGED),
14451520
SD_BUS_METHOD("GetImageOSRelease", "s", "a{ss}", method_get_image_os_release, SD_BUS_VTABLE_UNPRIVILEGED),
14461521
SD_BUS_METHOD("SetPoolLimit", "t", NULL, method_set_pool_limit, SD_BUS_VTABLE_UNPRIVILEGED),
14471522
SD_BUS_METHOD("SetImageLimit", "st", NULL, method_set_image_limit, SD_BUS_VTABLE_UNPRIVILEGED),

src/machine/org.freedesktop.machine1.conf

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -120,6 +120,18 @@
120120
send_interface="org.freedesktop.machine1.Manager"
121121
send_member="SetImageLimit"/>
122122

123+
<allow send_destination="org.freedesktop.machine1"
124+
send_interface="org.freedesktop.machine1.Manager"
125+
send_member="GetImageHostname"/>
126+
127+
<allow send_destination="org.freedesktop.machine1"
128+
send_interface="org.freedesktop.machine1.Manager"
129+
send_member="GetImageMachineID"/>
130+
131+
<allow send_destination="org.freedesktop.machine1"
132+
send_interface="org.freedesktop.machine1.Manager"
133+
send_member="GetImageMachineInfo"/>
134+
123135
<allow send_destination="org.freedesktop.machine1"
124136
send_interface="org.freedesktop.machine1.Manager"
125137
send_member="GetImageOSRelease"/>
@@ -204,6 +216,18 @@
204216
send_interface="org.freedesktop.machine1.Image"
205217
send_member="MarkReadOnly"/>
206218

219+
<allow send_destination="org.freedesktop.machine1"
220+
send_interface="org.freedesktop.machine1.Image"
221+
send_member="GetHostname"/>
222+
223+
<allow send_destination="org.freedesktop.machine1"
224+
send_interface="org.freedesktop.machine1.Image"
225+
send_member="GetMachineID"/>
226+
227+
<allow send_destination="org.freedesktop.machine1"
228+
send_interface="org.freedesktop.machine1.Image"
229+
send_member="GetMachineInfo"/>
230+
207231
<allow send_destination="org.freedesktop.machine1"
208232
send_interface="org.freedesktop.machine1.Image"
209233
send_member="GetOSRelease"/>

0 commit comments

Comments
 (0)