/* * If mask is nonzero, will not write any file whose filenamenode * has any flag bits set in mask. */ void write_filelist_except(struct pkginfo *pkg, struct pkgbin *pkgbin, struct fileinlist *list, enum fnnflags mask) { struct atomic_file *file; const char *listfile; listfile = pkg_infodb_get_file(pkg, pkgbin, LISTFILE); file = atomic_file_new(listfile, 0); atomic_file_open(file); while (list) { if (!(mask && (list->namenode->flags & mask))) { fputs(list->namenode->name, file->fp); putc('\n', file->fp); } list= list->next; } atomic_file_sync(file); atomic_file_close(file); atomic_file_commit(file); atomic_file_free(file); dir_sync_path(pkg_infodb_get_dir()); note_must_reread_files_inpackage(pkg); }
/* * Called by modstatdb_note. */ void trig_activate_packageprocessing(struct pkginfo *pkg) { debug(dbg_triggersdetail, "trigproc_activate_packageprocessing pkg=%s", pkg_name(pkg, pnaw_always)); trig_parse_ci(pkg_infodb_get_file(pkg, &pkg->installed, TRIGGERSCIFILE), NULL, trig_cicb_statuschange_activate, pkg, &pkg->installed); }
static void pkg_files_optimize_load(struct pkg_array *array) { struct statfs fs; int i; /* Get the filesystem block size. */ if (statfs(pkg_infodb_get_dir(), &fs) < 0) return; /* Sort packages by the physical location of their list files, so that * scanning them later will minimize disk drive head movements. */ for (i = 0; i < array->n_pkgs; i++) { struct pkginfo *pkg = array->pkgs[i]; struct { struct fiemap fiemap; struct fiemap_extent extent; } fm; const char *listfile; int fd; ensure_package_clientdata(pkg); if (pkg->status == stat_notinstalled || pkg->clientdata->listfile_phys_offs != 0) continue; pkg->clientdata->listfile_phys_offs = -1; listfile = pkg_infodb_get_file(pkg, &pkg->installed, LISTFILE); fd = open(listfile, O_RDONLY); if (fd < 0) continue; memset(&fm, 0, sizeof(fm)); fm.fiemap.fm_start = 0; fm.fiemap.fm_length = fs.f_bsize; fm.fiemap.fm_flags = 0; fm.fiemap.fm_extent_count = 1; if (ioctl(fd, FS_IOC_FIEMAP, (unsigned long)&fm) == 0) pkg->clientdata->listfile_phys_offs = fm.fiemap.fm_extents[0].fe_physical; close(fd); } pkg_array_sort(array, pkg_sorter_by_listfile_phys_offs); }
/* * cstatus might be msdbrw_readonly if we're in --no-act mode, in which * case we don't write out all of the interest files etc. but we do * invent all of the activations for our own benefit. */ static void trig_transitional_activate(enum modstatdb_rw cstatus) { struct pkgiterator *iter; struct pkginfo *pkg; iter = pkg_db_iter_new(); while ((pkg = pkg_db_iter_next_pkg(iter))) { if (pkg->status <= PKG_STAT_HALFINSTALLED) continue; debug(dbg_triggersdetail, "trig_transitional_activate %s %s", pkg_name(pkg, pnaw_always), pkg_status_name(pkg)); pkg->trigpend_head = NULL; trig_parse_ci(pkg_infodb_get_file(pkg, &pkg->installed, TRIGGERSCIFILE), cstatus >= msdbrw_write ? transitional_interest_callback : transitional_interest_callback_ro, NULL, pkg, &pkg->installed); /* Ensure we're not creating incoherent data that can't * be written down. This should never happen in theory but * can happen if you restore an old status file that is * not in sync with the infodb files. */ if (pkg->status < PKG_STAT_TRIGGERSAWAITED) continue; if (pkg->trigaw.head) pkg_set_status(pkg, PKG_STAT_TRIGGERSAWAITED); else if (pkg->trigpend_head) pkg_set_status(pkg, PKG_STAT_TRIGGERSPENDING); else pkg_set_status(pkg, PKG_STAT_INSTALLED); } pkg_db_iter_free(iter); if (cstatus >= msdbrw_write) { modstatdb_checkpoint(); trig_file_interests_save(); } }
static void pkg_files_optimize_load(struct pkg_array *array) { int i; /* Ask the kernel to start preloading the list files, so as to get a * boost when later we actually load them. */ for (i = 0; i < array->n_pkgs; i++) { struct pkginfo *pkg = array->pkgs[i]; const char *listfile; int fd; listfile = pkg_infodb_get_file(pkg, &pkg->installed, LISTFILE); fd = open(listfile, O_RDONLY | O_NONBLOCK); if (fd != -1) { posix_fadvise(fd, 0, 0, POSIX_FADV_WILLNEED); close(fd); } } }
/** * Load the list of files in this package into memory, or update the * list if it is there but stale. */ void ensure_packagefiles_available(struct pkginfo *pkg) { static int fd; const char *filelistfile; struct fileinlist **lendp; struct stat stat_buf; char *loaded_list, *loaded_list_end, *thisline, *nextline, *ptr; if (pkg->clientdata && pkg->clientdata->fileslistvalid) return; ensure_package_clientdata(pkg); /* Throw away any stale data, if there was any. */ pkg_files_blank(pkg); /* Packages which aren't installed don't have a files list. */ if (pkg->status == stat_notinstalled) { pkg->clientdata->fileslistvalid = true; return; } filelistfile = pkg_infodb_get_file(pkg, &pkg->installed, LISTFILE); onerr_abort++; fd= open(filelistfile,O_RDONLY); if (fd==-1) { if (errno != ENOENT) ohshite(_("unable to open files list file for package `%.250s'"), pkg_name(pkg, pnaw_nonambig)); onerr_abort--; if (pkg->status != stat_configfiles && dpkg_version_is_informative(&pkg->configversion)) { warning(_("files list file for package '%.250s' missing; assuming " "package has no files currently installed"), pkg_name(pkg, pnaw_nonambig)); } pkg->clientdata->files = NULL; pkg->clientdata->fileslistvalid = true; return; } push_cleanup(cu_closefd, ehflag_bombout, NULL, 0, 1, &fd); if (fstat(fd, &stat_buf)) ohshite(_("unable to stat files list file for package '%.250s'"), pkg_name(pkg, pnaw_nonambig)); if (!S_ISREG(stat_buf.st_mode)) ohshit(_("files list for package '%.250s' is not a regular file"), pkg_name(pkg, pnaw_nonambig)); if (stat_buf.st_size) { loaded_list = nfmalloc(stat_buf.st_size); loaded_list_end = loaded_list + stat_buf.st_size; if (fd_read(fd, loaded_list, stat_buf.st_size) < 0) ohshite(_("reading files list for package '%.250s'"), pkg_name(pkg, pnaw_nonambig)); lendp= &pkg->clientdata->files; thisline = loaded_list; while (thisline < loaded_list_end) { struct filenamenode *namenode; ptr = memchr(thisline, '\n', loaded_list_end - thisline); if (ptr == NULL) ohshit(_("files list file for package '%.250s' is missing final newline"), pkg_name(pkg, pnaw_nonambig)); /* Where to start next time around. */ nextline = ptr + 1; /* Strip trailing ‘/’. */ if (ptr > thisline && ptr[-1] == '/') ptr--; /* Add the file to the list. */ if (ptr == thisline) ohshit(_("files list file for package `%.250s' contains empty filename"), pkg_name(pkg, pnaw_nonambig)); *ptr = '\0'; namenode = findnamenode(thisline, fnn_nocopy); lendp = pkg_files_add_file(pkg, namenode, lendp); thisline = nextline; } } pop_cleanup(ehflag_normaltidy); /* fd = open() */ if (close(fd)) ohshite(_("error closing files list file for package `%.250s'"), pkg_name(pkg, pnaw_nonambig)); onerr_abort--; pkg->clientdata->fileslistvalid = true; }