+/* NB: lock on checksum file must be held when this is called. */
+static int
+hard_link_to_cached_appliance (guestfs_h *g,
+ const char *cachedir,
+ char **kernel, char **initrd, char **appliance)
+{
+ pid_t pid = getpid ();
+ size_t len = strlen (cachedir) + 32;
+
+ *kernel = safe_malloc (g, len);
+ *initrd = safe_malloc (g, len);
+ *appliance = safe_malloc (g, len);
+ snprintf (*kernel, len, "%s/kernel.%d", cachedir, pid);
+ snprintf (*initrd, len, "%s/initrd.%d", cachedir, pid);
+ snprintf (*appliance, len, "%s/root.%d", cachedir, pid);
+
+ char filename[len];
+ snprintf (filename, len, "%s/kernel", cachedir);
+ (void) unlink (*kernel);
+ if (link (filename, *kernel) == -1) {
+ perrorf (g, "link: %s %s", filename, *kernel);
+ goto error;
+ }
+ (void) lutimes (filename, NULL); /* lutimes because it's a symlink */
+
+ snprintf (filename, len, "%s/initrd", cachedir);
+ (void) unlink (*initrd);
+ if (link (filename, *initrd) == -1) {
+ perrorf (g, "link: %s %s", filename, *initrd);
+ goto error;
+ }
+ (void) utime (filename, NULL);
+
+ snprintf (filename, len, "%s/root", cachedir);
+ (void) unlink (*appliance);
+ if (link (filename, *appliance) == -1) {
+ perrorf (g, "link: %s %s", filename, *appliance);
+ goto error;
+ }
+ (void) utime (filename, NULL);
+
+ return 0;
+
+ error:
+ free (*kernel);
+ free (*initrd);
+ free (*appliance);
+ return -1;
+}
+